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
相关产品推荐
相关产品推荐

