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

如何在动画进度过半时等待其播放完毕再切换角色状态?

解决行走状态转Idle的动画过渡问题

核心思路

在行走状态的状态切换逻辑中加入动画进度判断:

  • 当角色满足切换Idle的条件时,先检查当前行走动画的播放进度
  • 进度不足50%:直接切换到Idle状态
  • 进度超过50%:标记等待状态,每帧检查动画是否播放完毕,待动画结束后再执行状态切换

修改后的代码实现

// 新增私有变量,标记是否在等待行走动画结束
private bool _isWaitingForAnimEnd;

// 每帧调用的状态切换检查
public override void ChangeState()
{
    if (_groundCheck.Check())
    {
        // 优先处理跳跃状态,不受动画等待逻辑影响
        if (_jump) 
        {
            controller.SetState(typeof(JumpState));
            return;
        }

        // 满足切换Idle的条件
        if (_rb.velocity.x == 0 && _xDirection == 0)
        {
            AnimatorStateInfo stateInfo = _animator.GetCurrentAnimatorStateInfo(0);
            // 检查当前是否处于行走动画状态(需和你Animator Controller里的状态名对应)
            if (stateInfo.IsName("Walk"))
            {
                float normalizedProgress = stateInfo.normalizedTime % 1;
                if (normalizedProgress <= 0.5f)
                {
                    // 进度不足50%,直接切换Idle
                    controller.SetState(typeof(IdleState));
                }
                else
                {
                    // 进度超过50%,标记等待动画结束
                    _isWaitingForAnimEnd = true;
                }
            }
            else
            {
                // 当前不是行走动画,直接切换Idle
                controller.SetState(typeof(IdleState));
            }
        }
        else
        {
            // 角色仍在移动,取消等待标记
            _isWaitingForAnimEnd = false;
        }
    }
}

public override void Update()
{
    _animator.MovingAnimation(_groundCheck.Check());
    _animator.CorrectRotation(_xDirection);

    // 若处于等待动画结束状态,每帧检查动画是否播放完成
    if (_isWaitingForAnimEnd)
    {
        AnimatorStateInfo stateInfo = _animator.GetCurrentAnimatorStateInfo(0);
        // normalizedTime >=1 表示当前动画已播放完至少一轮
        if (stateInfo.normalizedTime >= 1f)
        {
            // 动画播放完毕,切换Idle并重置等待标记
            controller.SetState(typeof(IdleState));
            _isWaitingForAnimEnd = false;
        }
    }
}

public override void Exit()
{
    // 退出状态时重置等待标记,避免残留状态影响下次进入
    _isWaitingForAnimEnd = false;
    controller.Animator.MovingAnimation(false);
}

关键细节说明

  • 确保stateInfo.IsName("Walk")中的动画状态名和你Animator Controller里的行走状态名称完全一致
  • normalizedTime % 1用于获取循环动画的当前单轮进度,排除多轮循环的干扰
  • 跳跃状态优先处理,避免等待动画时无法响应跳跃输入
  • 退出状态时重置_isWaitingForAnimEnd,防止状态切换后残留标记导致逻辑异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:45:41