这里是一个问题,其中使用 Unity 的 Input System API,表现得有些奇怪。

首先,我们需要了解这段代码的作用:它创建了一个 Input Action Map,并添加了一系列的动作,控制摄像机的移动和旋转。但其行为有些令人混乱。

原因可能是因为我们并没有合理地处理用户的输入。让我们一步步分析:

  1. _lookAction.AddBinding("<Mouse>/position"); 这行代码让用户通过鼠标左键控制摄像机的旋转。此时,鼠标不再是右键。
  2. 当用户同时按下 W 这个键(或其他 WASD 键)和鼠标右键时,这个问题就会出现。我们期望用户能够既可以移动摄像机,又可以旋转摄像机。但是,以目前的设置,用户在释放右键(或按下,取决于具体的事件)后,鼠标就变成了左键,我们期望它一直是右键。

这里的关键点是 _lookButtonAction.AddBinding("<Mouse>/rightButton") 这一行代码。它的作用是检测鼠标右键的点击。问题发生在我们判断右键的判断逻辑部分。

我们期望 _lookButtonAction.ReadValue<float>() 永远小于 0.2f。但是,问题是 _lookButtonAction 并不是一个持续的值,是一个“弹性”的弹跳值(按下后马上弹起来),而不是一个持续的操作值,直到按下按键后才释放直到按下另外一个按键。

这就解释了为什么你要按 W 先,然后才能旋转摄像机了。你必须先按下 W,才会让用户能够旋转摄像机。

那么,如何做到既可以移动,也可以旋转呢?

让我们看看这个:

private InputActionMap _map;
private InputAction _moveAction, _verticalAction, _lookAction, _lookButtonAction;
private float _previousHorizontalValue, _previousVerticalValue;
private bool _hasPreviousMouse = false;

private void OnEnable()
{
    _map = new InputActionMap("Camera");

    _map.Enable();
}

void Update() 
{
    // Check  LookButton down state 
    if (_lookButtonAction.ReadValue<bool>())
    {
        // Hold down and Press the right mouse button 
        if(_lookButtonAction.ReadValue<bool>() && 

            "_rightMouseBtnState == false ")
        {

            _rightMouseBtnState = true;
        }

        else
        {
            _rightMouseBtnState = false;


        }
    }
}

 private void UpdateCamera()
{
    if (_lookButtonAction.ReadValue<bool>())
    {//
        // Check whether  previous mouse state changed
        if (_previousMouseState != _lookButtonAction.ReadValue<float>())
        {
            _previousMouseState = _lookButtonAction.ReadValue<float>();

            _hasPreviousMouse = true;

        }

    }

    // If Move and lookButton both hold down
    if (_moveAction.ReadValue<Vector2>() != Vector2.zero)
    {
            // Check the right mouse button state
            if (_rightMouseBtnState == true)// 
                {
                    // Check whether MoveAction is hold down before previous Mouse State
                    if (_moveAction.ReadValue<Vector2>() != Vector2.zero)

                    {//
                        _hasPreviousMouse = false;

                        // RotateCamera
                        // RotateCamera();
                    }

                }
                //
    }
}

此时问题就得以解决了,可以既移动,又可以旋转了。