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

Unity添加动画代码后角色无法移动的问题排查与解决求助

解决Unity 2D角色添加动画控制后无法移动的问题

你的核心问题是每帧重复启动大量协程,导致多个协程同时执行移动逻辑互相干扰,最终让角色无法正常移动。问题和动画控制本身无关,协程的启动逻辑才是bug根源。

问题分析

在Update方法里,只要检测到方向键输入就会启动新的MoveCoroutine协程。按住方向键时,每帧都会创建新协程,短时间内会有几十个甚至上百个协程同时运行,它们都在修改角色位置和动画参数,直接打乱了执行流程,导致移动失效。

修复方案

方案1:用标记变量避免重复启动协程

添加布尔变量标记协程运行状态,确保同一时间只有一个协程执行:

using System.Collections;
using UnityEngine;

public class PlayerManager : MonoBehaviour
{
    public float speed;
    public float runSpeed;
    
    private Vector3 vector;
    private float applyRunSpeed;
    private Animator anim;
    private bool isMovingCoroutineRunning; // 新增标记变量

    private void Start()
    {
        anim = GetComponent<Animator>();
    }

    IEnumerator MoveCoroutine()
    {
        isMovingCoroutineRunning = true;
        
        while (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)
        {
            // 处理加速逻辑
            applyRunSpeed = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift) ? runSpeed : 0;

            // 获取输入方向
            vector.Set(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"), transform.position.z);

            // 更新动画参数
            anim.SetFloat("DirX", vector.x);
            anim.SetFloat("DirY", vector.y);
            anim.SetBool("Idle", false);

            // 移动角色(归一化方向避免斜向速度过快)
            if (vector.x != 0 || vector.y != 0)
            {
                transform.Translate(vector.normalized * (speed + applyRunSpeed) * Time.deltaTime);
            }
            
            yield return null;
        }

        // 停止移动时设置Idle动画
        anim.SetBool("Idle", true);
        isMovingCoroutineRunning = false;
    }

    private void Update()
    {
        if ((Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0) && !isMovingCoroutineRunning)
        {
            StartCoroutine(MoveCoroutine());
        }
    }
}

方案2:直接在Update中处理(更简洁,推荐)

你的逻辑不需要协程,直接把移动和动画逻辑放到Update里更简单,彻底避免协程带来的问题:

using UnityEngine;

public class PlayerManager : MonoBehaviour
{
    public float speed;
    public float runSpeed;
    
    private Vector3 vector;
    private float applyRunSpeed;
    private Animator anim;

    private void Start()
    {
        anim = GetComponent<Animator>();
    }

    private void Update()
    {
        // 获取输入
        float horizontal = Input.GetAxisRaw("Horizontal");
        float vertical = Input.GetAxisRaw("Vertical");

        if (horizontal != 0 || vertical != 0)
        {
            // 处理加速
            applyRunSpeed = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift) ? runSpeed : 0;

            vector.Set(horizontal, vertical, transform.position.z);
            
            // 更新动画参数
            anim.SetFloat("DirX", vector.x);
            anim.SetFloat("DirY", vector.y);
            anim.SetBool("Idle", false);

            // 移动(归一化方向避免斜向加速)
            transform.Translate(vector.normalized * (speed + applyRunSpeed) * Time.deltaTime);
        }
        else
        {
            // 停止移动时切换Idle动画
            anim.SetBool("Idle", true);
        }
    }
}

额外优化建议

  • 用vector.normalized处理方向向量,避免斜向移动时速度比单方向快(斜向向量长度约为1.414,会导致移动速度变相翻倍)
  • 可以给Animator中的DirX、DirY参数设置平滑时间,让动画过渡更自然

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 11:40:03