| using System.Collections; | 
| using Cysharp.Threading.Tasks; | 
| using DG.Tweening; | 
| using UnityEngine; | 
| using UnityEngine.UI; | 
|   | 
| public class TotalDamageDisplayer : MonoBehaviour | 
| { | 
|     public Image damageBackground; | 
|     public Text textDamage; | 
|     public Text textTotalDesc; //总伤害或者总治疗 | 
|   | 
|     public UniTask task = default; | 
|   | 
|     private Coroutine hideCoroutine; | 
|     private int hideVersion = 0; | 
|   | 
|     private long damage = 0; | 
|   | 
|     private long heal = 0; | 
|   | 
|     public void SetDamage(BattleDmgInfo dmgInfo) | 
|     { | 
|         // 先统一停止并清理此前的隐藏协程(如果有) | 
|         ClearHideCoroutine(); | 
|   | 
|         if (!gameObject.activeInHierarchy) | 
|             gameObject.SetActive(true); | 
|   | 
|         if (dmgInfo == null) | 
|             return; | 
|   | 
|         if (dmgInfo.IsType(DamageType.Recovery)) | 
|         { | 
|             // 保持原有处理逻辑位置 | 
|             foreach (var h in dmgInfo.damageList) | 
|             { | 
|                 heal += h; | 
|             } | 
|             textDamage.text = BattleUtility.DisplayDamageNum(heal, BattleConst.BattleTotalRecoverType); | 
|             textTotalDesc.text = "总治疗"; | 
|         } | 
|         else if (dmgInfo.IsType(DamageType.Damage) || dmgInfo.IsType(DamageType.Realdamage)) | 
|         { | 
|             // 保持原有处理逻辑位置 | 
|             foreach (var d in dmgInfo.damageList) | 
|             { | 
|                 damage += d; | 
|             } | 
|             textDamage.text = BattleUtility.DisplayDamageNum(damage, BattleConst.BattleTotalDamageType); | 
|             textTotalDesc.text = "总伤害"; | 
|         } | 
|   | 
|         textDamage.transform.DOPunchScale(Vector3.one * 0.2f, 0.2f, 1).OnComplete(() => | 
|         { | 
|             textDamage.transform.localScale = Vector3.one; | 
|         }); | 
|   | 
|         if (dmgInfo.isLastHit) | 
|         { | 
|             // 启动新的隐藏协程,先生成新的版本号以用于协程有效性校验 | 
|             hideVersion++; | 
|             int myVersion = hideVersion; | 
|   | 
|             damage = 0; | 
|             heal = 0; | 
|   | 
|             var battleField = BattleManager.Instance.GetBattleField(dmgInfo.battleFieldGuid); | 
|   | 
|             float ms = 500f / battleField.speedRatio; | 
|   | 
|             hideCoroutine = StartCoroutine(HideAfterDelayCoroutine(ms, myVersion)); | 
|   | 
|             task = default; | 
|         } | 
|     } | 
|   | 
|     protected void OnDisable() | 
|     { | 
|         ClearHideCoroutine(); | 
|         hideVersion++; | 
|     } | 
|   | 
|     protected void OnDestroy() | 
|     { | 
|         ClearHideCoroutine(); | 
|         hideVersion++; | 
|     } | 
|   | 
|     public void CancelHide() | 
|     { | 
|         ClearHideCoroutine(); | 
|         hideVersion++; | 
|     } | 
|   | 
|     private void ClearHideCoroutine() | 
|     { | 
|         if (hideCoroutine != null) | 
|         { | 
|             try { StopCoroutine(hideCoroutine); } catch { } | 
|             hideCoroutine = null; | 
|         } | 
|     } | 
|   | 
|     private IEnumerator HideAfterDelayCoroutine(float secondsDelay, int version = 0) | 
|     { | 
|         yield return new WaitForSeconds(secondsDelay); | 
|   | 
|         if (version != 0 && version != hideVersion) | 
|             yield break; | 
|   | 
|         if (this == null) yield break; | 
|         if (gameObject != null) | 
|             gameObject.SetActive(false); | 
|   | 
|         if (hideCoroutine != null) | 
|             hideCoroutine = null; | 
|     } | 
| } |