Unity中如何在动画播放结束后执行Player GameObject的Transform变换
Unity检测Pre Teleport动画结束触发传送的三种实现方案
方法1:动画事件(首选方案)
这是性能最优、逻辑最直观的实现方式,直接在动画剪辑的时间轴上绑定触发逻辑:
- 打开Animation窗口,选中你的
Pre Teleport动画剪辑,将时间轴滑块拖到动画最后一帧的位置 - 点击时间轴左上角的「添加事件」按钮,在弹出的事件配置面板中,选择要绑定的目标方法
- 玩家对象挂载的传送参考代码如下:
using UnityEngine; public class PlayerTeleport : MonoBehaviour { [SerializeField] private Animator playerAnimator; [SerializeField] private Transform teleportTarget; // 提前配置好的传送目标位置 // 点击传送触发对象时调用该方法启动流程 public void TriggerTeleportProcess() { playerAnimator.SetTrigger("PreTeleport"); } // 给Pre Teleport动画结束事件绑定的方法 private void ExecuteTeleport() { // 执行玩家位移 transform.position = teleportTarget.position; // 触发传送后动画 playerAnimator.SetTrigger("PostTeleport"); } }
动画播放到最后一帧时会自动调用ExecuteTeleport方法,完美匹配你的流程需求。
方法2:Animator状态机行为检测
适合需要把动画状态逻辑和业务逻辑分离的场景:
- 打开Animator窗口,选中
Pre Teleport对应的动画状态 - 在Inspector面板点击「Add Behaviour」,新建状态机行为脚本,重写
OnStateExit方法即可,参考代码:
using UnityEngine; public class PreTeleportState : StateMachineBehaviour { // Pre Teleport状态退出时(即动画播放完成)自动调用 override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { PlayerTeleport teleportComp = animator.GetComponent<PlayerTeleport>(); if(teleportComp != null) { teleportComp.ExecuteTeleport(); } } }
方法3:帧更新轮询检测
适合临时测试、不想修改动画资源的场景,性能略低于前两种方案:
只需要在玩家传送脚本中加入帧检测逻辑即可,参考代码:
using UnityEngine; public class PlayerTeleport : MonoBehaviour { [SerializeField] private Animator playerAnimator; [SerializeField] private Transform teleportTarget; private bool isCheckingPreTeleportEnd = false; private void Update() { if (isCheckingPreTeleportEnd) { AnimatorStateInfo currentState = playerAnimator.GetCurrentAnimatorStateInfo(0); // normalizedTime大于等于1代表动画播放完成 if (currentState.IsName("PreTeleport") && currentState.normalizedTime >= 1f) { isCheckingPreTeleportEnd = false; ExecuteTeleport(); } } } public void TriggerTeleportProcess() { playerAnimator.SetTrigger("PreTeleport"); isCheckingPreTeleportEnd = true; } private void ExecuteTeleport() { transform.position = teleportTarget.position; playerAnimator.SetTrigger("PostTeleport"); } }
注意:代码中的
PreTeleport需要和你Animator中对应的状态名完全一致。
内容的提问来源于stack exchange,提问作者Sadeem Sajid
相关产品推荐
相关产品推荐

