2026-06-26 16:36:01 +08:00

134 lines
4.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}