【问题标题】:Unity Input System mouse button hold and dragUnity 输入系统鼠标按键按住并拖动
【发布时间】:2021-03-01 15:03:31
【问题描述】:

我正在制作一个 2D 数字棋盘游戏,并使用新的 Unity 输入系统(版本 2020.2.6f1)添加一些用于相机控制的玩家控件。对于鼠标和键盘设置,我能够测量单击和保持(使用交互),但我似乎无法将左键、右键或中键单击的保持与鼠标移动结合起来。我尝试在轴上创建一个“使用一个修改器复合添加按钮”或“两个修改器复合”,但这只是将两个或三个按钮组合在一起。我需要将鼠标的 Vector2 delta 与鼠标或键盘按钮单击(并按住)相结合的东西。

现在,我有一个单独的动作用于鼠标移动来设置状态,然后一个用于指针移动以根据状态执行某些操作。

我的方法是正确的方法吗? Unity 中是否存在带有按钮修饰符的 Vector2(或类似的东西)?

这是我早期的输入代码。如您所见,有一个版本的平移、旋转和拖动(“OnSet”方法)对应于设置 CameraState,然后是“OnPointerMovement”,它根据输入系统中的鼠标增量进行移动。然后是用于使用游戏手柄的“OnPan”和“OnRotate”(OnPan 使用右摇杆,OnRotate 使用 L/R 触发器作为轴)。

using UnityEngine;
using UnityEngine.InputSystem;

public class HumanPlayerInput : MonoBehaviour
{
    [SerializeField]
    Player HumanPlayer;
    [SerializeField]
    Camera PlayerCamera;
    PointerChangeState CameraState;

    void OnEnable()
    {
        CameraState = PointerChangeState.None;
        if(PlayerCamera = null)
            SetPlayerCamera();
    }

    public void OnSetPan(InputAction.CallbackContext context) => SetPointerState(context.ReadValueAsButton(), PointerChangeState.Pan);

    public void OnSetDrag(InputAction.CallbackContext context) => SetPointerState(context.ReadValueAsButton(), PointerChangeState.Drag);

    public void OnSetRotate(InputAction.CallbackContext context) => SetPointerState(context.ReadValueAsButton(), PointerChangeState.Rotate);

    public void OnPan(InputAction.CallbackContext context) => PanCamera(context.ReadValue<Vector2>());

    public void OnRotate(InputAction.CallbackContext context) => RotateCamera(context.ReadValue<float>());

    public void OnPointerMovement(InputAction.CallbackContext context)
    {
        switch(CameraState)
        {
            case PointerChangeState.Drag:
                break;
            case PointerChangeState.Pan:
                PanCamera(context.ReadValue<Vector2>());
                break;
            case PointerChangeState.Rotate:
                RotateCamera(context.ReadValue<Vector2>().x);
                break;
            default:
                break;
        }
    }

    public void OnZoom(InputAction.CallbackContext context) => PlayerCamera.orthographicSize = context.ReadValue<float>() * 100f;

    void PanCamera(Vector2 changeInPan) => PlayerCamera.transform.Translate(changeInPan * 500f);

    void RotateCamera(float changeInRotation) => PlayerCamera.transform.Rotate(Vector3.up, changeInRotation);

    void SetPointerState(bool isButtonPressed, PointerChangeState stateToEnable) => CameraState = isButtonPressed ? stateToEnable : PointerChangeState.None;

    void SetPlayerCamera()
    {
        var playerCameraTransform = transform.Find("PlayerCamera");
        if(playerCameraTransform == null)
            PlayerCamera = Camera.main;
        else
        {
            PlayerCamera = playerCameraTransform.GetComponent<Camera>();
            if(PlayerCamera == null)
                PlayerCamera = Camera.main;
        }
    }
}

【问题讨论】:

    标签: c# unity3d input


    【解决方案1】:

    所以我总是创建新输入系统的 c# 脚本并使用它,你的方法对我来说有点不寻常,但我遇到了同样的问题。在我看来,Unity 在新系统中没有“按住”或按住某些功能。但是对于一个动作,它有 3 种不同的状态,分别是执行、取消和完成。

        bool pressed = false;
        SetPan.performed += ctx => pressed = true; 
        SetPan.canceled += ctx => pressed = false;
    

    假设您用鼠标单击,然后您的操作将首先“执行”,这将使 bool 为 true,并且如果您不再将其设置为 false,它将永远保持为 true。所以你可以使用这个布尔值来确定你仍然按住按钮,这样你就可以在按住时拖动鼠标。释放鼠标后,将触发 cancelled 事件,您可以使用该事件来重置您按下的 bool 值。 Unity 新输入可以理解您按下或释放的时间,但不会像您想象的那样连接它们。这也是我的期望,但是好吧,所以你需要检查你何时开始一个动作,你需要检查你何时完成它,并使用这两个值。

    还有一个“已执行”事件,但在这种情况下您不需要它。你可以查看here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-05
      相关资源
      最近更新 更多