You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity Animator SetTrigger无法自动重置,如何实现动画单次播放?

嘿,先给你纠正一个关键的认知误区:Animator.SetTrigger() 本身并不会在动画播放完成后自动重置触发状态。触发标记一旦被设为true,就会一直保持这个状态——这就是你的Move动画持续循环的核心原因:状态机看到触发标记一直是true,就会反复从Default切换到Move状态。

下面给你几个不用手动检测时机就能实现“调用SetTrigger后动画仅播放一次”的可行方案,按推荐程度排序:

方案1:纯动画状态机配置(零额外代码,最推荐)

这是最省心的实现方式,完全在Unity的Animator窗口里完成配置:

  • 首先,确保你的Move状态取消勾选Loop Time(在动画剪辑的Inspector面板里,或者Animator窗口中选中Move状态后,右侧Inspector的Settings里)——这样动画本身只会播放一次。
  • 然后,在状态机中添加一条从Move到Default的过渡:
    • 这条过渡不需要设置任何条件(把Conditions列表清空)。
    • 勾选Has Exit Time,并把Exit Time设为1(表示动画播放到最后一帧时触发过渡)。
    • 把Transition Duration设为0或者你需要的过渡时长。
  • 原来的Default到Move的过渡保持不变,条件设为你的PlayingTrigger触发。

这样配置后,当你调用SetTrigger(Playing),状态会从Default切到Move,动画播放一次后,因为Exit Time满足,会自动切回Default,而且Animator会在触发过渡完成后自动消耗这个触发标记(也就是把它设为false),完美实现单次播放的需求。

方案2:用动画事件自动重置触发

如果你的状态机结构不适合方案1,或者需要在动画播放到特定节点时重置,可以用动画事件:

  1. 在Unity的Animation窗口中打开你的Move动画剪辑,在时间轴的最后一帧位置右键,选择Add Event
  2. 在你的TestAnimation脚本中添加一个方法:
public void OnMoveAnimationEnded() {
    _animation.ResetTrigger(Playing);
}
  1. 选中刚才添加的动画事件,在右侧Inspector的Function下拉框中选择OnMoveAnimationEnded

这样动画播放到最后一帧时,会自动调用这个方法重置触发标记,状态机就会自动切回Default(前提是Move到Default的过渡条件是触发标记为false,或者无条件)。

方案3:代码监听动画状态(适合需要额外逻辑的场景)

如果需要在动画结束时执行其他自定义逻辑,可以在代码中监听当前动画状态:
修改你的TestAnimation脚本,添加状态监听逻辑:

private AnimatorStateInfo _currentState;

void Update() {
    if (Input.GetKeyDown(KeyCode.A)) {
        _animation.SetTrigger(Playing);
        IDebug.Log("Playing animation ");
    }

    // 获取当前基础层的动画状态
    _currentState = _animation.GetCurrentAnimatorStateInfo(0);
    // 判断是否处于Move状态,且动画已经播放完成(normalizedTime >=1),同时动画不循环
    if (_currentState.IsName("Move") && _currentState.normalizedTime >= 1f && !_currentState.loop) {
        _animation.ResetTrigger(Playing);
        IDebug.Log("Animation finished, trigger reset");
    }
}

这里要注意,必须确保Move状态的Loop Time是关闭的,否则normalizedTime会一直循环增长,无法判断结束时机。


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

火山引擎 最新活动