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

如何在播放坐下等特定动画时禁止玩家移动?(New Input System)

解决Unity第三人称控制器坐下时仍可移动的问题

你已经成功添加了坐下输入和动画,但问题出在没有用你定义的disableMovement标记去拦截移动逻辑。以下是具体修改方案:


1. 从输入源头切断移动指令

修改StarterAssetsInputs.cs,在处理移动输入时,若处于禁用移动状态,强制将移动输入设为0:

找到OnMove方法(处理WASD输入的回调),修改为:

public void OnMove(InputValue value)
{
    if (disableMovement)
    {
        MoveInput(Vector2.zero);
    }
    else
    {
        MoveInput(value.Get<Vector2>());
    }
}

如果你的MoveInput方法是直接赋值的,也可以在该方法内添加判断:

public void MoveInput(Vector2 newMoveDirection)
{
    move = disableMovement ? Vector2.zero : newMoveDirection;
}

2. 在核心移动逻辑层拦截

修改ThirdPersonController.cs的Move方法,在执行移动计算前先检查禁用状态,直接跳过移动逻辑:

private void Move()
{
    // 坐下时直接终止移动逻辑
    if (_input.disableMovement)
    {
        // 同步把动画的Speed参数设为0,避免残留移动动画
        if (_hasAnimator)
        {
            _animator.SetFloat(_animIDSpeed, 0f);
        }
        return;
    }

    // 以下是原有的移动逻辑代码,保持不变
    Vector3 moveDirection = new Vector3(_input.move.x, 0.0f, _input.move.y).normalized;

    if (_mainCamera != null)
    {
        Vector3 cameraForward = _mainCamera.transform.forward;
        cameraForward.y = 0f;
        cameraForward.Normalize();
        moveDirection = Quaternion.LookRotation(cameraForward) * moveDirection;
    }

    float targetSpeed = _input.sprint ? _sprintSpeed : _walkSpeed;
    if (_input.move == Vector2.zero) targetSpeed = 0.0f;

    float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude;
    float speedOffset = 0.1f;
    float inputMagnitude = _input.analogMovement ? _input.move.magnitude : 1f;

    if (currentHorizontalSpeed < targetSpeed - speedOffset || currentHorizontalSpeed > targetSpeed + speedOffset)
    {
        _speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude, Time.deltaTime * _speedChangeRate);
        _speed = Mathf.Round(_speed * 1000f) / 1000f;
    }
    else
    {
        _speed = targetSpeed * inputMagnitude;
    }

    Vector3 velocity = moveDirection * _speed;
    velocity.y = _controller.velocity.y;

    _controller.Move(velocity * Time.deltaTime);

    if (_hasAnimator)
    {
        _animator.SetFloat(_animIDSpeed, inputMagnitude);
        _animator.SetFloat(_animIDMotionSpeed, inputMagnitude);
    }
}

3. 可选:禁用坐下时的跳跃/冲刺(按需添加)

如果需要坐下时无法触发跳跃和冲刺,在StarterAssetsInputs.cs的对应方法里添加判断:

public void OnJump(InputValue value)
{
    if (!disableMovement)
    {
        JumpInput(value.isPressed);
    }
}

public void OnSprint(InputValue value)
{
    if (!disableMovement)
    {
        SprintInput(value.isPressed);
    }
}

这样修改后,按下Z触发坐下后,WASD输入会被清空,同时移动逻辑也会被直接跳过,彻底实现坐下时无法移动的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:32:09