/* * @Author: 白哉 * @Description: * @Date: 2025年07月01日 星期二 14:07:05 * @Modify: */ using RuntimeData; using TH1_Anim.UnitAtomAnim; using TH1_DataAssetsScript; using TH1_Logic.Core; using TH1_Renderer.UnitAtomAnim; using TH1Renderer; using UnityEngine; namespace TH1_Anim.Fragments { public class FragmentAttackAndCounter : FragmentBase { public FragmentAttackAndCounterData Data; private ProjectileTypeInfo _attackInfo; private ProjectileTypeInfo _counterInfo; private bool _step1_attack; private bool _step2_attackmoveback; private bool _step3_wait; private bool _step4_counter; private bool _step5_countermoveback; private bool _step6_updateunit; private float _step1_start; private float _step2_start; private float _step3_start; private float _step4_start; private float _step5_start; private float _step6_start; public FragmentAttackAndCounter(FragmentAttackAndCounterData data) : base() { Data = data; var animTable = Table.Instance.AnimDataAssets; if (!Table.Instance.ProjectileTypeDataAssets.GetProjectileTypeInfo(Data.AttackType, out _attackInfo)) { State = FragmentState.Wrong; return; } if (!Table.Instance.ProjectileTypeDataAssets.GetProjectileTypeInfo(Data.CounterType, out _counterInfo)) { State = FragmentState.Wrong; return; } _step1_start = 0; _step2_start = _step1_start + _attackInfo.AnimTime; _step3_start = _step2_start + (_attackInfo.ProjectileType == ProjectileType.Melee ? animTable.AttackReturnAnimTime : 0); _step4_start = _step3_start + animTable.BetweenAttackCounterAnimTime; _step5_start = _step4_start + _counterInfo.AnimTime; _step6_start = _step5_start + (_counterInfo.ProjectileType == ProjectileType.Melee ? animTable.CounterReturnAnimTime : 0); Duration = _step6_start; } public override bool CheckDone(float progressTime) { //超时保险 if (progressTime > Duration * 2) { Debug.Log($"Fragement Timeout {this.GetType()}"); return true; } if (!_step1_attack || !_step2_attackmoveback || !_step3_wait || !_step4_counter || !_step5_countermoveback || !_step6_updateunit) return false; if (progressTime <= Duration) return false; return true; } public override void OnUpdate(float progressTime) { //Step #1执行第一步 -> 攻击 if (progressTime >= _step1_start && !_step1_attack) { _step1_attack = true; //近战攻击 if (_attackInfo.ProjectileType == ProjectileType.Melee) { var animData = UnitAtomAnimDataFactory.Create(UnitAtomAnimType.AttackMove,Data.OriginGrid.Pos.V2(), Data.TargetGrid.Pos.V2()); Data.OriginUnitRenderer.AnimManager.EnqueueAnim(UnitAtomAnimType.AttackMove,animData); } else //远战攻击 { var animData = UnitAtomAnimDataFactory.CreateUnitAtomAnimProjectile(UnitAtomAnimType.Projectile,_attackInfo.ProjectileType,Data.OriginGrid.Pos.V2(), Data.TargetGrid.Pos.V2()); Data.OriginUnitRenderer.AnimManager.EnqueueAnim(UnitAtomAnimType.Projectile,animData); } return; } //Step #2执行第二步 -> 受伤 + 返回(如有) if (progressTime >= _step2_start && !_step2_attackmoveback) { _step2_attackmoveback = true; //更新受伤数据 Data.TargetUnitRenderer.InstantUpdateUnit(false); //播放弹动效果 Data.TargetUnitRenderer.AnimManager.EnqueueAnim(UnitAtomAnimType.Bounce,UnitAtomAnimDataFactory.Create(UnitAtomAnimType.Bounce)); //播放特效 Data.TargetGrid.Renderer(Main.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Hurt)); Data.TargetGrid.Renderer(Main.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Damage,Data.AttackDmg)); //如果是近战,做一个返回动画 if (_attackInfo.ProjectileType == ProjectileType.Melee) { var animData = UnitAtomAnimDataFactory.Create(UnitAtomAnimType.AttackMoveBack, Data.OriginGrid.Pos.V2(),Data.TargetGrid.Pos.V2()); Data.OriginUnitRenderer.AnimManager.EnqueueAnim(UnitAtomAnimType.AttackMoveBack,animData); } return; } //Step #3执行第二步 -> 等待 if (progressTime >= _step3_start && !_step3_wait) { _step3_wait = true; return; } //Step #4执行第二步 -> 反击 if (progressTime >= _step4_start && !_step4_counter) { _step4_counter = true; //处理近战 if (_counterInfo.ProjectileType == ProjectileType.Melee) { var animData = UnitAtomAnimDataFactory.Create(UnitAtomAnimType.AttackMove, Data.TargetGrid.Pos.V2(),Data.OriginGrid.Pos.V2()); Data.TargetUnitRenderer.AnimManager.EnqueueAnim(UnitAtomAnimType.AttackMove,animData); } else //处理远战 { var animData = UnitAtomAnimDataFactory.CreateUnitAtomAnimProjectile(UnitAtomAnimType.Projectile,_counterInfo.ProjectileType,Data.TargetGrid.Pos.V2(), Data.OriginGrid.Pos.V2()); Data.TargetUnitRenderer.AnimManager.EnqueueAnim(UnitAtomAnimType.Projectile,animData); } return; } //Step #5执行第二步 -> 受伤 + 反击返回(如有) if (progressTime >= _step5_start && !_step5_countermoveback) { _step5_countermoveback = true; //更新受伤 or 死亡 if (Data.Type == FragmentType.AttackAndCounterDie) { Data.OriginUnitRenderer.Die(); Data.OriginGrid.Renderer(Main.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Fog)); //重置周围单位的高亮状态 MapRenderer.Instance.UpdateAroundHighlight(Main.MapData,Data.OriginGrid); //更新死亡一方所属的城市的城市状态 Data.OriginCity.SetCityRenderer(Main.MapData); } else { Data.OriginUnitRenderer.InstantUpdateUnit(false); //播放弹动效果 Data.OriginUnitRenderer.AnimManager.EnqueueAnim(UnitAtomAnimType.Bounce,UnitAtomAnimDataFactory.Create(UnitAtomAnimType.Bounce)); } //播放特效 Data.OriginGrid.Renderer(Main.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Hurt)); Data.OriginGrid.Renderer(Main.MapData)?.PlayVFX(new GridVFXParams(GridVFXType.Damage,Data.CounterDmg)); if (_counterInfo.ProjectileType == ProjectileType.Melee) { var animData = UnitAtomAnimDataFactory.Create(UnitAtomAnimType.AttackMoveBack, Data.TargetGrid.Pos.V2(),Data.OriginGrid.Pos.V2()); Data.TargetUnitRenderer.AnimManager.EnqueueAnim(UnitAtomAnimType.AttackMoveBack,animData); } return; } //Step #6 全部结束,更新unitRender的状态(处理隐藏在视野外这种情况) if (progressTime >= _step6_start && !_step6_updateunit) { _step6_updateunit = true; //注意,这里origin有可能死亡 Data.OriginUnitRenderer.InstantUpdateUnit(true); Data.TargetUnitRenderer.InstantUpdateUnit(true); Data.OriginGrid.Renderer(Main.MapData)?.InstantUpdateGrid(); Data.TargetGrid.Renderer(Main.MapData)?.InstantUpdateGrid(); } } } }