Unity中命令模式重构角色移动代码后无法移动的问题
Unity命令模式重构角色移动:修复输入无响应问题
以下是从命令链路、输入绑定、核心逻辑三个关键环节的排查与修正方案:
1. 确保命令类与Character的调用链路正确
命令类必须准确持有Character实例,并在Execute中调用对应动作方法,避免出现逻辑空实现、未传递目标角色的问题:
// 抽象命令基类 public abstract class CharacterCommand { protected readonly Character _target; protected CharacterCommand(Character target) { _target = target; } public abstract void Execute(); } // 移动命令 public class MoveCommand : CharacterCommand { private readonly float _direction; public MoveCommand(Character target, float direction) : base(target) { _direction = direction; } public override void Execute() { _target.Move(_direction); } } // 跳跃命令 public class JumpCommand : CharacterCommand { public JumpCommand(Character target) : base(target) {} public override void Execute() { _target.Jump(); } }
2. 修正UserInput的输入检测与命令执行逻辑
输入类需要正确绑定Character组件,并在合适的生命周期触发命令(Update检测输入,涉及物理的逻辑可配合FixedUpdate执行):
public class UserInput : MonoBehaviour { private Character _character; private void Awake() { // 确保获取到父类Character组件 _character = GetComponent<Character>(); if (_character == null) Debug.LogError("未找到Character组件"); } private void Update() { HandleMovement(); HandleJump(); } private void HandleMovement() { float horizontal = Input.GetAxisRaw("Horizontal"); // 每次输入变化时生成并执行移动命令 var moveCmd = new MoveCommand(_character, horizontal); moveCmd.Execute(); } private void HandleJump() { // 仅在按下空格的帧执行跳跃命令 if (Input.GetKeyDown(KeyCode.Space)) { var jumpCmd = new JumpCommand(_character); jumpCmd.Execute(); } } }
3. 验证Character基类的核心动作逻辑
确保Character的移动、跳跃逻辑本身可正常运行,这是命令执行有效的基础:
public abstract class Character : MonoBehaviour { [SerializeField] protected Rigidbody2D _rb; [SerializeField] protected float _moveSpeed = 5f; [SerializeField] protected float _jumpForce = 7f; [SerializeField] protected Transform _groundCheck; [SerializeField] protected LayerMask _groundLayer; protected bool IsGrounded() { // 检测角色是否在地面上 return Physics2D.OverlapCircle(_groundCheck.position, 0.2f, _groundLayer); } public void Move(float direction) { // 仅修改水平速度,保留垂直方向速度(比如下落重力) Vector2 newVelocity = new Vector2(direction * _moveSpeed, _rb.velocity.y); _rb.velocity = newVelocity; } public void Jump() { // 仅在地面时允许跳跃 if (IsGrounded()) { _rb.velocity = new Vector2(_rb.velocity.x, _jumpForce); } } protected virtual void Awake() { if (_rb == null) _rb = GetComponent<Rigidbody2D>(); } }
常见排查点
- 检查Character的
Rigidbody2D:确保Body Type为Dynamic,重力设置正常,未被冻结位置/旋转 - 地面检测:
_groundCheck的位置需在角色脚底,_groundLayer需正确选择地面所在的Layer - 输入配置:Unity Input Manager中是否存在"Horizontal"轴,键位绑定正确
- 组件挂载:UserInput需挂载在Player对象上,且Player继承自Character基类
内容的提问来源于stack exchange,提问作者acarlseen
相关产品推荐
相关产品推荐

