Files
Gen_Hack-and-Slash-Roguelite/Client/Assets/Scripts/Prefab/TemporaryAnimator.cs

79 lines
3.0 KiB
C#
Raw Normal View History

using System;
using Base;
using UnityEngine;
namespace Prefab
{
public class TemporaryAnimator : MonoBehaviour, ITick
{
[Tooltip("动画持续时间。当小于或等于0时动画将无限持续物体不会自动销毁。")]
public float lifeTime = 3;
private float _timer; // 每次启用时会重置为0
// 使用属性限制外部只能获取和一次性设置动画函数
[Tooltip("定义X轴偏移的函数 (时间 -> X偏移量)")]
public Func<float, float> GetXPosition { get; private set; }
[Tooltip("定义Y轴偏移的函数 (时间 -> Y偏移量)")]
public Func<float, float> GetYPosition { get; private set; }
private Vector3 _originalPosition;
private void Start()
{
_originalPosition = transform.localPosition; // 初始位置只需在组件生命周期中获取一次
}
private void OnEnable()
{
_timer = 0; // 每次启用时重置计时器,确保动画从头开始
Clock.AddTick(this); // 在启用时注册到全局Tick系统
}
private void OnDisable()
{
// 在禁用或销毁时从全局Tick系统取消注册避免不必要的调用和资源泄露
Clock.RemoveTick(this);
}
public virtual void Tick()
{
_timer += Time.deltaTime;
// 如果lifeTime > 0则钳制动画时间否则无限持续直接使用_timer
var currentAnimationTime = lifeTime > 0 ? Mathf.Min(_timer, lifeTime) : _timer;
// 调用委托获取X和Y轴的偏移量如果委托未设置则使用当前位置的对应轴值
// 有委托时:原始位置 + 偏移量;无委托时:当前位置的对应轴值
var xPos = GetXPosition != null
? _originalPosition.x + GetXPosition.Invoke(currentAnimationTime)
: transform.localPosition.x;
var yPos = GetYPosition != null
? _originalPosition.y + GetYPosition.Invoke(currentAnimationTime)
: transform.localPosition.y;
// 应用计算后的值到物体位置保持原始Z轴不变
transform.localPosition = new Vector3(xPos, yPos, _originalPosition.z);
// 只有当lifeTime > 0时才判断是否需要销毁
if (lifeTime > 0 && _timer >= lifeTime)
{
Destroy(this.gameObject);
}
}
/// <summary>
/// 设置动画的X和Y轴位移函数。
/// 此方法通常在实例化TemporaryAnimator后立即调用以配置其动画行为。
/// </summary>
/// <param name="getXPosFunc">时间到X轴位移的函数。</param>
/// <param name="getYPosFunc">时间到Y轴位移的函数。</param>
public void SetAnimationFunctions(Func<float, float> getXPosFunc, Func<float, float> getYPosFunc)
{
GetXPosition = getXPosFunc;
GetYPosition = getYPosFunc;
}
}
}