Switch input handlers in Unity
In this tutorial we will learn a simple and efficient way to change the input handlers in Unity3D using a UI Button. You can use this in your game menu settings if you want to let users change between different input handlers. This can be also very helpful if we want to port a game from mobile to PC and you still want to keep the logic behind your inputs.
Let’s consider that we have 3 types of input handlers that we want in our game and we want to change them maybe from a settings menu using only one button.
Input handlers:
- Keyboard
- Mouse
- Accelerometer
If we want to change them without headaches we can create an interface called IInput which is going to be implemented by our handlers.
Let’s create the IInput interface. For the moment we have only one dummy method called GetAxis which returns a Vector3 but you can add more methods if you want.
namespace MyGame { public interface IInput { Vector3 GetAxis(); } }
Now let’s create the 3 input handlers classes. MouseInput class looks like this:
namespace MyGame { public class MouseInput : IInput { public Vector3 GetAxis() { //here we can return mouse axis return new Vector3(x,y,z); } } }
Now do the same for KeyboardInput class:
namespace MyGame { public class KeyboardInput : IInput { public Vector3 GetAxis() { //here we can return an axis based on keyboard return new Vector3(x,y,z); } } }
And our last input handler called AccelInput:
namespace MyGame { public class AccelInput : IInput { public Vector3 GetAxis() { //here we can return an axis based on accelerometer return new Vector3(x,y,z); } } }
As you can see all these classes don’t derive from MonoBehaviour, we don’t want to attach them to any GameObject.
Finally, to show how this thing works, we need to create a script called Button_Input_Settings which we will attach to our UI button from Unity3D. Here we have a method OnClick() which is called when we press on the button. In this method we decide what input handler we are going to use:
namespace MyGame { public class Button_Input_Settings : MonoBehaviour { //consider: //keyboard 0 //Mouse 1 //Accel 2 private IInput m_InputType; private int m_InputSelect; //save button Text private Text m_ButtonText; // Use this for initialization void Start() { m_InputType = new KeyboardInput(); //get button text and cache Text component //InputButtonText is the Text UI component of the button m_ButtonText = this.transform.Find("InputButtonText").gameObject.GetComponent<Text>(); //change text to Keyboard m_ButtonText.text = "Keyboard"; } public void OnClick() { m_InputSelect++; //reset m_inputSelect if (m_InputSelect % 3 == 0) m_InputSelect = 0; switch (m_InputSelect) { case 0: m_InputType = new KeyboardInput(); m_ButtonText.text = "Keyboard"; break; case 1: m_InputType = new MouseInput(); m_ButtonText.text = "Mouse"; break; case 2: m_InputType = new AccelInput(); m_ButtonText.text = "Accelerometer"; break; default: break; } } // use the axis public Vector3 GetInputAxis() { return m_InputType.GetAxis(); } } }
This design allows you to keep the code clean and you can easily port from mobile to PC, without changing logic in your code.
I hope you find this helpful. Let me know your thought in the comment section below.
Cheers!