using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System.Text; namespace vnxbqy.UI { [DisallowMultipleComponent] public class PopUpNum : MonoBehaviour { [SerializeField] Text m_Text; [SerializeField] TweenCurve m_AlphaCurve; [SerializeField] Animation m_Animation; new public Animation animation { get { return m_Animation; } } [SerializeField] FollowTargetIgnoreY m_FollowTarget; [SerializeField] ScreenDiffuseMove m_DiffuseMove; Pattern m_Pattern = Pattern.EnemyAttack; public Pattern pattern { get { return m_Pattern; } set { m_Pattern = value; } } float hideTime = 0f; float startTimeStep2 = 0f; float durationStep1 = 0f; float durationStep2 = 0f; static StringBuilder stringBuild = new StringBuilder(); static int popupQueueMax = 20; static Queue m_PopupInfoQueue = new Queue(); public static Queue popupInfoQueue { get { return m_PopupInfoQueue; } } public static void RecordPopup(PopupInfo _popupInfo) { if (_popupInfo.isPlayer) { while (popupInfoQueue.Count >= popupQueueMax) { popupInfoQueue.Dequeue(); } popupInfoQueue.Enqueue( new PopupInfo() { pattern = _popupInfo.pattern, num = _popupInfo.num, camera = _popupInfo.camera, target = _popupInfo.target, direction = _popupInfo.direction, isPlayer = _popupInfo.isPlayer, realmSuppress = _popupInfo.realmSuppress, } ); } else { Popup(_popupInfo); } } public static void Popup(PopupInfo _popupInfo) { var groups = WindowCenter.Instance.uiRoot.fightCanvasGroup.damageNumGroups; if (groups == null || groups.Length == 0) { return; } if (_popupInfo.target==null || _popupInfo.camera==null) { return; } var popupNum = PopUpNumPool.Require(_popupInfo.pattern); if (popupNum == null) { return; } var uiPosition = CameraUtility.ConvertToUIPosition(_popupInfo.camera, _popupInfo.target.position); var targetGroup = groups[groups.Length - 1]; for (int i = 0; i < groups.Length; i++) { var group = groups[i]; if (group.childCount < 20) { targetGroup = group; break; } } popupNum.transform.SetParent(targetGroup); popupNum.transform.position = uiPosition; popupNum.transform.localPosition = popupNum.transform.localPosition.SetZ(0); popupNum.transform.localScale = Vector3.one; popupNum.PopUp(_popupInfo); } public void PopUp(PopupInfo _popupInfo) { stringBuild.Remove(0, stringBuild.Length); if (_popupInfo.realmSuppress) { var realmSuppressKey = GetRealmSuppressKey(_popupInfo.pattern); if (realmSuppressKey > 0) { stringBuild.Append((char)realmSuppressKey); } } var prefixKey = GetPrefiexKey(_popupInfo.pattern); if (prefixKey > 0) { stringBuild.Append((char)prefixKey); } var symbolKey = GetSymbolKey(_popupInfo.pattern); if (symbolKey > 0) { stringBuild.Append((char)symbolKey); } switch (_popupInfo.pattern) { case Pattern.PlayerMiss: case Pattern.PetMiss: case Pattern.EnemyMiss: case Pattern.PlayerImmune: case Pattern.PetImmune: case Pattern.EnemyImmune: case Pattern.EnemyZhanSha: case Pattern.PetZhanSha: case Pattern.PlayerZhanSha: break; default: var chars = _popupInfo.num.ToString(); for (var i = 0; i < chars.Length; i++) { var numChar = GetNumKey(_popupInfo.pattern, chars[i]); if (numChar > 0) { stringBuild.Append((char)numChar); } } break; } m_Text.text = stringBuild.ToString(); m_Text.color = m_Text.color.SetA(1f); this.SetActive(true); if (m_FollowTarget != null) { if (m_DiffuseMove != null) { switch (m_DiffuseMove.moveType) { case ScreenDiffuseMove.DiffuseType.RelativePosition: case ScreenDiffuseMove.DiffuseType.ReversalRelativePosition: m_FollowTarget.enabled = false; break; default: m_FollowTarget.Follow(_popupInfo.target, _popupInfo.camera); m_FollowTarget.enabled = true; break; } } else { m_FollowTarget.Follow(_popupInfo.target, _popupInfo.camera); m_FollowTarget.enabled = true; } } if (animation != null) { animation.enabled = true; animation.Play(); var clip = animation.clip; if (clip != null) { durationStep1 = clip.length; } } else { durationStep1 = 0f; } if (m_DiffuseMove != null) { m_DiffuseMove.delay = 0f; durationStep2 = m_DiffuseMove.duration; m_DiffuseMove.Begin(_popupInfo.direction, true); m_DiffuseMove.transform.localPosition = Vector3.zero; } durationStep1 = 0f; startTimeStep2 = Time.time + durationStep1; hideTime = Time.time + durationStep1 + durationStep2; PopUpNumPool.recycleAllEvent -= OnReycleAll; PopUpNumPool.recycleAllEvent += OnReycleAll; } public void SetEnable(bool _enable) { m_Animation.enabled = _enable; m_FollowTarget.enabled = _enable; m_DiffuseMove.enabled = _enable; this.enabled = _enable; } int GetRealmSuppressKey(Pattern _pattern) { var config = DamageNumConfig.Get(_pattern.ToString()); return config.realm; } int GetPrefiexKey(Pattern _pattern) { var config = DamageNumConfig.Get(_pattern.ToString()); return config.prefix; } int GetSymbolKey(Pattern _pattern) { var config = DamageNumConfig.Get(_pattern.ToString()); switch (_pattern) { case Pattern.EnemyRecovery: case Pattern.PlayerRecovery: case Pattern.PetRecovery: case Pattern.BuffAddDefense: case Pattern.BuffAddAttack: case Pattern.BuffAddAttackSpeed: case Pattern.BuffAddAccurate: case Pattern.BuffAddDodge: case Pattern.BuffAddMaxHp: case Pattern.BuffAddMoveSpeed: return config.plus; default: return config.minus; } } int GetNumKey(Pattern _pattern, int _num) { var key = string.Empty; var config = DamageNumConfig.Get(_pattern.ToString()); return config.nums[_num - 48]; } void LateUpdate() { if (Time.time > hideTime) { PopUpNumPool.Recycle(this); } else if (Time.time > startTimeStep2) { if (m_AlphaCurve != null) { var t = (Time.time - startTimeStep2) / durationStep2 * m_AlphaCurve.totalTime; m_Text.color = m_Text.color.SetA(1 - m_AlphaCurve.Evaluate(t)); } } } private void OnReycleAll() { PopUpNumPool.recycleAllEvent -= OnReycleAll; PopUpNumPool.Recycle(this); } public enum Pattern { PlayerAttack = 1, //玩家攻击,受击对象为敌对怪物或玩家 PetAttack = 2, //宠物攻击,受击对象为敌对怪物或玩家 EnemyAttack = 3, //敌对怪物或玩家攻击,受击对象为玩家及友方单位 PlayerRecovery = 4, //玩家回复 PetRecovery = 5, //宠物回复 EnemyRecovery = 6, //敌人回复 PlayerTurnTheBlade = 7, //玩家反弹,受击对象为敌对怪物或玩家 PetTurnTheBlade = 8, //宠物反弹,受击对象为敌对怪物或玩家 EnemyTurnTheBlade = 9, //敌人反弹,受击对象为玩家及友方单位 PlayerBleed = 10, //玩家流血 PetBleed = 11, //宠物流血 EnemyBleed = 12, //敌人流血 PlayerParry = 13, //玩家格挡 PetParry = 14, //宠物格挡 EnemyParry = 15, //敌人格挡 PlayerDoubleHit = 16, //玩家连击 PetDoubleHit = 17, //宠物连击 EnemyDoubleHit = 18, //敌人连击 PlayerCrit = 19, //玩家暴击 PetCrit = 20, //宠物暴击 EnemyCrit = 21, //敌人暴击 PlayerHuiXin = 22, //玩家会心一击 PetHuiXin = 23, //宠物会心一击 EnemyHuiXin = 24, //敌人会心一击 PlayerMiss = 25, //玩家Miss PetMiss = 26, //宠物Miss EnemyMiss = 27, //敌人Miss PlayerImmune = 28, //玩家免疫 PetImmune = 29, //宠物免疫 EnemyImmune = 30, //敌人免疫 PlayerZhanSha = 34, //玩家斩杀 PetZhanSha = 35, //宠物斩杀 EnemyZhanSha = 36, //敌人斩杀 PlayerZhuXian = 37, //玩家诛仙 PetZhuXian = 38, //宠物诛仙 EnemyZhuXian = 39, //敌人诛仙 PlayerDeadlyHit = 43, //玩家致死一击 PetDeadlyHit = 44, //宠物致死一击 EnemyDeadlyHit = 45, //敌人致死一击 PlayerThumpHit = 46, //玩家重击 PetThumpHit = 47, //宠物重击 EnemyThumpHit = 48, //敌人重击 PlayerYinji = 49, //玩家印记 PetYinji = 50, //宠物印记 EnemyYinji = 51, //敌人印记 PlayerBurning = 52, //玩家灼烧 PetBurning = 53, //宠物灼烧 EnemyBurning = 54, //敌人灼烧 BuffAddDefense = 101,//+防御buff BuffAddAttack = 102,//+攻击buff BuffAddAttackSpeed = 103,//+攻速buff BuffAddAccurate = 104,//+命中buff BuffAddDodge = 105,//+闪避Buff BuffAddMaxHp = 106,//+血量上限buff BuffAddMoveSpeed = 107,//+移动速度buff BuffReduceDefense = 201,//-防御buff BuffReduceAttack = 202,//-攻击buff BuffReduceAttackSpeed = 203,//-攻速buff BuffReduceAccurate = 204,//-命中buff BuffReduceDodge = 205,//-闪避Buff BuffReduceMaxHp = 206,//-血量上限buff BuffReduceMoveSpeed = 207,//-移动速度buff } public enum AttackObject { Player, Pet, Enemy, } public struct PopupInfo { public Pattern pattern; public ulong num; public Camera camera; public Transform target; public Vector3 direction; public bool realmSuppress; public bool isPlayer; } } }