134 lines
4.9 KiB
C#
134 lines
4.9 KiB
C#
using System.Collections.Generic;
|
||
using TH1_Renderer.UnitAtomAnim;
|
||
using TH1Renderer;
|
||
using UnityEngine;
|
||
|
||
namespace TH1_Anim.UnitAtomAnim
|
||
{
|
||
public class UnitAtomAnimMove : IUnitAtomAnim
|
||
{
|
||
private UnitAtomAnimMoveData _data;
|
||
private Vector3 _originPos;
|
||
private Vector3 _targetPos;
|
||
|
||
public UnitAtomAnimMove(IUnitAtomAnimData data) : base()
|
||
{
|
||
_data = data as UnitAtomAnimMoveData;
|
||
State = UnitAtomAnimState.Prepare;
|
||
}
|
||
public override bool OnStart(UnitMono unitMono)
|
||
{
|
||
if (_data == null)
|
||
{
|
||
return false;
|
||
}
|
||
Duration = Table.Instance.AnimDataAssets.AttackAnimTime;
|
||
if(_data.Path != null)
|
||
Duration = Table.Instance.AnimDataAssets.AttackAnimTime / 2f * _data.Path.Count;
|
||
if (_data.DurationOverride > 0f)
|
||
Duration = _data.DurationOverride;
|
||
|
||
_originPos = Table.Instance.GridPosToWorld(_data.OriginGridPos, "isUnit");
|
||
_targetPos = Table.Instance.GridPosToWorld(_data.TargetGridPos, "isUnit");
|
||
|
||
UpdateDirection(unitMono,_data.OriginGridPos,_data.TargetGridPos);
|
||
return true;
|
||
}
|
||
|
||
public Vector3 GetPositionOnPath(List<Vector2Int> path2, float t)
|
||
{
|
||
if (path2 == null || path2.Count == 0) return Vector3.zero;
|
||
var path = new List<Vector3>();
|
||
foreach (var p in path2)
|
||
path.Add(Table.Instance.GridPosToWorld(p, "isUnit"));
|
||
// 边界情况
|
||
if (path.Count == 1) return path[0];
|
||
|
||
// 计算总路程
|
||
float totalLength = 0;
|
||
for (int i = 0; i < path.Count - 1; i++)
|
||
{
|
||
totalLength += Vector3.Distance(path[i], path[i+1]);
|
||
}
|
||
if (totalLength <= 0) return path[0];
|
||
// 确定目标移动距离
|
||
float targetDistance = totalLength * Mathf.Clamp01(t);
|
||
float distanceCovered = 0;
|
||
// 找到目标点所在的线段
|
||
for (int i = 0; i < path.Count - 1; i++)
|
||
{
|
||
float segmentLength = Vector2.Distance(path[i], path[i + 1]);
|
||
if (distanceCovered + segmentLength >= targetDistance)
|
||
{
|
||
// 在此线段内进行插值
|
||
float distanceIntoSegment = targetDistance - distanceCovered;
|
||
float segmentT = distanceIntoSegment / segmentLength;
|
||
return Vector2.Lerp(path[i], path[i + 1], segmentT);
|
||
}
|
||
distanceCovered += segmentLength;
|
||
}
|
||
// 如果 t >= 1,直接返回终点
|
||
return path[path.Count - 1];
|
||
}
|
||
|
||
|
||
public override void OnUpdate(UnitMono unitMono,float progressTime)
|
||
{
|
||
if (unitMono == null) return;
|
||
float t = Mathf.Clamp(progressTime / Duration,0f,1f);
|
||
//如果是直接移动过去
|
||
if(_data.Path == null)
|
||
unitMono.gameObject.transform.position = Vector3.Lerp(_originPos, _targetPos, t);
|
||
else
|
||
{
|
||
unitMono.gameObject.transform.position = GetPositionOnPath(_data.Path,t);
|
||
}
|
||
//Debug.Log($"{Time.time} / {progressTime} : {_originPos} -> {_targetPos} now @ {unitMono.gameObject.transform.position}");
|
||
}
|
||
|
||
}
|
||
|
||
public class UnitAtomAnimParabolaMove : IUnitAtomAnim
|
||
{
|
||
private UnitAtomAnimParabolaMoveData _data;
|
||
private Vector3 _originPos;
|
||
private Vector3 _targetPos;
|
||
private float _height;
|
||
|
||
public UnitAtomAnimParabolaMove(IUnitAtomAnimData data) : base()
|
||
{
|
||
_data = data as UnitAtomAnimParabolaMoveData;
|
||
State = UnitAtomAnimState.Prepare;
|
||
}
|
||
|
||
public override bool OnStart(UnitMono unitMono)
|
||
{
|
||
if (_data == null) return false;
|
||
Duration = _data.Duration > 0f ? _data.Duration : 1.1f;
|
||
_originPos = Table.Instance.GridPosToWorld(_data.OriginGridPos, "isUnit");
|
||
_targetPos = Table.Instance.GridPosToWorld(_data.TargetGridPos, "isUnit");
|
||
_height = Mathf.Max(0.1f, _data.Height);
|
||
UpdateDirection(unitMono, _data.OriginGridPos, _data.TargetGridPos);
|
||
return true;
|
||
}
|
||
|
||
public override void OnUpdate(UnitMono unitMono, float progressTime)
|
||
{
|
||
if (unitMono == null) return;
|
||
float t = Mathf.Clamp01(Duration <= 0f ? 1f : progressTime / Duration);
|
||
var pos = Vector3.Lerp(_originPos, _targetPos, t);
|
||
pos.y += 4f * _height * t * (1f - t);
|
||
unitMono.gameObject.transform.position = pos;
|
||
}
|
||
|
||
public override void OnFinished(UnitMono unitMono)
|
||
{
|
||
if (unitMono == null) return;
|
||
unitMono.gameObject.transform.position = _targetPos;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
}
|