using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEngine.UI; using DG.Tweening; using Cysharp.Threading.Tasks; using System; using LitJson; // 这个界面是 persistent的界面 public class BattleHUDWin : UIBase { private GameObjectPoolManager.GameObjectPool damagePrefabPool; private GameObjectPoolManager.GameObjectPool buffIconPrefabPool; private GameObjectPoolManager.GameObjectPool buffLabelPrefabPool; public Transform damageNode; public Transform buffIconNode; public Transform buffLabelNode; private BattleField battleField; private List damageContentList = new List(); protected override void InitComponent() { base.InitComponent(); } protected override void OnPreOpen() { base.OnPreOpen(); EventBroadcast.Instance.AddListener(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken); EventBroadcast.Instance.AddListener(EventName.BATTLE_END, OnBattleEnd); damagePrefabPool = GameObjectPoolManager.Instance.RequestPool(UILoader.LoadPrefab("DamageContent")); } private void OnBattleEnd(string guid, JsonData data) { ClearContent(guid); } private void ClearContent(string guid, bool force = false) { if ((battleField != null && battleField.guid == guid) || force) { for (int i = damageContentList.Count - 1; i >= 0; i--) { var content = damageContentList[i]; content.Stop(); RemoveDamageContent(content); } damageContentList.Clear(); } } protected override void OnPreClose() { base.OnPreClose(); EventBroadcast.Instance.RemoveListener(EventName.BATTLE_DAMAGE_TAKEN, OnDamageTaken); EventBroadcast.Instance.RemoveListener(EventName.BATTLE_END, OnBattleEnd); } protected override void OnOpen() { base.OnOpen(); } protected override void OnClose() { base.OnClose(); if (battleField != null) { battleField.OnBattlePause -= OnBattlePause; battleField.OnBattleRun -= OnBattleRun; battleField.OnSpeedRatioChange -= OnSpeedRatioChange; battleField = null; } } protected override void NextFrameAfterOpen() { base.NextFrameAfterOpen(); } protected override void CompleteClose() { base.CompleteClose(); } private void RemoveDamageContent(DamageContent content) { damageContentList.Remove(content); damagePrefabPool.Release(content.gameObject); } private void OnDamageTaken(BattleDmgInfo damageInfo) { GameObject damageContent = damagePrefabPool.Request(); DamageContent content = damageContent.GetComponent(); damageContent.transform.SetParent(damageNode, false); var heroRect = damageInfo.hurtObj.heroRectTrans; if (heroRect == null) { damagePrefabPool.Release(damageContent); return; } var contentRect = content.GetComponent(); var contentParentRect = contentRect.parent as RectTransform; // 获取 heroRect 的世界坐标(锚点为中心) Vector3 worldTargetPos = heroRect.transform.TransformPoint(heroRect.rect.center); // 转换到 content 父节点下的 anchoredPosition Vector2 anchoredPos; RectTransformUtility.ScreenPointToLocalPointInRectangle( contentParentRect, RectTransformUtility.WorldToScreenPoint(null, worldTargetPos), null, out anchoredPos); // 设置动态位置(会覆盖配置中的位置) Vector2 beginPos = anchoredPos; Vector2 endPos = anchoredPos + new Vector2(0, 150); content.SetPosition(beginPos, endPos); // 设置速度比例 if (battleField != null) { content.SetRatio(battleField.speedRatio, 1f); } // 设置伤害数据并开始播放 content.SetDamage(damageInfo, () => RemoveDamageContent(content)); damageContentList.Add(content); } public void SetBattleField(BattleField _battleField) { if (battleField != null) { battleField.OnBattlePause -= OnBattlePause; battleField.OnBattleRun -= OnBattleRun; battleField.OnSpeedRatioChange -= OnSpeedRatioChange; } ClearContent(string.Empty, true); battleField = _battleField; battleField.OnBattlePause += OnBattlePause; battleField.OnBattleRun += OnBattleRun; battleField.OnSpeedRatioChange += OnSpeedRatioChange; } private void OnSpeedRatioChange(float newSpeedRatio) { foreach (var content in damageContentList) { content.SetRatio(newSpeedRatio, 1f); } } private void OnBattlePause(bool isPause) { if (isPause) { foreach (var content in damageContentList) { content.Stop(); } } else { foreach (var content in damageContentList) { content.Resume(); } } } private void OnBattleRun() { for (int i = damageContentList.Count - 1; i >= 0; i--) { if (i < damageContentList.Count) { damageContentList[i].Run(); } } } }