2

I am making a 2D digital board game and adding in some player controls for camera control using the new Unity Input System (version 2020.2.6f1). For mouse and keyboard setup, I am able to measure a click and a hold (using an Interaction), but I can't seem to combine the hold of left, right, or middle button click in combination with the mouse movement. I tried to make a "Add Button with One Modifier Composite" or "Two Modifier Composite" to an Axis, but that just combines two or three buttons together. I need something that combines the Vector2 delta of a mouse with a mouse or keyboard button click (and hold).

Right now, I have a separate action for the mouse movements to set a state and then one for pointer moves to do something based on state.

Is my approach the right approach? Does a Vector2 with a button modifier exist in Unity (or something like it)?

Here is my early input code. As you can see, there is a version of pan, rotate, and drag (the "OnSet" methods) which corresponds to setting the CameraState, and then the "OnPointerMovement" which does the movement based on mouse delta from the Input System. Then there is the "OnPan" and "OnRotate" which is for using a Gamepad (OnPan uses right stick and OnRotate uses L/R triggers as an Axis).

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;
        }
    }
}

1 Answer 1

3

So as I always create c# script of the new input system and use it, your method is a bit unusual for me but I had the same problem. It appeared to me that Unity doesn't have a "hold" or keep pressing something feature in the new system. But what it has 3 different states for an action as performed, canceled and completed.

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

Say you click with your mouse, than your action will be first "performed" which will make a bool true AND it will stay true forever if you don't set it to false again. So you can use this bool value to determine you are still holding the button so you can drag your mouse as you hold. Once you release the mouse, the canceled event will fire and you can use that event to reset your pressed bool value. Unity new input understands when you press or when you release but it doesn't connect them as you think. It was my expectation as well, but well, so you need to check when you started an action, and you need to check when you finished it, and use those two values.

There is also a "performed" event but in this case you won't need it. You can check it here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.