The basics of Input and Movement with Unity
Many games require the player to operate controls that directly effect the main character of the game, let’s look at how that’s possible in Unity and C#.
Firstly, let’s get setup with a GameObject to represent our player, spruce it up with a nice material and create a C# script to control our Player behaviors.
Once you’re done here, double click the script to open it in your defined editor.
Unity has kindly supplied us with it’s Input Manager which can be seen in the Project Settings window (Edit menu).
The default settings are generic gaming controls — A and D, left arrow and right arrow are mapped to left and right directions as W and S, up arrow and down arrow are mapped to vertical movements. They are also fully customizable to the control system you want to employ in your game.
This is what we’ll be using to detect input from the player.
Using the Unity Input Manager we can access specific information about the inputs and rather than looking for individual key presses, we can use the hierarchal nature of Unity, displayed in the Input Manager to use the Axes listed. For this, we first need to reference the Input class, from there we can find a method called GetAxis() — a quick look at the Unity docs will tell us that we can use the name of the Axis to receive a float value (between -1 and 1).
In our Update method —
// Query the value of the Horizontal Axis
float horizontalInput = Input.GetAxis("Horizontal");
// Similarly with the Vertical Axis
float verticalInput = Input.GetAxis("Vertical");
3D Movement in Unity is by way of Vector3s which are defined as a “Representation of 3D vectors and points”, but as we are only using the 2 axes we can look at the little brother, the Vector2 which is the 2D version. It still represents vectors and points but where a Vector3 uses X, Y and Z co-ordinates, the Vector2 uses just X and Y.
// Apply the inputs to a new Vector2
Vector2 direction = new Vector2(horizontanlInput, verticalInput);
Because the Vector2 is a struct (a container for information), we need to declare it as new when it’s created.
NOTE: The ‘new’ keyword does create garbage which Unity has to collect and dispose of, this can cause a drop in frame rate. While I have it in the Update method for this explanation, it is advisable to not use the ‘new’ keyword here (or in any looping code) where possible.
Once we have our vector setup, we can look at using that to move the player. Because this script is on the player, we can access any positional data on the player through the component ‘transform’. To move the player, there are a few methods we could use but let’s look at translating our player.
// Translate the Player
This instruction will translate our Player in the direction of our inputs. There is however a bit of an issue, the Player is moving far too fast. This is because we are in the Update method which runs approx. 60 times every second (once every frame). Unity does have a way to solve this and that is by using real time — more specifically — the time it took to complete the last frame. I’m also going to add a speed variable.
// At the beginning of our class
public float speed;
then back to our Tranlsate instruction…
transform.Translate(direction * speed * Time.deltaTime);
With that done, we can save our script and go back to Unity. Make sure we set a value for the speed on our Player (I’ve gone for 10) and hit play!