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

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:动画事件(更稳定的推荐方案)

不需要写进度判定逻辑,直接在动画时间轴上绑定回调:

  1. 打开Animator窗口选中你的Destroy死亡动画剪辑
  2. 在动画时间轴的最后一帧位置添加动画事件
  3. 把事件的回调方法绑定到敌人对象上的自定义禁用方法,示例代码如下:
// 给动画事件调用的方法
public void OnDeathAnimEnd()
{
    gameObject.SetActive(false);
}

触发受击时直接调用anim.Play("Destroy", 0, 0f)即可,动画播到最后一帧会自动执行禁用逻辑。

内容的提问来源于stack exchange,提问作者adas princ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 18:54:07