You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何从Event Trigger调用依赖帧的UI动画函数?

实现依赖帧的UI动画(无需持续调用Update)

方案1:使用Unity协程(Coroutine)

协程是Unity原生的逐帧逻辑处理方案,只有动画执行期间才会逐帧运行逻辑,结束后自动销毁,完全不需要在Update里轮询布尔值。

代码示例:

using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;

public class UIAnimationHandler : MonoBehaviour, IPointerClickHandler
{
    public RectTransform targetUI;
    public float animationDuration = 1.5f;
    private Vector3 targetPos;

    // Event Trigger触发的点击事件
    public void OnPointerClick(PointerEventData eventData)
    {
        targetPos = new Vector3(300, 100, 0); // 设置动画目标位置
        StartCoroutine(AnimateUIMove());
    }

    private IEnumerator AnimateUIMove()
    {
        float elapsedTime = 0f;
        Vector3 startPos = targetUI.localPosition;

        // 逐帧更新直到动画完成
        while (elapsedTime < animationDuration)
        {
            targetUI.localPosition = Vector3.Lerp(startPos, targetPos, elapsedTime / animationDuration);
            elapsedTime += Time.deltaTime;
            yield return null; // 等待下一帧
        }

        // 确保UI最终停在准确的目标位置
        targetUI.localPosition = targetPos;
    }
}

优势:逻辑简洁,无需额外管理,动画结束后自动停止帧更新,性能开销极低。


方案2:使用Unity动画系统(Animator)

如果是包含移动、缩放、淡入淡出的复杂UI动画,直接用Animator可视化编辑动画片段,Event Trigger触发时播放即可,完全不需要手写逐帧逻辑。

代码示例:

using UnityEngine;
using UnityEngine.EventSystems;

public class UIAnimationHandler : MonoBehaviour, IPointerClickHandler
{
    public Animator uiAnimator;

    public void OnPointerClick(PointerEventData eventData)
    {
        // 播放指定名称的动画片段
        uiAnimator.Play("UI_SlideInAnimation");
    }
}

操作步骤:

  • 给UI元素添加Animator组件
  • 创建动画控制器(Animator Controller),用Animation Window编辑移动、缩放等关键帧动画片段
  • 可在动画片段中添加动画事件(Animation Event),用于在动画结束时执行自定义回调逻辑

优势:可视化编辑直观高效,Unity自动优化动画更新效率,无需手写逐帧代码。


方案3:自定义帧更新管理器(集中式回调)

如果需要统一管理多个UI动画,可以做一个全局的帧更新管理器,只有活跃的动画才会注册到管理器的帧回调中,动画结束后注销,避免无意义的Update调用。

代码示例:

全局帧更新管理器

using UnityEngine;
using System.Collections.Generic;

public class FrameUpdateManager : MonoBehaviour
{
    private static List<System.Action> activeAnimationCallbacks = new List<System.Action>();

    private void Update()
    {
        // 倒序遍历,避免移除元素时索引出错
        for (int i = activeAnimationCallbacks.Count - 1; i >= 0; i--)
        {
            activeAnimationCallbacks[i]();
        }
    }

    // 注册帧回调
    public static void RegisterAnimationCallback(System.Action callback)
    {
        if (!activeAnimationCallbacks.Contains(callback))
        {
            activeAnimationCallbacks.Add(callback);
        }
    }

    // 注销帧回调
    public static void UnregisterAnimationCallback(System.Action callback)
    {
        if (activeAnimationCallbacks.Contains(callback))
        {
            activeAnimationCallbacks.Remove(callback);
        }
    }
}

UI动画处理类

using UnityEngine;
using UnityEngine.EventSystems;

public class UIAnimationHandler : MonoBehaviour, IPointerClickHandler
{
    public RectTransform targetUI;
    public float animationDuration = 1f;
    private Vector3 startPos;
    private Vector3 targetPos;
    private float elapsedTime;
    private System.Action animationCallback;

    private void Awake()
    {
        // 初始化动画帧回调逻辑
        animationCallback = UpdateAnimation;
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        elapsedTime = 0f;
        startPos = targetUI.localPosition;
        targetPos = new Vector3(-200, 0, 0);
        // 注册回调到管理器
        FrameUpdateManager.RegisterAnimationCallback(animationCallback);
    }

    private void UpdateAnimation()
    {
        elapsedTime += Time.deltaTime;
        if (elapsedTime >= animationDuration)
        {
            targetUI.localPosition = targetPos;
            // 动画完成,注销回调
            FrameUpdateManager.UnregisterAnimationCallback(animationCallback);
            return;
        }
        targetUI.localPosition = Vector3.Lerp(startPos, targetPos, elapsedTime / animationDuration);
    }
}

优势:集中管理所有动画的帧更新,只有需要执行的动画才会占用帧资源,适合多动画场景的性能优化。


总结

  • 优先用协程:适合需要自定义逻辑的简单动画,实现成本低
  • 优先用Animator:适合复杂的组合动画,可视化编辑更高效
  • 自定义帧管理器:适合需要统一管控多个动画的大型项目

内容的提问来源于stack exchange,提问作者Priyansh Yadav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:50:26