using System.Collections.Generic; using UnityEngine; using Game.Battle; namespace Game { /// /// 实体身上的UI显示,均在此管理 /// public class PageHeadBar : UIPageBase { private int _targetCache = 0; private readonly Dictionary> _hpBarDict = new Dictionary>(); private readonly Dictionary>> _hitNumDict = new Dictionary>>(); private readonly Dictionary>> _hitBuffDict = new Dictionary>>(); private readonly Dictionary> _interactDict = new Dictionary>(); protected override void OnCreate() { CreateUI(false); } protected override void OnOpen() { //打开时创建所有非主角实体的血条 var entities = Util.GetGroup(GameMatcher.Interact); //怪物、npc、宝箱、传送门... foreach (var entity in entities) { if (entity.iD.Data.IsDestroy) { continue; } SetHpBar(entity.ID(), true); SetHitNum(entity.ID(), true); SetInteract(entity.ID(), true); } EventManager.Instance.AddEvent(EEvent.EntityAlive, OnEntityAlive); EventManager.Instance.AddEvent(EEvent.EntityHit, OnEntityHit); EventManager.Instance.AddEvent(EEvent.EntityHitText, OnEntityHitText); UpdateHeadBarPos(); //打开时更新位置 避免闪烁 } protected override void OnClose() { foreach (var kvp in _hpBarDict) { kvp.Value.Destroy(); } _hpBarDict.Clear(); EventManager.Instance.RemoveEvent(EEvent.EntityAlive, OnEntityAlive); EventManager.Instance.RemoveEvent(EEvent.EntityHit, OnEntityHit); EventManager.Instance.RemoveEvent(EEvent.EntityHitText, OnEntityHitText); } public override void FixedUpdate() { UpdateLock(); //锁定 UpdateHeadBarPos(); //headBar位置更新 UpdateHitNum(); //跳字更新 UpdateHitBuff(); //buff跳字更新 } private void UpdateLock() { var master = Util.GetMaster(); var targetId = master.combo.TargetLock; var target = Util.GetEntity(targetId); View.m_showLock.SetSelectedIndex(target == null ? 0 : 1); if (target == null) return; if (targetId != _targetCache) { View.m_lock.m_actLock.Play(); _targetCache = targetId; } View.m_lock.position = GetScreenPos(Util.EntityViewPos(target)); } private void UpdateHeadBarPos() { foreach (var kvp in _hpBarDict) { var entity = Util.GetEntity(kvp.Key); if (entity != null) { var headBarItem = kvp.Value; var posScreen = GetScreenPos(Util.EntityViewPos(entity)); headBarItem.Component.SetPosition(posScreen.x, posScreen.y - 80, posScreen.z); } } foreach (var kvp in _hitNumDict) { var entity = Util.GetEntity(kvp.Key); if (entity != null) { var hitNumList = kvp.Value; var posScreen = GetScreenPos(Util.EntityViewPos(entity)); foreach (var item in hitNumList) { item.Component.SetPosition(posScreen.x, posScreen.y, posScreen.z); } } } foreach (var kvp in _hitBuffDict) { var entity = Util.GetEntity(kvp.Key); if (entity != null) { var hitNumList = kvp.Value; var posScreen = GetScreenPos(Util.EntityViewPos(entity)); foreach (var item in hitNumList) { item.Component.SetPosition(posScreen.x, posScreen.y - 40, posScreen.z); } } } foreach (var kvp in _interactDict) { var entity = Util.GetEntity(kvp.Key); if (entity != null) { var interactItem = kvp.Value; var posScreen = GetScreenPos(Util.EntityViewPos(entity)); interactItem.Component.SetPosition(posScreen.x, posScreen.y - 80, posScreen.z); } } } /// /// 更新伤害跳字:更新动效等待时间,等待时间结束播放2阶段动效 2阶段动效结束删除 /// private void UpdateHitNum() { foreach (var kvp in _hitNumDict) { var hitNumList = kvp.Value; if (hitNumList.Count == 0) { continue; } var entity = Util.GetEntity(kvp.Key); if (entity == null) { continue; } if (entity.pause.IsPause) { continue; } var hp = entity.hp; if (hp.DmgShowTime > 0) { hp.DmgShowTime -= Time.deltaTime; if (hp.DmgShowTime <= 0) { hp.DmgShowTime = 0; var lastItem = hitNumList[hitNumList.Count - 1].Component as ViewHitNum; lastItem.m_step2.Play(); if (GameRandom.Roll(0.5f)) { lastItem.m_step3.Play(); } else { lastItem.m_step4.Play(); } } } for (int i = hitNumList.Count - 1; i >= 0; i--) { if (i == hitNumList.Count - 1 && hp.DmgShowTime > 0) { continue; } var item = hitNumList[i]; var hitInfo = hitNumList[i].Component as ViewHitNum; if (!hitInfo.m_step2.playing) { item.Destroy(); hitNumList.RemoveAt(i); } } } } private void UpdateHitBuff() { foreach (var kvp in _hitBuffDict) { var hitNumList = kvp.Value; if (hitNumList.Count == 0) { continue; } var entity = Util.GetEntity(kvp.Key); if (entity == null) { continue; } if (entity.pause.IsPause) { continue; } for (int i = hitNumList.Count - 1; i >= 0; i--) { var item = hitNumList[i]; var hitInfo = hitNumList[i].Component as ViewHitBuff; if (entity.pause.IsPause) { hitInfo.m_step1.SetPaused(true); continue; } hitInfo.m_step1.SetPaused(false); if (!hitInfo.m_step1.playing) { item.Destroy(); hitNumList.RemoveAt(i); } } } } private void OnEntityAlive(PEntityAlive param) { var entity = param.Entity; if (entity == Util.GetMasterID()) { return; } SetHpBar(param.Entity, param.IsAlive); SetHitNum(param.Entity, param.IsAlive); SetInteract(param.Entity, param.IsAlive); } private void SetInteract(int entityID, bool isAlive = true) { var entity = Util.GetEntity(entityID); if (!entity.hasInteract) { return; } if (isAlive) { if (!_interactDict.ContainsKey(entityID)) { var interactBar = UIManager.Instance.Creator.CreateUIItem(ViewInteract.URL); _interactDict[entityID] = interactBar; var interactComp = interactBar.Component; var interact = entity.interact; BindData(interact.IsActive, (_, now) => { interactComp.m_showInteract.selectedIndex = now ? 1 : 0; }); BindData(interact.IsTarget, (_, now) => { interactComp.m_isTarget.selectedIndex = now ? 1 : 0; }); } } else { if (_interactDict.ContainsKey(entityID)) { _interactDict[entityID].Destroy(); _interactDict.Remove(entityID); var interact = entity.interact; UnbindData(interact.IsActive); UnbindData(interact.IsTarget); } } } private void SetHitNum(int entityID, bool isAlive = true) { if (isAlive) { if (!_hitNumDict.ContainsKey(entityID)) { _hitNumDict[entityID] = new List>(); _hitBuffDict[entityID] = new List>(); } } else { if (_hitNumDict.ContainsKey(entityID)) { foreach (var item in _hitNumDict[entityID]) { item.Destroy(); } _hitNumDict.Remove(entityID); foreach (var item in _hitBuffDict[entityID]) { item.Destroy(); } _hitBuffDict.Remove(entityID); } } } private void SetHpBar(int entityID, bool isAlive = true) { var entity = Util.GetEntity(entityID); if (!entity.hasHp) { return; } if (isAlive) { if (!_hpBarDict.ContainsKey(entityID)) { //创建血条UI var hpBar = UIManager.Instance.Creator.CreateUIItem(Viewc_blood.URL); _hpBarDict[entityID] = hpBar; var hpComp = hpBar.Component; if (entity.hasHp) { var hp = entity.hp; var buff = entity.buff; var ai = entity.aI; //数据绑定 BindData(hp.IsDamaged, (_, now) => { hpComp.m_showhp.selectedIndex = now ? 1 : 0; hpComp.m_showshield.selectedIndex = now && (hp.ShieldMax.Value > 0) ? 1 : 0; //是否显示额外数据 var isShowExtra = now && GameSetting.IsShowExtraHeadBar; hpComp.m_showExtra.selectedIndex = isShowExtra ? 1 : 0; }); BindData(hp.HpMax, (_, now) => { hpComp.m_bloodBarEnemy.m_sub.max = now; hpComp.m_bloodBarEnemy.m_tween.max = now; //根据hpMax动态调整血条长度 var width = Mathf.Clamp(now, 40, 150); hpComp.m_bloodBarEnemy.width = width; hpComp.m_shieldBarEnemy.width = width; }); BindData(hp.Hp, (_, now) => { hpComp.m_bloodBarEnemy.m_sub.value = now; hpComp.m_bloodBarEnemy.m_tween.TweenValue(now - 1, 0.5f); }); BindData(hp.ShieldMax, (_, now) => { hpComp.m_shieldBarEnemy.m_sub.max = now; hpComp.m_shieldBarEnemy.m_tween.max = now; hpComp.m_showshield.selectedIndex = hp.IsDamaged.Value && (now > 0) ? 1 : 0; }); BindData(hp.Shield, (_, now) => { hpComp.m_shieldBarEnemy.m_sub.value = now; hpComp.m_shieldBarEnemy.m_tween.TweenValue(now - 1, 0.5f); hpComp.m_showshield.selectedIndex = hp.IsDamaged.Value && (now > 0) ? 1 : 0; }); BindData(hp.Stun, (_, now) => { hpComp.m_stunBarEnemy.value = now; }); BindData(hp.StunMax, (_, now) => { hpComp.m_stunBarEnemy.max = now; }); BindData(ai.Hungry, (_, now) => { hpComp.m_hungryBarEnemy.value = now; }); BindData(ai.HungryMax, (_, now) => { hpComp.m_hungryBarEnemy.max = now; }); BindData(ai.ModuleType, (_, now) => { hpComp.m_moduleType.selectedIndex = (int)now; }); BindData(ai.IsHungryFull, (_, now) => { if (now) { hpComp.m_attackStatus.selectedIndex = 1; } }); BindData(ai.AttackPermit, (_, now) => { if (now) { hpComp.m_attackStatus.selectedIndex = 2; } else { hpComp.m_attackStatus.selectedIndex = 0; } }); } } } else { if (_hpBarDict.ContainsKey(entityID)) { //销毁血条ui _hpBarDict[entityID].Destroy(); _hpBarDict.Remove(entityID); //取消数据绑定 if (entity.hasHp) { var hp = entity.hp; var ai = entity.aI; var buff = entity.buff; UnbindData(hp.HpMax); UnbindData(hp.Hp); UnbindData(hp.ShieldMax); UnbindData(hp.Shield); UnbindData(hp.StunMax); UnbindData(hp.Stun); UnbindData(ai.HungryMax); UnbindData(ai.Hungry); UnbindData(ai.ModuleType); UnbindData(ai.IsHungryFull); UnbindData(ai.AttackPermit); } } } } private void OnEntityHit(PEntityHit param) { AddHitNum(param.Target, param.Dmg); } private void OnEntityHitText(PEntityHitText param) { AddHitText(param.Target, param.Text); } private void AddHitNum(int entityID, int dmg) { if (!_hitNumDict.ContainsKey(entityID)) { return; } var hitList = _hitNumDict[entityID]; var hp = Util.GetEntity(entityID).hp; ViewHitNum targetItem = null; if (hp.DmgShowTime == 0) { hp.LastDmg = dmg; var hitNum = UIManager.Instance.Creator.CreateUIItem(ViewHitNum.URL); var item = hitNum.Component as ViewHitNum; hitList.Add(hitNum); targetItem = item; } else { hp.LastDmg += dmg; targetItem = hitList[hitList.Count - 1].Component as ViewHitNum; } targetItem.m_num.text = $"{hp.LastDmg}"; targetItem.m_step1.Play(); hp.DmgShowTime = GameConst.HitNumTerm; } private void AddHitText(int entityID, string text) { if (!_hitBuffDict.ContainsKey(entityID)) { return; } var hitList = _hitBuffDict[entityID]; var hitNum = UIManager.Instance.Creator.CreateUIItem(ViewHitBuff.URL); hitList.Add(hitNum); var item = hitNum.Component as ViewHitBuff; item.m_name.text = text; item.m_step1.Play(); } } }