Unity 2021中如何设置玩家Idle状态及上下移动的速度与动画?
问题分析与修复方案
核心问题根源
- Speed参数逻辑错误:原代码仅以X轴输入绝对值作为Speed,导致上下移动时Speed为0(无法触发行走动画);替换为Y轴后,左右移动时Speed为0(左右动画失效)。
- 方向状态未重置:仅在按键按下时设置
isforward,未处理松开后的状态清除,导致松开W后仍保持true,动画卡在行走循环无法回到Idle。 - 方向判断混淆:向下移动(S键)被归为
isforward=false,无法区分向下与左右方向,动画逻辑混乱。
修复后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerMovement : MonoBehaviour { public Animator Animator; [SerializeField] private float speed = 1f; private Rigidbody2D body; private Vector2 axisMovement; void Start() { body = GetComponent<Rigidbody2D>(); } void Update() { axisMovement.x = Input.GetAxisRaw("Horizontal"); axisMovement.y = Input.GetAxisRaw("Vertical"); // 用移动向量的模长判断是否移动,覆盖所有方向 Animator.SetFloat("Speed", axisMovement.magnitude); // 先重置所有方向状态,避免残留 Animator.SetBool("isUp", false); Animator.SetBool("isDown", false); Animator.SetBool("isLeft", false); Animator.SetBool("isRight", false); // 根据输入设置对应方向的动画状态 if (axisMovement.y > 0) { Animator.SetBool("isUp", true); } else if (axisMovement.y < 0) { Animator.SetBool("isDown", true); } else if (axisMovement.x < 0) { Animator.SetBool("isLeft", true); } else if (axisMovement.x > 0) { Animator.SetBool("isRight", true); } } private void FixedUpdate() { Move(); } private void Move() { body.velocity = axisMovement.normalized * speed; CheckForFlipping(); } private void CheckForFlipping() { bool movingLeft = axisMovement.x < 0; bool movingRight = axisMovement.x > 0; if (movingLeft) { transform.localScale = new Vector3(-1f, transform.localScale.y); } if (movingRight) { transform.localScale = new Vector3(1f, transform.localScale.y); } } }
关键修改说明
- Speed参数优化:使用
axisMovement.magnitude代替单一轴的绝对值,确保任何方向的输入都会触发Speed大于0,无输入时Speed为0,Idle动画能正确触发。 - 方向状态重置:每次Update先清除所有方向bool,避免按键松开后残留状态,解决动画卡在循环的问题。
- 方向判断拆分:将原有的
isforward拆分为四个独立的方向bool,清晰区分上下左右,方便Animator状态机对应不同的行走动画。
Animator状态机配置建议
- Idle状态过渡条件:
Speed == 0 - 各行走状态(WalkUp/WalkDown/WalkLeft/WalkRight)过渡条件:对应方向bool为
true且Speed > 0 - 行走状态返回Idle条件:
Speed == 0
内容的提问来源于stack exchange,提问作者jamie
相关产品推荐
相关产品推荐

