using System; using Base; using UnityEngine; namespace Prefab { public class TemporaryAnimator : MonoBehaviour, ITick { [Tooltip("动画持续时间。当小于或等于0时,动画将无限持续,物体不会自动销毁。")] public float lifeTime = 3; private Vector3 _originalPosition; private float _timer; // 每次启用时会重置为0 // 使用属性限制外部只能获取和一次性设置动画函数 [Tooltip("定义X轴偏移的函数 (时间 -> X偏移量)")] public Func GetXPosition { get; private set; } [Tooltip("定义Y轴偏移的函数 (时间 -> Y偏移量)")] public Func GetYPosition { get; private set; } 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(gameObject); } /// /// 设置动画的X和Y轴位移函数。 /// 此方法通常在实例化TemporaryAnimator后立即调用以配置其动画行为。 /// /// 时间到X轴位移的函数。 /// 时间到Y轴位移的函数。 public void SetAnimationFunctions(Func getXPosFunc, Func getYPosFunc) { GetXPosition = getXPosFunc; GetYPosition = getYPosFunc; } } }