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

Unity玩家动画未按编程逻辑在Idle与Walk间异常切换问题

问题现象
  • 按住D键控制玩家移动时,Walk动画无法持续播放,在Idle与Walk状态间反复切换
  • 单独预览Idle、Walk单个动画片段无异常
  • 状态过渡会从Idle状态启动后才切换至Walk状态,新建项目重写整套逻辑问题仍复现
原实现代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    [SerializeField]
    float moveForce = 10f;

    [SerializeField]
    float jumpForce = 11f;

    float movementX;

    Rigidbody2D myBody;

    Animator Anim;

    private SpriteRenderer sr;

    string WALK_ANIMATION = "Walk";

    private void Update()
    {
        playerMoveKeyboard();
        animatePlayer();
    }

    private void Awake()
    {
        myBody = GetComponent<Rigidbody2D>();
        Anim = myBody.GetComponent<Animator>();
        sr = GetComponent<SpriteRenderer>();
    }
    void playerMoveKeyboard()
    {
        movementX = Input.GetAxisRaw("Horizontal");
        transform.position += new Vector3(movementX, 0f, 0f) * moveForce * Time.deltaTime;
    }
    void animatePlayer()
    {
        if(movementX > 0)
        {
            Anim.SetBool(WALK_ANIMATION, true);
            sr.flipX = false;
        }
        else if (movementX < 0)
        {
            Anim.SetBool(WALK_ANIMATION, true);
            sr.flipX = true;
        }
        else
        {
            Anim.SetBool(WALK_ANIMATION, false);
        }
    }
}
问题根因

动画异常跳变由两个问题共同导致:

  • Animator状态机过渡配置错误:Idle与Walk的双向过渡勾选了Has Exit Time(存在退出时间)。当Walk动画播放到设定的退出时间节点时会自动触发状态校验,即使Walk布尔参数持续为true,也会短暂切回Idle状态;切回Idle后检测到Walk参数仍为true,又会再次切回Walk,最终形成反复切换的抖动效果。
  • 代码组件获取逻辑存在隐患:原代码通过Rigidbody2D组件调用GetComponent<Animator>()获取动画组件,虽然组件都挂在同一物体上时能正常运行,但后续如果调整对象层级结构(比如将动画、渲染组件移到子节点),会直接出现空引用报错。
修复方案

1. 修正Animator状态机配置

  • 打开Animator窗口,分别选中Idle→Walk、Walk→Idle两个过渡箭头
  • 在Inspector面板取消勾选Has Exit Time
  • 将*Transition Duration(s)(过渡时长)*调整为0~0.1之间的数值,避免动画硬切过于突兀
  • 确认过渡条件配置无多余项:
    • Idle→Walk过渡:仅保留条件为Walk参数等于true
    • Walk→Idle过渡:仅保留条件为Walk参数等于false
  • 分别选中Idle、Walk两个动画片段,在Inspector面板确认勾选Loop Time(循环时间),保证动画可正常循环播放

2. 修正代码逻辑

优化组件获取方式,简化动画判断逻辑,修复后完整代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    [SerializeField]
    float moveForce = 10f;

    [SerializeField]
    float jumpForce = 11f;

    float movementX;

    Rigidbody2D myBody;
    Animator anim;
    SpriteRenderer sr;

    const string WALK_ANIMATION = "Walk";

    private void Awake()
    {
        myBody = GetComponent<Rigidbody2D>();
        // 直接获取当前物体上的Animator组件,避免通过其他组件中转查找带来的引用异常
        anim = GetComponent<Animator>();
        sr = GetComponent<SpriteRenderer>();
    }

    private void Update()
    {
        PlayerMoveKeyboard();
        AnimatePlayer();
    }

    void PlayerMoveKeyboard()
    {
        movementX = Input.GetAxisRaw("Horizontal");
        transform.position += new Vector3(movementX, 0f, 0f) * moveForce * Time.deltaTime;
    }

    void AnimatePlayer()
    {
        bool isWalking = movementX != 0;
        anim.SetBool(WALK_ANIMATION, isWalking);
        // 仅在有移动输入时调整角色朝向,避免静止状态下不必要的翻转
        if (movementX != 0)
        {
            sr.flipX = movementX < 0;
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:01:14