Managing Input from mouse and Gamepad

I use Cinemachine Freelook for my Camera. As default this camera moves around with the mouse, but I wanted it to only move if I was holding down mouse(1) at the same time, so I added this script (that I found online):

public class FreeLookUserInput : MonoBehaviour {

    private bool _freeLookActive;

    // Use this for initialization
    private void Start()
    {
        CinemachineCore.GetInputAxis = GetInputAxis;
    }

    private void Update()
    {
        _freeLookActive = Input.GetMouseButton(1); // 0 = left mouse btn or 1 = right
    }

    private float GetInputAxis(string axisName)
    {
        return !_freeLookActive ? 0 : Input.GetAxis(axisName == "Mouse Y" ? "Mouse Y" : "Mouse X");
    }
}

While I understand what it does, I do not understand it well enough to modify it now that I want to support an X-box controller.
I want the camera to move around when moving my right stick on the controller, which works fine. But only when I hold down mouse(1).

Can anyone explain how I can solve this? Or if not, translate the GetInputAxis method into a “normal” if-statement, since I am not familiar with these ? : in C#.

Basically I need to have another Axis that listens to my Gamepad, so I can in my code determine if the player is using a mouse or a controller, and if it is coming from a controller, it should not require the player to hold down mouse(1).

The ? : is called a ternary operator and is basically a shortcut if-else statement.

string FormatHealth(int health)
{
   return (health < 10) ? "Near Death" : "Healthy"

  // is the same as:
  /*
    if(health < 10)
       return "Near Death";
    else
      return "Healthy";
*/
}

As for your issue, I assume you can simply feed it whatever value you want in order of preference, controller axis first? I’ve never used a gamepad for input, but I found these two resources: one and two. I’m also not entirely sure how that Cinemachine callback works, so you’ll probably have to play around with the code.

So assuming you have everything setup correctly with the input manager, try something like this:

private float GetInputAxis(string axisName)
{
   switch(axisName)
   {
       case "Mouse X":
           float controller = Input.GetAxis("RightThumbstickHorizontal");

           if(Mathf.Approximately(controller, 0) == false)
               return controller;
           else
               return (_freeLookActive == true) ? Input.GetAxis("Mouse X") : 0;
       break;
       case "Mouse Y":
           float controller = Input.GetAxis("RightThumbstickVertical");

           if(Mathf.Approximately(controller, 0) == false)
               return controller;
           else
               return (_freeLookActive == true) ? Input.GetAxis("Mouse Y") : 0;
       break;
   }
}

Thanks for this, this worked really well, just some tiny modifications and it worked instantly :slight_smile:

For future use here is the entire script:

public class FreeLookUserInput : MonoBehaviour {

    private bool _freeLookActive;

    // Use this for initialization
    private void Start()
    {
        CinemachineCore.GetInputAxis = GetInputAxis;
    }

    private void Update()
    {
        _freeLookActive = Input.GetMouseButton(1); // 0 = left mouse btn or 1 = right
    }

    private float GetInputAxis(string axisName)
    {
        float controller = 0;

        switch (axisName)
        {
            case "Mouse X":
                controller = Input.GetAxis("Gamepad X");

                if (Mathf.Approximately(controller, 0) == false)
                    return controller;
                else
                    return (_freeLookActive == true) ? Input.GetAxis("Mouse X") : 0;
            case "Mouse Y":
                controller = Input.GetAxis("Gamepad Y");

                if (Mathf.Approximately(controller, 0) == false)
                    return controller;
                else
                    return (_freeLookActive == true) ? Input.GetAxis("Mouse Y") : 0;
        }

        return 0;
    }
}
1 Like

this doesnt work. how do you get this working. also i need to put this on an empty game object.