using System.Collections.Generic; using Logic.Skill; using RuntimeData; using TH1_Logic.Core; using UnityEngine; namespace TH1_Renderer { internal class UnitStatusIcon { public int Level; public StatusIconMono IconMono; public GameObject IconObject; } /// /// 单位状态管理器 - 管理单位的所有重要负面状态显示 /// public class UnitStatusArea { private readonly Dictionary _statusIcons = new(); private readonly Dictionary _statusLevels = new(); private readonly Transform _statusContainer; private readonly GameObject _statusIconPrefab; private readonly UnityEngine.RectTransform _infoGroup; // private const string KOMEIJI_FEAR_PATH = "TH1UI/Icon/SkillIcon/Komeiji/Skill_KomeijiFear"; // private const string KOMEIJI_FEAR2_PATH = "TH1UI/Icon/SkillIcon/Komeiji/Skill_KomeijiFear2"; /// /// 当前显示的状态数量 /// public int Count => _statusIcons.Count; /// /// 获取所有当前显示的状态 /// internal IEnumerable AllIcons => _statusIcons.Values; public UnitStatusArea(Transform statusContainer, GameObject statusIconPrefab, UnityEngine.RectTransform infoGroup = null) { _statusContainer = statusContainer; _statusIconPrefab = statusIconPrefab; _infoGroup = infoGroup; } /// /// 添加或更新状态显示 /// /// 技能类型 /// 单位完整类型 /// 是否有层数机制 /// 技能等级/层数 /// 是否成功添加或更新 public bool AddOrUpdateStatus(SkillType skillType, UnitFullType unitFullType, bool hasLevel, int level) { if (_statusIconPrefab == null || _statusContainer == null) return false; if (!_statusIcons.TryGetValue(skillType, out var existingIcon)) { var newIconObj = GameObject.Instantiate(_statusIconPrefab, _statusContainer); var iconMono = newIconObj.GetComponent(); if (iconMono == null) { iconMono = newIconObj.AddComponent(); } existingIcon = new UnitStatusIcon { IconObject = newIconObj, IconMono = iconMono, Level = 0 }; _statusIcons.Add(skillType, existingIcon); } existingIcon.Level = level; existingIcon.IconMono.SetContent(skillType, unitFullType, hasLevel, level); // if (skillType == SkillType.KomeijiFear) // { // string targetPath = level >= 2 ? KOMEIJI_FEAR2_PATH : KOMEIJI_FEAR_PATH; // var specialSprite = TH1Resource.ResourceLoader.Load(targetPath); // if (specialSprite != null) // { // existingIcon.IconMono.SetIcon(specialSprite); // } // existingIcon.IconMono.SetColor(Color.green); // } // else // { // existingIcon.IconMono.SetColor(Color.white); // } existingIcon.IconMono.SetColor(Color.white); _statusLevels[skillType] = level; RefreshLayout(); return true; } /// /// 移除指定状态 /// /// 技能类型 /// 是否成功移除 public bool RemoveStatus(SkillType skillType) { if (!_statusIcons.TryGetValue(skillType, out var icon)) return false; if (icon.IconObject != null) { // GameObject.Destroy 是延迟销毁;先 SetActive(false) 让 LayoutGroup 在本帧 // 重建时立即忽略此节点,否则 StatusAreaContainer 的尺寸测量仍会包含它, // 导致父节点(InfoGroup/背景板)的尺寸无法收缩。 icon.IconObject.SetActive(false); GameObject.Destroy(icon.IconObject); } _statusIcons.Remove(skillType); _statusLevels.Remove(skillType); // 移除后强制刷新布局 RefreshLayout(); return true; } /// /// 检查是否包含指定状态 /// public bool HasStatus(SkillType skillType) { return _statusIcons.ContainsKey(skillType); } /// /// 获取指定状态的层数 /// public int GetStatusLevel(SkillType skillType) { return _statusLevels.TryGetValue(skillType, out var level) ? level : 0; } /// /// 清除所有状态 /// public void ClearAllStatus() { foreach (var icon in _statusIcons.Values) { if (icon.IconObject != null) { // 先 SetActive(false) 让 LayoutGroup 立即忽略,再 Destroy(延迟销毁)。 icon.IconObject.SetActive(false); GameObject.Destroy(icon.IconObject); } } _statusIcons.Clear(); _statusLevels.Clear(); // 清除后强制刷新布局 RefreshLayout(); } /// /// 同步单位技能数据到状态显示区域 /// 仅显示 SkillInfo.ShowOnUnitMono = true 且当前单位拥有的技能 /// public void SyncWithUnitSkills(UnitData unitData) { if (unitData == null || unitData.Skills == null) return; var showSkills = new HashSet(); foreach (var skill in unitData.Skills) { if (skill == null) continue; var skillType = skill.GetSkillType(); if (!Table.Instance.SkillDataAssets.GetSkillInfo(skillType, out var skillInfo)) continue; if (skillInfo.ShowOnUnitMono) { showSkills.Add(skillType); } } var toRemove = new List(); foreach (var skillType in _statusIcons.Keys) { if (!showSkills.Contains(skillType)) toRemove.Add(skillType); } bool hasChanged = false; foreach (var skillType in toRemove) { RemoveStatus(skillType); hasChanged = true; } foreach (var skillType in showSkills) { if (!unitData.GetSkill(skillType, out var skill)) { if (HasStatus(skillType)) { RemoveStatus(skillType); hasChanged = true; } continue; } if (skill.HasLevel && skill.NoShow) { if (HasStatus(skillType)) { RemoveStatus(skillType); hasChanged = true; } continue; } bool hasLevel = skill.HasLevel; int level = hasLevel ? skill.Level : 1; if (!HasStatus(skillType) || GetStatusLevel(skillType) != level) { AddOrUpdateStatus(skillType, unitData.UnitFullType, hasLevel, level); hasChanged = true; } else if (_statusIcons.TryGetValue(skillType, out var existingIcon)) { existingIcon.IconMono.SetContent(skillType, unitData.UnitFullType, hasLevel, level); } } if (hasChanged) { RefreshLayout(); } } /// /// 刷新所有状态的显示位置(用于自动布局更新) /// public void RefreshLayout() { if (_statusContainer == null) return; // 强制刷新布局 if (_statusContainer is UnityEngine.RectTransform rectTransform) { UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform); } // 图标增减后同时重排 InfoGroup,让背景板等父级 LayoutGroup 感知尺寸变化 if (_infoGroup != null) { UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(_infoGroup); } } /// /// 设置整个状态区域是否可见 /// public void SetAreaVisible(bool visible) { if (_statusContainer != null) _statusContainer.gameObject.SetActive(visible); } } }