using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using Cysharp.Threading.Tasks; using DG.Tweening; public class DamageContent : MonoBehaviour, IBattleFloatingUI { public GameObject line; public RectTransform parent; [Header("Floating Config")] [Tooltip("请在Inspector中拖拽FloatingConfig资源")] public FloatingConfig floatingConfig; protected List damageLineList = new List(); private BattleDmgInfo battleDmgInfo; private BattleFloatingUIController controller; #region Unity Lifecycle void Awake() { line.SetActive(false); } #endregion #region Controller Management private void InitController() { if (controller != null) return; if (floatingConfig == null) { Debug.LogError($"[DamageContent] FloatingConfig 未配置,请在Inspector中拖拽赋值! GameObject: {gameObject.name}"); return; } RectTransform rectTransform = GetComponent(); controller = new BattleFloatingUIController(rectTransform, gameObject, ApplyColor, floatingConfig); } public void SetRatio(float speed, float scale) { InitController(); controller?.SetRatio(speed, scale); } public void SetFloatingConfig(FloatingConfig config) { floatingConfig = config; if (controller != null) { controller.SetConfig(config); } } #endregion #region Position Management /// /// 设置飘字的起点和终点位置(运行时动态设置) /// public void SetPosition(Vector2 beginPos, Vector2 endPos) { InitController(); controller?.SetRuntimePosition(beginPos, endPos); } #endregion #region Damage Display public void SetDamage(BattleDmgInfo _battleDmgInfo, List damages, Action _onComplete) { battleDmgInfo = _battleDmgInfo; EnsureDamageLineCapacity(damages.Count); DisplayDamageLines(damages); HideExcessDamageLines(damages.Count); bool isCrit = battleDmgInfo.IsCrit(); Play(isCrit, _onComplete); } /// /// 确保有足够的DamageLine对象 /// private void EnsureDamageLineCapacity(int requiredCount) { RectTransform lineTemplate = line.GetComponent(); Vector2 templateAnchorMin = lineTemplate.anchorMin; Vector2 templateAnchorMax = lineTemplate.anchorMax; Vector2 templatePivot = lineTemplate.pivot; for (int i = damageLineList.Count; i < requiredCount; i++) { GameObject newLine = GameObject.Instantiate(line, parent); DamageLine damageLine = newLine.GetComponent(); RectTransform newLineRect = newLine.GetComponent(); if (newLineRect != null) { newLineRect.anchorMin = templateAnchorMin; newLineRect.anchorMax = templateAnchorMax; newLineRect.pivot = templatePivot; newLineRect.anchoredPosition = Vector2.zero; newLineRect.localScale = Vector3.one; } damageLineList.Add(damageLine); } } /// /// 显示伤害行并设置位置 /// private void DisplayDamageLines(List damages) { for (int i = 0; i < damages.Count; i++) { DamageLine damageLine = damageLineList[i]; SetDamageLinePosition(damageLine, i); damageLine.SetActive(true); damageLine.SetDamage(damages[i]); } } /// /// 设置单个伤害行的位置(使用Y轴偏移) /// private void SetDamageLinePosition(DamageLine damageLine, int index) { RectTransform lineRect = damageLine.GetComponent(); if (lineRect == null) return; RectTransform lineTemplate = line.GetComponent(); Vector2 basePos = lineTemplate.anchoredPosition; Vector2 pos = basePos; pos.y += 60f * index; lineRect.anchoredPosition = pos; } /// /// 隐藏多余的伤害行 /// private void HideExcessDamageLines(int displayCount) { for (int i = displayCount; i < damageLineList.Count; i++) { damageLineList[i].SetActive(false); } } #endregion #region Animation Control public void Play(bool isCrit, Action onComplete = null) { InitController(); controller?.Play(isCrit, onComplete); } public void Run() { if (controller == null) return; controller.Run(); } public void Stop() { if (controller == null) return; controller.Stop(); } public void Resume() { if (controller == null) return; controller.Resume(); } #endregion #region Visual Effects private void ApplyColor(Color color) { for (int i = 0; i < damageLineList.Count; i++) { if (damageLineList[i].gameObject.activeSelf) { damageLineList[i].SetColor(color); } } } #endregion }