using System.Collections.Generic; using TH1_Renderer.UnitAtomAnim; using TH1Renderer; using UnityEngine; namespace TH1_Anim.UnitAtomAnim { public enum UnitAtomAnimState { Prepare, Playing, Finished, Wrong } public enum UnitAtomAnimType { None, Bounce, Move, AttackMove, AttackMoveBack, KillMove, Projectile } public static class UnitAtomAnimFactory { public static IUnitAtomAnim Create(UnitAtomAnimType type,IUnitAtomAnimData unitAtomAnimData) { return type switch { UnitAtomAnimType.Move => new UnitAtomAnimMove(unitAtomAnimData) { }, UnitAtomAnimType.Bounce =>new UnitAtomAnimBounce(unitAtomAnimData) { }, UnitAtomAnimType.AttackMove => new UnitAtomAnimAttackMove(unitAtomAnimData) { }, UnitAtomAnimType.AttackMoveBack => new UnitAtomAnimAttackMoveBack(unitAtomAnimData){}, UnitAtomAnimType.Projectile => new UnitAtomAnimProjectile(unitAtomAnimData){}, _ => null }; } } public abstract class IUnitAtomAnim { public UnitAtomAnimType Type; public UnitAtomAnimState State; public float StartTime; public float Duration; public IUnitAtomAnim() { } public virtual void InitData(){} public virtual bool OnStart(UnitMono unitMono) { return true;} public virtual void OnFinished(UnitMono unitMono) { } public virtual void OnUpdate(UnitMono unitMono,float progressTime) { } public virtual void UpdateDirection(UnitMono unitMono, Vector2Int originGridPos,Vector2Int targetGridPos) { // 计算移动方向并设置朝向 int dx = originGridPos.x - targetGridPos.x; int dy = originGridPos.y - targetGridPos.y; // 如果向左上方移动(y1-y2 > x1-x2),翻转朝向 if (dy > dx) { var v3 = unitMono.SpriteRenderer.transform.localScale; v3.x = Mathf.Abs(v3.x); unitMono.SpriteRenderer.transform.localScale = v3; } // 如果向右上方移动(y1-y2 < x1-x2),保持默认朝向 else if(dy < dx) { var v3 = unitMono.SpriteRenderer.transform.localScale; v3.x = -Mathf.Abs(v3.x); unitMono.SpriteRenderer.transform.localScale = v3; } } } public class UnitAtomAnimBounce : IUnitAtomAnim { private UnitAtomAnimBounceData _data; private Vector3 _bounceUpPos; private Vector3 _bounceDownPos; public UnitAtomAnimBounce(IUnitAtomAnimData data) : base() { _data = data as UnitAtomAnimBounceData; } public override bool OnStart(UnitMono unitMono) { if (_data == null)return false; Duration = Table.Instance.AnimDataAssets.BounceDownTime + Table.Instance.AnimDataAssets.BounceUpTime; _bounceUpPos = unitMono.gameObject.transform.position; _bounceDownPos = new Vector3(unitMono.gameObject.transform.position.x, unitMono.gameObject.transform.position.y - 0.8f, unitMono.gameObject.transform.position.z); return true; } public override void OnUpdate(UnitMono unitMono, float progressTime) { if (progressTime <= Table.Instance.AnimDataAssets.BounceDownTime) { float t = progressTime / Table.Instance.AnimDataAssets.BounceDownTime; unitMono.gameObject.transform.position = Vector3.Lerp(_bounceUpPos, _bounceDownPos, t); return; } if (progressTime > Table.Instance.AnimDataAssets.BounceDownTime) { float t = (progressTime - Table.Instance.AnimDataAssets.BounceDownTime) / Table.Instance.AnimDataAssets.BounceUpTime; unitMono.gameObject.transform.position = Vector3.Lerp(_bounceDownPos, _bounceUpPos, t); return; } } } public class UnitAtomAnimProjectile : IUnitAtomAnim { private UnitAtomAnimProjectileData _data; private Vector3 _originPos; private Vector3 _targetPos; public UnitAtomAnimProjectile(IUnitAtomAnimData data) : base() { _data = data as UnitAtomAnimProjectileData; State = UnitAtomAnimState.Prepare; } public override bool OnStart(UnitMono unitMono) { if (_data == null) return false; Duration = Table.Instance.AnimDataAssets.AttackAnimTime; if (Table.Instance.ProjectileTypeDataAssets.GetProjectileTypeInfo(_data.ProjectileType, out var info)) Duration = info.AnimTime; _originPos = Table.Instance.GridPosToWorld(_data.OriginGridPos, "isUnit"); _targetPos = Table.Instance.GridPosToWorld(_data.TargetGridPos, "isUnit"); MapRenderer.Instance.ProjectileManager.CreateProjectile(_originPos,_targetPos,_data.ProjectileType); UpdateDirection(unitMono,_data.OriginGridPos,_data.TargetGridPos); return true; } public override void OnUpdate(UnitMono unitMono,float progressTime) { //if (unitMono == null) return; //float t = Mathf.Clamp(progressTime / Duration,0f,1f); //unitMono.gameObject.transform.position = Vector3.Lerp(_originPos, _targetPos, t); //Debug.Log($"{Time.time} / {progressTime} : {_originPos} -> {_targetPos} now @ {unitMono.gameObject.transform.position}"); } } }