如何在动画进度过半时等待其播放完毕再切换角色状态?
解决行走状态转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
相关产品推荐
相关产品推荐

