Simple Movement using Gamepad and Keyboard - Unity Game Development Tutorial

In this Unity game development tutorial we'll look at how we can process player input from a gamepad or the keyboard and use that to move an object within the game.

1. To get started let's create a new 3D project in Unity Hub.

Creating a 3D game project

2. Add a Plane to the scene to represent our floor by clicking the plus button on the Hierarchy panel and selecting 3D Object->Plane.

Adding a plane to the game scene

3. We'll use a capsule to represent our player. Add this to the scene by clicking the plus button on the Hierarchy panel and selecting 3D Object->Capsule.

Adding a capsule to the game scene

4. Set the position of the capsule to (0, 1, 0) in the Inspector panel to position it on top of the plane.

Setting the position of the capsule in the scene

5. In order to process the player input and use it to make the capsule move we need to create a C# script to contain our logic. To do this click on the 'Add Component' button in the Inspector panel, search for script and click 'New Script'. Call the new script PlayerMovement.

Adding a script component

This will create a script component attached to the capsule.

6. Double click the PlayerMovement script in the Project panel to open the script in Visual Studio. You'll see the default script which has a method called Start and another called Update. 

The Start method is called when the Scene starts. We won't be needing this for this script so it can be deleted.

The update method is called every frame and this is where we'll be putting our input handling logic.

Change the script to match the following

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    void Update()
    {
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        Debug.Log($"Horizontal input: {horizontal}, Vertical input: {vertical}");    
    }
}

The first line in the Update statement is getting the input from the player for the horizontal axis and assigning it to a float variable. It will result in a value between -1 and 1 being stored in the variable depending on what input there is. By default Unity maps the horizontal axis input to the left and right arrow keys, the A and D keys, and the left and right movement of the gamepad left thumbstick. So, for example, the horizontal value will be -1 when we press the left arrow and +1 when we press the right arrow.

The second line does the same  for the vertical axis. Unity has the vertical axis input mapped to the up and down arrow keys, the W and S keys, and the up and down movement of the gamepad left thumbstick.

The final line in the method will simply output a message to the console with the value of the horizontal and vertical input.

7. Save the script and return to Unity. Switch to the Game view and press the play button. If you now press the arrow keys, the WASD keys or use the left thumbstick of a connected gamepad, you will see the input in the message at the bottom of the screen. 


8.  We can now use the input values we obtained in the previous step to set the movement of the capsule. Add the following lines to the Update method, just below the Debug.Log line.

        Vector3 movementDirection = new Vector3(horizontal, 0, vertical);

        transform.position += movementDirection * Time.deltaTime;

The first line is creating a three dimensional vector with our desired movement direction. The direction on the X axis will be determined by our horizontal input and the direction on the Z axis will be determined by our vertical input. The direction in the Y axis will be set to zero as we don't want the capsule to travel up or down.

The second line is changing the position of the capsule based on the movement direction. Time.deltaTime is the amount of time that has passed since the last frame so we need to multiply the movement direction by this value to ensure the capsule moves at the same speed regardless of our framerate. This prevents the capsule moving faster on more powerful machines.

9. Save the script and return to Unity. Switch to the Game view and press the play button. If you now press the arrow keys, the WASD keys or use the left thumbstick of a connected gamepad, you will see the capsule moving in response.

Moving the capsule in the Game view

10. The capsule is now moving but it isn't doing so very quickly. To remedy this, we'll now add a way to control the speed. Add the highlighted changes to the script.

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public float speed;

    void Update()
    {
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        Debug.Log($"Horizontal input: {horizontal}, Vertical input: {vertical}");

        Vector3 movementDirection = new Vector3(horizontal, 0, vertical);

        transform.position += movementDirection * speed * Time.deltaTime;
    }
}

Here we have added a public float variable to hold the speed, and then we are multiplying the movement by this speed.

11. Save the script and switch back to Unity. As we made the speed variable public it is now available to set in the Inspector panel. Set the value to 5.

Setting the movement speed

12. Switch to the Game view and press the play button. The capsule will now move much faster. Try changing the value of the Speed value to see how it affects the movement speed.

13. If you move in a diagonal direction you may notice that the capsule is moving faster than when it is moving in one direction. This is because, in this scenario, the magnitude of the movement direction is greater than 1. For example a Vector3 of (1, 0, 1) has a magnitude of 1.4142135623730951. To fix this we need to normalize the movement direction vector. Normalizing a vector maintains the direction but sets the magnitude to 1.

Add the highlighted line to the script to do this.

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public float speed;

    void Update()
    {
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        Debug.Log($"Horizontal input: {horizontal}, Vertical input: {vertical}");

        Vector3 movementDirection = new Vector3(horizontal, 0, vertical);
        movementDirection.Normalize();

        transform.position += movementDirection * speed * Time.deltaTime;
    }
}

14. Save the script and play the game again to see that the speed is now consistent in all directions.

15. You may notice that when controlling the capsule with the keyboard that the motion doesn't stop immediately when the key is released. This is because the input falls off at a configured 'Gravity' rate. To change this, go to Edit->Project Settings on the main menu and select 'Input Manager'. Expand the Axes and set the Gravity value of the Horizontal and Vertical axis to 18. 

Changing the input falloff

When you play the game now the capsule will stop as soon as the key is released.

That covers everything for this tutorial. We hope that you found it useful. Please leave any questions or feedback in the comments below, and don't forget to subscribe to get notified when we publish our next post.

Thanks.

Comments

Popular posts from this blog

Rotating a Character in the Direction of Movement - Unity Game Development Tutorial

Changing the Colour of a Material - Unity Game Development Tutorial

Creating Terrain from Heightmaps - Unity Game Development Tutorial