Unity如何在动画播放结束后执行指定操作?现有方案报错如何解决?
问题原因与解决方案
错误原因说明
- 关于CS0021报错:你查到的
anim["Destroy"].normalizedTime = 0f是Unity早年已废弃的JavaScript语法风格API,新版C#版Animator不支持索引器直接访问动画状态,所以会抛出「无法将[]索引应用于Animator类型的表达式」的CS0021错误。 - 关于判断条件失效:你调用
anim.Play()后直接读取当前层级的动画状态,此时Animator还没完成状态切换,你拿到的仍然是之前一直在运行的旧动画的状态信息,所以获取到的normalizedTime是旧动画累计的15+数值,模1后的判断逻辑自然不符合预期,导致对象被立即禁用。
正确实现方案
方案1:协程判定(适配原有写法的修正版)
核心逻辑是先等待Animator切换到目标死亡动画状态,再判定播放进度:
// 先缓存死亡动画的名称哈希,避免每帧字符串比对消耗 private readonly int destroyAnimHash = Animator.StringToHash("Destroy"); IEnumerator PlayDeathAndDisable() { // 播放死亡动画,第三个参数强制从0帧开始播放 anim.Play(destroyAnimHash, 0, 0f); // 先等待状态切换到死亡动画 while (!anim.GetCurrentAnimatorStateInfo(0).shortNameHash.Equals(destroyAnimHash)) { yield return null; } // 再等待死亡动画播放完成 AnimatorStateInfo stateInfo; do { stateInfo = anim.GetCurrentAnimatorStateInfo(0); yield return null; } while (stateInfo.normalizedTime < 1f); // 执行禁用 gameObject.SetActive(false); }
注意:需要把死亡动画的「循环」选项关闭,否则动画会循环播放,normalizedTime会一直累加永远无法触发停止条件。如果你的死亡动画后配置了过渡效果,可根据需求调整为等待过渡完成后再禁用。
方案2:动画事件(更稳定的推荐方案)
不需要写进度判定逻辑,直接在动画时间轴上绑定回调:
- 打开Animator窗口选中你的
Destroy死亡动画剪辑 - 在动画时间轴的最后一帧位置添加动画事件
- 把事件的回调方法绑定到敌人对象上的自定义禁用方法,示例代码如下:
// 给动画事件调用的方法 public void OnDeathAnimEnd() { gameObject.SetActive(false); }
触发受击时直接调用anim.Play("Destroy", 0, 0f)即可,动画播到最后一帧会自动执行禁用逻辑。
内容的提问来源于stack exchange,提问作者adas princ
相关产品推荐
相关产品推荐

