超大量的更新 修复很多问题,gameplay特效初步
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System.Collections;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using DG.Tweening;
|
||||
@@ -55,8 +55,7 @@ public class CharacterCardView : MonoBehaviour, IBeginDragHandler, IDragHandler,
|
||||
if (characterImage != null) characterImage.raycastTarget = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// 未在队中的卡点击后进入被操纵状态。若在队伍中默认进入已经入队状态
|
||||
/// </summary>
|
||||
/// Documentation text normalized.
|
||||
public void beSelected()
|
||||
{
|
||||
if (!isSelected)
|
||||
@@ -70,7 +69,7 @@ public class CharacterCardView : MonoBehaviour, IBeginDragHandler, IDragHandler,
|
||||
|
||||
public void beUnSelected()
|
||||
{
|
||||
//还需要走TeamManager去掉此角色的队列信息
|
||||
// Documentation text normalized.
|
||||
isSelected = false;
|
||||
TeamManager.Instance.removeTeamCharacter(characterID);
|
||||
characterImage.color = new Color(1f, 1f, 1f,1);
|
||||
|
||||
+130
-166
@@ -1,45 +1,27 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
public class TeamManager : MonoBehaviour
|
||||
{
|
||||
public static TeamManager Instance {get; private set;}
|
||||
public static TeamManager Instance { get; private set; }
|
||||
|
||||
public teamSettingPanel teamSettingPanelInstance;
|
||||
/// <summary>
|
||||
/// 当前玩家存档下的所有编队配置,key为编队索引,value为该编队的角色列表,表内只有角色ID
|
||||
/// </summary>
|
||||
|
||||
public Dictionary<int, TeamSetting> currentTeamSettings = new Dictionary<int, TeamSetting>();
|
||||
/// <summary>
|
||||
/// 玩家存档下已经解锁的角色信息列表
|
||||
/// </summary>
|
||||
public List<CharacterView> SelectableCharacterList = new List<CharacterView>();
|
||||
/// <summary>
|
||||
/// 根据此字段来在编队信息页显示已有编队
|
||||
/// </summary>
|
||||
|
||||
public int currentSelectedTeam = 0;
|
||||
/// <summary>
|
||||
/// 记录被选中的编队中角色的索引,用于处理队列位置交换的逻辑。-1表示无角色被选中
|
||||
/// </summary>
|
||||
public int currentSelectedTeamCharacter = -1;
|
||||
/// <summary>
|
||||
/// 标记要被放入编队的角色
|
||||
/// </summary>
|
||||
public int currentSelectedTeamCharacter = -1;
|
||||
public CharacterView currentSelectedCharacterCard = null;
|
||||
/// <summary>
|
||||
/// 在修改被选中的编队中角色的索引时触发
|
||||
/// </summary>
|
||||
|
||||
public event Action OnSelectedCharacterChanged;
|
||||
/// <summary>
|
||||
/// 修改选定的预设队伍时触发
|
||||
/// </summary>
|
||||
public event Action OnSelectedTeamChanged;
|
||||
|
||||
void Awake()
|
||||
|
||||
private const int TeamCount = 4;
|
||||
private const int TeamSlotCount = 5;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
@@ -51,202 +33,184 @@ public class TeamManager : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
void testTeamSetting()
|
||||
private void Start()
|
||||
{
|
||||
SelectableCharacterList.Add(new CharacterView(1001001,"C"));
|
||||
SelectableCharacterList.Add(new CharacterView(1001002,"S"));
|
||||
|
||||
//手动向currentTeamSettings和SelectableCharacterList添加测试数据
|
||||
currentTeamSettings.Add(0,new TeamSetting(new List<CharacterView>(),1001001));
|
||||
currentTeamSettings[0].teamIdList.Add(new CharacterView(1001001,"C"));
|
||||
currentTeamSettings[0].teamIdList.Add(new CharacterView(1001002,"S"));
|
||||
currentTeamSettings[0].teamIdList.Add(new CharacterView(1001001,"C"));
|
||||
currentTeamSettings[0].teamIdList.Add( new CharacterView(1001002,"C"));
|
||||
currentTeamSettings[0].teamIdList.Add(new CharacterView(0,null));
|
||||
|
||||
currentTeamSettings.Add(1,new TeamSetting(new List<CharacterView>(),1001002));
|
||||
currentTeamSettings[1].teamIdList.Add(new CharacterView(1001001,"C"));
|
||||
currentTeamSettings[1].teamIdList.Add(new CharacterView(1001002,"B"));
|
||||
currentTeamSettings[1].teamIdList.Add(new CharacterView(1001001,"C"));
|
||||
currentTeamSettings[1].teamIdList.Add( new CharacterView(1001002,"A"));
|
||||
currentTeamSettings[1].teamIdList.Add(new CharacterView(1001002,"A"));
|
||||
//在当前版本中,就算是空队伍也要用如下填满,请等待数据结构的重构
|
||||
currentTeamSettings.Add(2,new TeamSetting(new List<CharacterView>(),-1));
|
||||
currentTeamSettings[2].teamIdList.Add(new CharacterView(0,null));
|
||||
currentTeamSettings[2].teamIdList.Add(new CharacterView(0,null));
|
||||
currentTeamSettings[2].teamIdList.Add(new CharacterView(0,null));
|
||||
currentTeamSettings[2].teamIdList.Add( new CharacterView(0,null));
|
||||
currentTeamSettings[2].teamIdList.Add(new CharacterView(0,null));
|
||||
|
||||
currentTeamSettings.Add(3,new TeamSetting(new List<CharacterView>(),-1));
|
||||
currentTeamSettings[3].teamIdList.Add(new CharacterView(0,null));
|
||||
currentTeamSettings[3].teamIdList.Add(new CharacterView(0,null));
|
||||
currentTeamSettings[3].teamIdList.Add(new CharacterView(0,null));
|
||||
currentTeamSettings[3].teamIdList.Add( new CharacterView(0,null));
|
||||
currentTeamSettings[3].teamIdList.Add(new CharacterView(0,null));
|
||||
|
||||
|
||||
Debug.Log("testTeamSetting ready");
|
||||
if (teamSettingPanelInstance == null && teamSettingPanel.Instance != null)
|
||||
teamSettingPanelInstance = teamSettingPanel.Instance;
|
||||
|
||||
EnsureDefaultTeamSettings();
|
||||
}
|
||||
|
||||
private void EnsureDefaultTeamSettings()
|
||||
{
|
||||
for (int i = 0; i < TeamCount; i++)
|
||||
{
|
||||
if (!currentTeamSettings.ContainsKey(i) || currentTeamSettings[i] == null)
|
||||
{
|
||||
currentTeamSettings[i] = CreateEmptyTeamSetting();
|
||||
}
|
||||
|
||||
EnsureTeamSlotCount(currentTeamSettings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static TeamSetting CreateEmptyTeamSetting()
|
||||
{
|
||||
var list = new List<CharacterView>(TeamSlotCount);
|
||||
for (int i = 0; i < TeamSlotCount; i++)
|
||||
list.Add(new CharacterView(0, null));
|
||||
return new TeamSetting(list, -1);
|
||||
}
|
||||
|
||||
private static void EnsureTeamSlotCount(TeamSetting setting)
|
||||
{
|
||||
if (setting == null) return;
|
||||
if (setting.teamIdList == null)
|
||||
setting.teamIdList = new List<CharacterView>();
|
||||
|
||||
while (setting.teamIdList.Count < TeamSlotCount)
|
||||
setting.teamIdList.Add(new CharacterView(0, null));
|
||||
}
|
||||
|
||||
public void openTeamSettingPanel()
|
||||
{
|
||||
if (teamSettingPanelInstance != null)
|
||||
teamSettingPanelInstance.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
public void closeTeamSettingPanel()
|
||||
{
|
||||
if (teamSettingPanelInstance != null)
|
||||
teamSettingPanelInstance.gameObject.SetActive(false);
|
||||
}
|
||||
public void openTeamSettingPanel()=> teamSettingPanelInstance.gameObject.SetActive(true);
|
||||
public void closeTeamSettingPanel()=> teamSettingPanelInstance.gameObject.SetActive(false);
|
||||
|
||||
public void setCurrentSelectedTeam(int index)
|
||||
{
|
||||
if (index > 3 || index < 0)
|
||||
if (index < 0 || index >= TeamCount)
|
||||
{
|
||||
Debug.LogWarning("所选队伍预设索引超出范围");
|
||||
Debug.LogWarning($"Selected team index out of range: {index}");
|
||||
return;
|
||||
}
|
||||
currentSelectedTeam = index;
|
||||
}
|
||||
void Start()
|
||||
{
|
||||
// if(teamSettingPanelInstance == null)
|
||||
// {
|
||||
// teamSettingPanelInstance = teamSettingPanel.Instance;
|
||||
// }
|
||||
// Ensure we have a reference to the UI panel instance if available
|
||||
if (teamSettingPanelInstance == null && teamSettingPanel.Instance != null)
|
||||
teamSettingPanelInstance = teamSettingPanel.Instance;
|
||||
|
||||
testTeamSetting();//接入玩家存档后请注释掉此行
|
||||
}
|
||||
void saveTeamSetting()
|
||||
public void setcurrentTeamSettings(Dictionary<int, TeamSetting> playerTeamSettings)
|
||||
{
|
||||
//todo:我想,在接存档系统的时候这个会有用。
|
||||
currentTeamSettings = playerTeamSettings ?? new Dictionary<int, TeamSetting>();
|
||||
EnsureDefaultTeamSettings();
|
||||
}
|
||||
/// <summary>
|
||||
/// 读取玩家存档信息后可直接在此写入编队信息
|
||||
/// </summary>
|
||||
/// <param name="playerTeamSettings"></param>
|
||||
public void setcurrentTeamSettings(Dictionary<int,TeamSetting> playerTeamSettings)
|
||||
{
|
||||
currentTeamSettings = playerTeamSettings;
|
||||
}
|
||||
/// <summary>
|
||||
/// 依据选定的队伍预设索引来获得队伍信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
public TeamSetting getCurrentSelectedTeam()
|
||||
{
|
||||
EnsureDefaultTeamSettings();
|
||||
return currentTeamSettings[currentSelectedTeam];
|
||||
}
|
||||
|
||||
public void setCurrentSelectedTeam(TeamSetting newTeamData, int teamIndex)
|
||||
{
|
||||
if (teamIndex < 0 || teamIndex >= TeamCount || newTeamData == null)
|
||||
return;
|
||||
|
||||
EnsureTeamSlotCount(newTeamData);
|
||||
currentTeamSettings[teamIndex] = newTeamData;
|
||||
}
|
||||
|
||||
public void setCurrentSelectedCharacterInTeam(int characterIndex)
|
||||
{
|
||||
if (characterIndex != currentSelectedTeamCharacter)
|
||||
{
|
||||
Debug.Log($"修改选中对象从{currentSelectedTeamCharacter}到{characterIndex}");
|
||||
currentSelectedTeamCharacter = characterIndex;
|
||||
OnSelectedCharacterChanged?.Invoke(); // 触发事件
|
||||
OnSelectedCharacterChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentSelectedTeamSetting(int teamIndex)
|
||||
{
|
||||
if(teamIndex != currentSelectedTeam)
|
||||
if (teamIndex < 0 || teamIndex >= TeamCount)
|
||||
return;
|
||||
|
||||
if (teamIndex != currentSelectedTeam)
|
||||
{
|
||||
Debug.Log($"修改选中队伍预设从{currentSelectedTeam}到{teamIndex}");
|
||||
currentSelectedTeam = teamIndex;
|
||||
OnSelectedTeamChanged?.Invoke(); // 触发事件
|
||||
OnSelectedTeamChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 交换指定索引中的两个队伍中元素的位置
|
||||
/// </summary>
|
||||
/// <param name="firstIndex">当前元素</param>
|
||||
/// <param name="secondIndex">目标元素位置</param>
|
||||
|
||||
public void swapTeamElements(int firstIndex, int secondIndex)
|
||||
{
|
||||
List<CharacterView> newCurrentTeam = getCurrentSelectedTeam().teamIdList;
|
||||
CharacterView temp = newCurrentTeam[firstIndex];
|
||||
newCurrentTeam[firstIndex] = newCurrentTeam[secondIndex];
|
||||
newCurrentTeam[secondIndex] = temp;
|
||||
currentTeamSettings[currentSelectedTeam].teamIdList = newCurrentTeam;
|
||||
teamSettingPanelInstance.updateTeamSettingElements();
|
||||
setCurrentSelectedCharacterInTeam(secondIndex);
|
||||
var team = getCurrentSelectedTeam()?.teamIdList;
|
||||
if (team == null) return;
|
||||
if (firstIndex < 0 || firstIndex >= team.Count) return;
|
||||
if (secondIndex < 0 || secondIndex >= team.Count) return;
|
||||
|
||||
CharacterView temp = team[firstIndex];
|
||||
team[firstIndex] = team[secondIndex];
|
||||
team[secondIndex] = temp;
|
||||
|
||||
currentTeamSettings[currentSelectedTeam].teamIdList = team;
|
||||
if (teamSettingPanelInstance != null)
|
||||
teamSettingPanelInstance.updateTeamSettingElements();
|
||||
|
||||
setCurrentSelectedCharacterInTeam(secondIndex);
|
||||
}
|
||||
|
||||
public void setTeamLeader(int characterID)
|
||||
{
|
||||
Debug.Log($"{characterID},{SelectableCharacterList.Count}");
|
||||
currentTeamSettings[currentSelectedTeam].LeaderId=characterID;
|
||||
teamSettingPanelInstance.updateTeamSettingElements();
|
||||
}
|
||||
/// <summary>
|
||||
/// 填入或者覆盖队伍指定位置的信息
|
||||
/// </summary>
|
||||
/// <param name="aimListIndex"></param>
|
||||
public void ResetTeamCharacter (int aimListIndex)
|
||||
{
|
||||
//如果在队伍中已有角色的情况下再次触发此方法,首先要去掉旧信息,再放新信息
|
||||
CharacterView newCharacter = currentSelectedCharacterCard;
|
||||
List<CharacterView> newCurrentTeam = getCurrentSelectedTeam().teamIdList;
|
||||
var team = getCurrentSelectedTeam();
|
||||
if (team == null) return;
|
||||
|
||||
// 修复:原代码使用 (aimListIndex > 0 || aimListIndex < Count) 永远几乎为真,
|
||||
// 会导致当 aimListIndex = 0 或越界时也进入逻辑,造成数据错乱。
|
||||
if (aimListIndex >= 0 && aimListIndex < newCurrentTeam.Count)
|
||||
{
|
||||
for(int i=0;i<newCurrentTeam.Count;i++)
|
||||
{
|
||||
if (newCurrentTeam[i].characterId == newCharacter.characterId && aimListIndex != i)//满足此条件为更换角色的队伍位置
|
||||
{
|
||||
//说明是在更换角色所在的位置下标,旧角色,位置置空
|
||||
newCurrentTeam[aimListIndex] = newCharacter;
|
||||
CharacterView characterView = new CharacterView(0, null);
|
||||
newCurrentTeam[i] = characterView;
|
||||
currentTeamSettings[currentSelectedTeam].teamIdList = newCurrentTeam;
|
||||
teamSettingPanelInstance.updateTeamSettingElements();
|
||||
return;
|
||||
}
|
||||
else if (newCurrentTeam[i].characterId == newCharacter.characterId && aimListIndex == i)
|
||||
{
|
||||
//原地点击操作,不做任何操作
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
newCurrentTeam[aimListIndex] = newCharacter;
|
||||
currentTeamSettings[currentSelectedTeam].teamIdList = newCurrentTeam;
|
||||
team.LeaderId = characterID;
|
||||
if (teamSettingPanelInstance != null)
|
||||
teamSettingPanelInstance.updateTeamSettingElements();
|
||||
}
|
||||
|
||||
public void ResetTeamCharacter(int aimListIndex)
|
||||
{
|
||||
var selected = currentSelectedCharacterCard;
|
||||
var team = getCurrentSelectedTeam()?.teamIdList;
|
||||
if (selected == null || team == null)
|
||||
return;
|
||||
if (aimListIndex < 0 || aimListIndex >= team.Count)
|
||||
{
|
||||
Debug.LogWarning($"ResetTeamCharacter index out of range: {aimListIndex}");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogWarning($"TeamManager.ResetTeamCharacter: aimListIndex out of range: {aimListIndex} (Count={newCurrentTeam.Count})");
|
||||
for (int i = 0; i < team.Count; i++)
|
||||
{
|
||||
if (i == aimListIndex) continue;
|
||||
if (team[i] != null && team[i].characterId == selected.characterId)
|
||||
{
|
||||
team[i] = new CharacterView(0, null);
|
||||
}
|
||||
}
|
||||
|
||||
team[aimListIndex] = selected;
|
||||
currentTeamSettings[currentSelectedTeam].teamIdList = team;
|
||||
|
||||
if (teamSettingPanelInstance != null)
|
||||
teamSettingPanelInstance.updateTeamSettingElements();
|
||||
}
|
||||
/// <summary>
|
||||
/// 移除队伍中的指定角色
|
||||
/// </summary>
|
||||
/// <param name="characterID"></param>
|
||||
|
||||
public void removeTeamCharacter(int characterId)
|
||||
{
|
||||
currentSelectedCharacterCard = null;
|
||||
List<CharacterView> newCurrentTeam = getCurrentSelectedTeam().teamIdList;
|
||||
foreach (CharacterView character in newCurrentTeam)
|
||||
var team = getCurrentSelectedTeam()?.teamIdList;
|
||||
if (team == null) return;
|
||||
|
||||
for (int i = 0; i < team.Count; i++)
|
||||
{
|
||||
if (character.characterId == characterId)
|
||||
if (team[i] != null && team[i].characterId == characterId)
|
||||
{
|
||||
character.characterId = 0;
|
||||
character.currentBoundaryLevel = null;
|
||||
team[i].characterId = 0;
|
||||
team[i].currentBoundaryLevel = null;
|
||||
}
|
||||
}
|
||||
currentTeamSettings[currentSelectedTeam].teamIdList = newCurrentTeam;
|
||||
// attempt to update UI panel safely
|
||||
|
||||
currentTeamSettings[currentSelectedTeam].teamIdList = team;
|
||||
|
||||
var panel = teamSettingPanelInstance ?? teamSettingPanel.Instance;
|
||||
if (panel != null)
|
||||
{
|
||||
panel.updateTeamSettingElements();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("TeamManager.removeTeamCharacter: teamSettingPanel instance missing, UI not updated.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -105,8 +105,8 @@ public class TeamSelectorAnimController : MonoBehaviour
|
||||
StartCoroutine(AnimateSlots());
|
||||
StartCoroutine(AnimateSmallCards());
|
||||
|
||||
// skills flash after bottom panel enters
|
||||
float delay = panelEnterTime + panelStagger + 0.05f;
|
||||
// Defer skills flash to avoid stacking with slot enter animation work.
|
||||
float delay = panelEnterTime + panelStagger + EstimateSlotEnterWindow() + 0.05f;
|
||||
DOVirtual.DelayedCall(delay, () => PlaySkillsFlashInternal(null)).SetUpdate(useUnscaled);
|
||||
}
|
||||
|
||||
@@ -167,9 +167,15 @@ public class TeamSelectorAnimController : MonoBehaviour
|
||||
|
||||
IEnumerator AnimateSlots()
|
||||
{
|
||||
// Some slots can be instantiated/enabled a couple frames after the panel is shown.
|
||||
// Wait a bit for the full slot set so we don't miss animating the last one.
|
||||
int expectedCount = cachedTeam != null && cachedTeam.Length > 0 ? cachedTeam.Length : 5;
|
||||
if (newTeamSelector.Instance != null && newTeamSelector.Instance.slotCount > 0)
|
||||
expectedCount = newTeamSelector.Instance.slotCount;
|
||||
|
||||
List<RectTransform> slotRects = GetSlotRects();
|
||||
int tries = 0;
|
||||
while ((slotRects == null || slotRects.Count == 0) && tries < 10)
|
||||
while ((slotRects == null || slotRects.Count < expectedCount) && tries < 20)
|
||||
{
|
||||
tries++;
|
||||
yield return null;
|
||||
@@ -182,22 +188,26 @@ public class TeamSelectorAnimController : MonoBehaviour
|
||||
if (leftSlotsContainer != null)
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(leftSlotsContainer);
|
||||
|
||||
slotRects.Sort((a, b) => a.position.y.CompareTo(b.position.y));
|
||||
slotRects.Sort((a, b) => a.GetSiblingIndex().CompareTo(b.GetSiblingIndex()));
|
||||
|
||||
if (layoutEnabled) layout.enabled = false;
|
||||
|
||||
var basePosBySlot = new Dictionary<RectTransform, Vector2>(slotRects.Count);
|
||||
for (int i = 0; i < slotRects.Count; i++)
|
||||
{
|
||||
RectTransform rt = slotRects[i];
|
||||
if (rt == null) continue;
|
||||
Vector2 basePos = rt.anchoredPosition;
|
||||
basePosBySlot[rt] = basePos;
|
||||
rt.DOKill();
|
||||
rt.anchoredPosition = basePos + new Vector2(0f, -slotEnterOffset);
|
||||
rt.DOAnchorPos(basePos, slotEnterTime)
|
||||
.SetEase(Ease.OutCubic)
|
||||
.SetDelay(i * slotStagger)
|
||||
.SetUpdate(useUnscaled)
|
||||
.SetLink(rt.gameObject, LinkBehaviour.KillOnDisable);
|
||||
// If a slot gets disabled/enabled during layout/UI updates, don't kill the tween
|
||||
// (killing it can leave the slot stuck at the start offset).
|
||||
.SetLink(rt.gameObject, LinkBehaviour.PauseOnDisablePlayOnEnable);
|
||||
}
|
||||
|
||||
float total = slotEnterTime + slotStagger * Mathf.Max(0, slotRects.Count - 1);
|
||||
@@ -208,6 +218,22 @@ public class TeamSelectorAnimController : MonoBehaviour
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// Failsafe: if any slot tween was interrupted (e.g. killed by disable), snap it back.
|
||||
foreach (var kvp in basePosBySlot)
|
||||
{
|
||||
RectTransform rt = kvp.Key;
|
||||
if (rt == null) continue;
|
||||
Vector2 basePos = kvp.Value;
|
||||
if (Vector2.Distance(rt.anchoredPosition, basePos) > 0.5f)
|
||||
{
|
||||
rt.DOKill();
|
||||
rt.DOAnchorPos(basePos, 0.12f)
|
||||
.SetEase(Ease.OutCubic)
|
||||
.SetUpdate(useUnscaled)
|
||||
.SetLink(rt.gameObject, LinkBehaviour.PauseOnDisablePlayOnEnable);
|
||||
}
|
||||
}
|
||||
|
||||
if (layoutEnabled) layout.enabled = true;
|
||||
if (leftSlotsContainer != null)
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(leftSlotsContainer);
|
||||
@@ -217,8 +243,8 @@ public class TeamSelectorAnimController : MonoBehaviour
|
||||
{
|
||||
if (smallCardsContainer == null)
|
||||
EnsureRefs();
|
||||
// wait for top panel to slide in
|
||||
float t = panelEnterTime + 0.02f;
|
||||
// Start a bit later to avoid overlapping slot enter bursts.
|
||||
float t = panelEnterTime + Mathf.Min(0.2f, EstimateSlotEnterWindow() * 0.4f);
|
||||
while (t > 0f)
|
||||
{
|
||||
t -= useUnscaled ? Time.unscaledDeltaTime : Time.deltaTime;
|
||||
@@ -481,6 +507,14 @@ public class TeamSelectorAnimController : MonoBehaviour
|
||||
Graphic g = rt.GetComponent<Graphic>();
|
||||
if (g != null) g.raycastTarget = true;
|
||||
}
|
||||
|
||||
float EstimateSlotEnterWindow()
|
||||
{
|
||||
int count = 5;
|
||||
if (newTeamSelector.Instance != null && newTeamSelector.Instance.slotCount > 0)
|
||||
count = newTeamSelector.Instance.slotCount;
|
||||
return slotEnterTime + Mathf.Max(0, count - 1) * slotStagger;
|
||||
}
|
||||
}
|
||||
|
||||
static class TeamSelectorAnimBootstrap
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Collections;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
/// <summary>
|
||||
/// 适用于编队系统数据层,存储单个队伍的信息
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
public class TeamSetting
|
||||
{
|
||||
@@ -17,7 +17,7 @@ public class TeamSetting
|
||||
public List<CharacterView> teamIdList = new List<CharacterView>();
|
||||
|
||||
/// <summary>
|
||||
/// 队长
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
public int LeaderId{get; set;}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class CharacterView
|
||||
this.characterId = characterId;
|
||||
this.currentBoundaryLevel = currentBoundaryLevel;
|
||||
}
|
||||
//todo:回头加一个轨道颜色对应
|
||||
public int characterId{get; set;}
|
||||
public string currentBoundaryLevel{get; set;}
|
||||
|
||||
public int characterId { get; set; }
|
||||
public string currentBoundaryLevel { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections;
|
||||
@@ -7,13 +7,13 @@ public class newTeamSelector : MonoBehaviour
|
||||
{
|
||||
public static newTeamSelector Instance { get; private set; }
|
||||
|
||||
[Header("�ȼ�ͼƬCBAS")]
|
||||
[Header("Inspector")]
|
||||
public Sprite levelIcon_sprite_C;
|
||||
public Sprite levelIcon_sprite_B;
|
||||
public Sprite levelIcon_sprite_A;
|
||||
public Sprite levelIcon_sprite_S;
|
||||
|
||||
[Header("��ѡ��Ķ���")]
|
||||
[Header("Inspector")]
|
||||
public int selected_heroSlot01_heroID;
|
||||
public int selected_heroSlot02_heroID;
|
||||
public int selected_heroSlot03_heroID;
|
||||
@@ -34,14 +34,20 @@ public class newTeamSelector : MonoBehaviour
|
||||
|
||||
[Tooltip("If true, create slots automatically on Start")]
|
||||
public bool instantiateOnStart = true;
|
||||
[Tooltip("Delay skill list rebuild until after slot enter animation to reduce hitching.")]
|
||||
public float delayedSkillRefreshSeconds = 0.75f;
|
||||
|
||||
private readonly List<slots_heroSlots> createdSlots = new List<slots_heroSlots>();
|
||||
private static AllyHero_SO[] cachedHeroes;
|
||||
private static Dictionary<int, AllyHero_SO> cachedHeroesById;
|
||||
private Coroutine refreshSkillsRoutine;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
Instance = this;
|
||||
EnsureHeroCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -53,11 +59,17 @@ public class newTeamSelector : MonoBehaviour
|
||||
{
|
||||
if (instantiateOnStart)
|
||||
CreateSlots();
|
||||
LoadSelectedHeroes();
|
||||
StartCoroutine(LoadSelectedHeroesNextFrame());
|
||||
}
|
||||
|
||||
void Update() { }
|
||||
|
||||
private IEnumerator LoadSelectedHeroesNextFrame()
|
||||
{
|
||||
yield return null;
|
||||
LoadSelectedHeroes();
|
||||
}
|
||||
|
||||
public void CreateSlots()
|
||||
{
|
||||
if (slotPrefab == null || container == null)
|
||||
@@ -175,7 +187,7 @@ public class newTeamSelector : MonoBehaviour
|
||||
PlayerPrefs.SetInt("selected_heroSlot05_heroID", selected_heroSlot05_heroID);
|
||||
PlayerPrefs.Save();
|
||||
|
||||
Debug.Log("�ѱ��浱ǰ���鵽PlayerPrefs");
|
||||
Debug.Log("已保存当前英雄到 PlayerPrefs");
|
||||
}
|
||||
|
||||
public void LoadSelectedHeroes()
|
||||
@@ -205,14 +217,15 @@ public class newTeamSelector : MonoBehaviour
|
||||
AllyHero_SO hero = FindHeroById(slot.heroSlot_heroID);
|
||||
if (hero != null)
|
||||
{
|
||||
slot.SetSlot(slot.heroSlot_heroID, hero.ally_heroName, hero.ally_heroPoster);
|
||||
// Delay expensive skill UI refresh to avoid slot-enter stutters.
|
||||
slot.SetSlot(slot.heroSlot_heroID, hero.ally_heroName, hero.ally_heroPoster, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear slot logic
|
||||
slot.heroSlot_heroID = 0;
|
||||
if (slot.heroSlot_heroName != null) slot.heroSlot_heroName.text = "����";
|
||||
if (slot.heroSlot_heroName != null) slot.heroSlot_heroName.text = "未选择";
|
||||
if (slot.heroImage != null)
|
||||
{
|
||||
// revert to default sprite if provided, otherwise keep transparent
|
||||
@@ -233,18 +246,61 @@ public class newTeamSelector : MonoBehaviour
|
||||
slot.heroLevelImage.color = new Color(1f, 1f, 1f, 0f);
|
||||
}
|
||||
// Update skill list
|
||||
slot.UpdateSkillList();
|
||||
slot.UpdateSkillList(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (refreshSkillsRoutine != null)
|
||||
StopCoroutine(refreshSkillsRoutine);
|
||||
refreshSkillsRoutine = StartCoroutine(RefreshSkillsGradually());
|
||||
}
|
||||
|
||||
private IEnumerator RefreshSkillsGradually()
|
||||
{
|
||||
if (delayedSkillRefreshSeconds > 0f)
|
||||
yield return new WaitForSecondsRealtime(delayedSkillRefreshSeconds);
|
||||
else
|
||||
yield return null;
|
||||
|
||||
for (int i = 0; i < createdSlots.Count; i++)
|
||||
{
|
||||
var slot = createdSlots[i];
|
||||
if (slot == null) continue;
|
||||
if (slot.heroSlot_heroID != 0)
|
||||
{
|
||||
slot.UpdateSkillList(false);
|
||||
// Spread UI instantiation across frames to reduce hitch.
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
TeamSelectorAnimController.PlaySkillsFlash(null);
|
||||
refreshSkillsRoutine = null;
|
||||
}
|
||||
|
||||
private AllyHero_SO FindHeroById(int id)
|
||||
{
|
||||
var arr = Resources.LoadAll<AllyHero_SO>("");
|
||||
foreach (var a in arr)
|
||||
{
|
||||
if (a != null && a.ally_heroID == id) return a;
|
||||
}
|
||||
EnsureHeroCache();
|
||||
if (cachedHeroesById != null && cachedHeroesById.TryGetValue(id, out var hero))
|
||||
return hero;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void EnsureHeroCache()
|
||||
{
|
||||
if (cachedHeroesById != null && cachedHeroesById.Count > 0)
|
||||
return;
|
||||
|
||||
if (cachedHeroes == null || cachedHeroes.Length == 0)
|
||||
cachedHeroes = Resources.LoadAll<AllyHero_SO>("");
|
||||
|
||||
cachedHeroesById = new Dictionary<int, AllyHero_SO>();
|
||||
if (cachedHeroes == null) return;
|
||||
|
||||
for (int i = 0; i < cachedHeroes.Length; i++)
|
||||
{
|
||||
AllyHero_SO hero = cachedHeroes[i];
|
||||
if (hero == null) continue;
|
||||
cachedHeroesById[hero.ally_heroID] = hero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class loadSettlementTeamPrefab : MonoBehaviour
|
||||
{
|
||||
[Header("��Ҫ����")]
|
||||
[Header("Inspector")]
|
||||
public ScoreManager sm;
|
||||
public teamUIController tuic;
|
||||
public GameManager gm;
|
||||
[Header("����")]
|
||||
[Header("Inspector")]
|
||||
public GameObject settleTeamCardsPrefab;
|
||||
public GameObject objectToPutdown;
|
||||
|
||||
@@ -35,7 +35,7 @@ public class loadSettlementTeamPrefab : MonoBehaviour
|
||||
if (tuic == null && teamUIController.Instance != null)
|
||||
tuic = teamUIController.Instance;
|
||||
|
||||
// 修复:确保 sm 被正确赋值
|
||||
// Documentation text normalized.
|
||||
if (sm == null && ScoreManager.Instance != null)
|
||||
sm = ScoreManager.Instance;
|
||||
|
||||
@@ -43,7 +43,7 @@ public class loadSettlementTeamPrefab : MonoBehaviour
|
||||
bool parentSceneValid = objectToPutdown != null && objectToPutdown.scene.IsValid();
|
||||
Debug.Log($"[loadSettlementTeamPrefab] Target parent: {objectToPutdown.name}, activeInHierarchy: {objectToPutdown.activeInHierarchy}, sceneValid: {parentSceneValid}");
|
||||
|
||||
// 诊断:记录 ScoreManager 的状态
|
||||
// Documentation text normalized.
|
||||
if (sm != null)
|
||||
{
|
||||
Debug.Log($"[loadSettlementTeamPrefab] ScoreManager found. Idol sums: R{sm.red_idolScore_sum} G{sm.green_idolScore_sum} Y{sm.yellow_idolScore_sum} P{sm.purple_idolScore_sum} B{sm.blue_idolScore_sum}");
|
||||
@@ -177,7 +177,7 @@ public class loadSettlementTeamPrefab : MonoBehaviour
|
||||
float fill = ac.maxHP > 0 ? (float)ac.currentHP / ac.maxHP : 0f;
|
||||
card.ally_healthBar.fillAmount = Mathf.Clamp01(fill);
|
||||
|
||||
// 新增:如果角色血量为0(死了),给 ally_profile 赋予灰色材质
|
||||
// Documentation text normalized.
|
||||
if (ac.currentHP <= 0 && card.ally_profile != null && card.grayM != null)
|
||||
{
|
||||
card.ally_profile.material = card.grayM;
|
||||
@@ -187,12 +187,12 @@ public class loadSettlementTeamPrefab : MonoBehaviour
|
||||
}
|
||||
|
||||
// this_allyIdolScore: map index to ScoreManager fields if available
|
||||
// 修复:确保从正确的 ScoreManager 实例读取数据
|
||||
// Documentation text normalized.
|
||||
if (card.this_allyIdolScore != null)
|
||||
{
|
||||
int idol = 0;
|
||||
|
||||
// 优先使用已赋值的 sm,否则从 ScoreManager.Instance 获取
|
||||
// Documentation text normalized.
|
||||
var scoreManager = sm != null ? sm : ScoreManager.Instance;
|
||||
|
||||
if (scoreManager != null)
|
||||
@@ -236,11 +236,11 @@ public class loadSettlementTeamPrefab : MonoBehaviour
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 格式化角色名字为"称号 名字"的形式
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
/// <param name="designation">称号</param>
|
||||
/// <param name="name">名字</param>
|
||||
/// <returns>格式化后的名字</returns>
|
||||
/// Documentation text normalized.
|
||||
/// Documentation text normalized.
|
||||
/// Documentation text normalized.
|
||||
private string FormatAllyName(string designation, string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(designation))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class settleTeamPrefab : MonoBehaviour
|
||||
@@ -11,24 +11,24 @@ public class settleTeamPrefab : MonoBehaviour
|
||||
[Header("this_Ally_settlement")]
|
||||
public Text thisAlly_earnExp;
|
||||
public Text this_allyIdolScore;
|
||||
[Header("本场贡献")]
|
||||
[Header("Inspector")]
|
||||
public Text this_allyDamageDealt;
|
||||
public Text this_allyDamageTook;
|
||||
public Text this_allyHealthRestored;
|
||||
public Text this_allyManaRestored;
|
||||
[Header("展示详细贡献按钮")]
|
||||
[Header("Inspector")]
|
||||
public Button displayDetailContributionButton;
|
||||
public GameObject detailContributionGO;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// 初始化:详细贡献面板默认不激活
|
||||
// Documentation text normalized.
|
||||
if (detailContributionGO != null)
|
||||
{
|
||||
detailContributionGO.SetActive(false);
|
||||
}
|
||||
|
||||
// 为按钮添加点击监听
|
||||
// Documentation text normalized.
|
||||
if (displayDetailContributionButton != null)
|
||||
{
|
||||
displayDetailContributionButton.onClick.AddListener(OnDisplayDetailContributionButtonClicked);
|
||||
@@ -37,7 +37,7 @@ public class settleTeamPrefab : MonoBehaviour
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
// 移除监听以避免内存泄漏
|
||||
// Documentation text normalized.
|
||||
if (displayDetailContributionButton != null)
|
||||
{
|
||||
displayDetailContributionButton.onClick.RemoveListener(OnDisplayDetailContributionButtonClicked);
|
||||
@@ -52,7 +52,7 @@ public class settleTeamPrefab : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
// 切换详细贡献面板的激活状态
|
||||
// Documentation text normalized.
|
||||
bool isCurrentlyActive = detailContributionGO.activeSelf;
|
||||
detailContributionGO.SetActive(!isCurrentlyActive);
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
//适用于编队 列表
|
||||
// Documentation text normalized.
|
||||
public class teamCharacterView : MonoBehaviour
|
||||
{
|
||||
public int characterID;
|
||||
@@ -31,7 +31,7 @@ public class teamCharacterView : MonoBehaviour
|
||||
controlButton.SetActive(isSelected);
|
||||
}
|
||||
/// <summary>
|
||||
/// 单机team列表内对象时触发选定
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
public void SetSelected()
|
||||
{
|
||||
@@ -47,7 +47,7 @@ public class teamCharacterView : MonoBehaviour
|
||||
TeamManager.Instance.setCurrentSelectedCharacterInTeam(-1);
|
||||
}
|
||||
/// <summary>
|
||||
/// 将当前队伍选中角色向下交换位置
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
public void downChangeTeamElementIndex()
|
||||
{
|
||||
@@ -56,7 +56,7 @@ public class teamCharacterView : MonoBehaviour
|
||||
TeamManager.Instance.swapTeamElements(this.listIndex,this.listIndex+1);
|
||||
}
|
||||
/// <summary>
|
||||
/// 将当前队伍选中角色向上交换位置
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
public void upChangeTeamElementIndex()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
@@ -8,32 +8,29 @@ using Transform = UnityEngine.Transform;
|
||||
public class teamSettingPanel : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// 编队页面顶父级对象,用于控制显示隐藏等操作
|
||||
/// </summary>
|
||||
/// Documentation text normalized.
|
||||
[SerializeField]
|
||||
public GameObject teamSettingPanelObj;
|
||||
/// <summary>
|
||||
/// ui层编队显示,包含五个组件
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public GameObject[] teamElementsObj;
|
||||
/// <summary>
|
||||
/// 编队显示上层切换编队预设按钮
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
[SerializeField] public TeamIndexSetterView[] teamSettingButtonStatusObj;
|
||||
/// <summary>
|
||||
/// team用角色数据库总表
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public TeamCharacterList teamCharacterList;
|
||||
/// <summary>
|
||||
/// 等级贴图表
|
||||
/// </summary>
|
||||
/// Documentation text normalized.
|
||||
[SerializeField]
|
||||
public TeamCharacterLevelData teamCharacterLevelData;
|
||||
/// <summary>
|
||||
/// 左侧角色选择页组件
|
||||
/// </summary>
|
||||
/// Documentation text normalized.
|
||||
[SerializeField]
|
||||
public GameObject teamCharacterPrefab;
|
||||
[SerializeField]
|
||||
@@ -84,7 +81,7 @@ public class teamSettingPanel : MonoBehaviour
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 切换预设编队
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
public void updateSelectedTeam(int index)
|
||||
@@ -96,7 +93,7 @@ public class teamSettingPanel : MonoBehaviour
|
||||
{
|
||||
if (teamCharacterList == null)
|
||||
{
|
||||
Debug.LogError("teamCharacterList 缺失");
|
||||
Debug.LogError("teamCharacterList is missing.");
|
||||
return null;
|
||||
}
|
||||
foreach (TeamCharacterDataInfo tcdi in teamCharacterList.characters)
|
||||
@@ -106,7 +103,7 @@ public class teamSettingPanel : MonoBehaviour
|
||||
return tcdi;
|
||||
}
|
||||
}
|
||||
Debug.LogWarning($"未找到{characterID}对应的角色信息");;
|
||||
Debug.LogWarning($"Character data not found for characterID={characterID}.");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -114,7 +111,7 @@ public class teamSettingPanel : MonoBehaviour
|
||||
{
|
||||
if(level==null)
|
||||
{
|
||||
Debug.LogWarning("level为空,无法获取对应等级贴图");
|
||||
Debug.LogWarning("Level is null, cannot resolve level sprite.");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -129,13 +126,12 @@ public class teamSettingPanel : MonoBehaviour
|
||||
case "C":
|
||||
return teamCharacterLevelData.LevelCSprite;
|
||||
default:
|
||||
Debug.LogWarning($"未找到对应等级贴图,当前等级为:{level}");
|
||||
Debug.LogWarning($"No level sprite mapped for level '{level}'.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 把队列恢复到空视图状态
|
||||
/// </summary>
|
||||
/// Documentation text normalized.
|
||||
public void clearTeamSettingElements()
|
||||
{
|
||||
foreach (GameObject gameObject in teamElementsObj)
|
||||
@@ -223,8 +219,7 @@ public class teamSettingPanel : MonoBehaviour
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取当前可选入队伍的角色列表,并显示在界面上
|
||||
/// </summary>
|
||||
/// Documentation text normalized.
|
||||
public void updateSelectableCharacterViewList()
|
||||
{
|
||||
foreach (Transform child in teamCharacterViewContent.transform)
|
||||
@@ -266,8 +261,7 @@ public class teamSettingPanel : MonoBehaviour
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// 用于保证team内对象的选中状态一致
|
||||
/// </summary>
|
||||
/// Documentation text normalized.
|
||||
public void updateTeamCharacterSelectedStatus()
|
||||
{
|
||||
int currentSelectedCharacter = teamManager.currentSelectedTeamCharacter;
|
||||
@@ -289,8 +283,7 @@ public class teamSettingPanel : MonoBehaviour
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 右切换编队信息
|
||||
/// </summary>
|
||||
/// Documentation text normalized.
|
||||
public void rightChangeTeamSettingIndex()
|
||||
{
|
||||
int currentSelectedTeam = teamManager.currentSelectedTeam;
|
||||
@@ -300,8 +293,7 @@ public class teamSettingPanel : MonoBehaviour
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 左切换编队信息
|
||||
/// </summary>
|
||||
/// Documentation text normalized.
|
||||
public void leftChangeTeamSettingIndex()
|
||||
{
|
||||
int currentSelectedTeam = teamManager.currentSelectedTeam;
|
||||
|
||||
Reference in New Issue
Block a user