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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:22:25