fbpx

Player Movement in Unity

Read Time:8 Minute, 50 Second

In this guide, we will learn how to add physics-based player movement in Unity and allow the player to walk around the map. In the next guide, we will learn how to add jumping and sprinting in Unity.
Also, be sure to check the Non-Physics Player Movement in Unity.

In every game, the player can somehow move. The way he does depends on the type of the game.
For example, in a first-person shooter, the player can move by walking around. In a racing game, the player can move only forward and backward. To move sideways, he has to turn the wheels.
In chess, there is no player movement at all! The user can only move his pawns.

Setting Everything Up

To allow the user to move around, we need to add a ground the player can move on.
Create a plane by right clicking on the hierarchy view, select “3D Object” and then “Plane”. Change its name to “Ground” and reset its Transform component.

Reset the Ground game object’s Transform component

I will also go ahead and scale the plane so the player has more space to move on.

Scale the plane so the player has more space to move on

Now, let us add a capsule that will be used as our player game object.
Change the game object name to “Player” and reset its Transform component. Same way as the plane above.

We added the player game object and reset its Transform component but now we see the game object is not on the plane but rather intersects with it. Change the player game object’s Y position to 1.
Now our player game object is sitting on the plane and everything looks good.

Change the player game object’s Y position to 1

Create the Player Movement Script File

Now that we have a player and a ground for him to move on, we can write the script to allow our user to move. We need to add a script to the player game object to do that.
There are two methods to add a script to a game object.

Add a Script Component

Select the player game object (either by clicking on it in the hierarchy view or by clicking on it in the scene). In the inspector view, click on Add Component, write “Script” and select “New Script”. Name the script and press Enter. I will name the script “PlayerMovement”.

In your project view, navigate to the Assets folder if you are not already in it, there you can see our new script file. Create a folder called “Scripts” and move the script file to that folder.
This is a small project so it will not have a big impact but in larger projects, it is best to keep everything organized so it will be easier to manage the project.

Create a Script and Assign it to a Game Object

In the project view, create a folder called “Scripts” and enter the folder. Then, right-click in the Project view, select “Create” and then “C# Script”. Name the script “PlayerMovement” and assign it to the player game object by dragging the file onto the player game object in the hierarchy view.

Start coding the Player Movement

Initial Player Movement Script

After we did all that, we can finally start writing the player movement script. Open the script for editing by double clicking the script file in the Project view.

Your default IDE for editing Unity scripts will open with the script file we have just created, and we will start to code player movement in Unity.

Every C# script created in Unity will start like the following.
The only initial difference is the class name which in this case is “PlayerMovement”. The same as the file’s name we created earlier and we are now editing.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine;public class PlayerMovement : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
     
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

In Unity, there are pre-defined methods to ease our development using the engine.
To detect when a player presses the arrow keys or the W, A, S, D keys, simply add the following code to your Update method.

// This will detect forward and backward movement
float horizontalMovement = Input.GetAxis("Horizontal");

// This will detect sideways movement
float verticalMovement = Input.GetAxis("Vertical");

Now we have these two variables but what do they do?

In Unity, we can add public variables to a class. This will allow us to see and edit the variables from Unity’s Inspector view instead of coming back to the script each time.

Let us change the variables we had just create to public variables so we can see what they do.

Add this code above the Start method.

public float horizontalMovement;
public float verticalMovement;

These are the class fields.
When you add variables to a class, they are called fields.

Also, change the code in the Update method to the following.

// This will detect forward and backward movement
horizontalMovement = Input.GetAxis("Horizontal");

// This will detect sideways movement
verticalMovement = Input.GetAxis("Vertical");

Currently, the script file will look like this.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public float horizontalMovement;
    public float verticalMovement;

    // Start is called before the first frame update
    void Start()
    {   
     
    }

    // Update is called once per frame
    void Update()
    {
        // This will detect forward and backward movement
        horizontalMovement = Input.GetAxis("Horizontal");

        // This will detect sideways movement
        verticalMovement = Input.GetAxis("Vertical");
    }
}

Save the script and go back to Unity. Click on the player game object and look for the Player Movement (Script) component. It will look like this.

The Player Movement (Script) component

Enter play mode and try pressing the arrows or W, A, S, D keys.
Do you notice how the values in these fields change when you press the buttons?

Notice how the values in these fields change when you press the buttons

These values ranged from -1 to 1. Horizontally, -1 is left and 1 is right while vertically -1 is backward and 1 is forward.
Knowing that, let us make the player game object move.

Exit play mode and make sure the player game object is selected. Click on “Add Component” and add a Rigidbody component to it (notice you are not adding a 3d rigidbody component).
Great, now physics works on our player game object and we can move it using physics.

Add the following field to the class (underneath the “horizontalMovement” and “verticalMovement” fields we added earlier).

private Rigidbody rg;

Add this line of code to the Start method.

rb = GetComponent<Rigidbody>();

// This will stop the player game object from rotating
// Try to comment this line and see what happens
rb.freezeRotation = true;

And this code at the end of the code inside the Update method.

// Calculate the direction to move the player
Vector3 movementDirection = transform.forward * verticalMovement + transform.right * horizontalMovement;

// Move the player
rb.AddForce(movementDirection, ForceMode.Force);

This will calculate the direction to move the player according to the player’s input. Then, it will move the player by adding a force to the player using physics.

Great, now our player can move. Let us add an option to change the movement speed through Unity.

Add the following class field.

// A field editable from inside Unity with a default value of 5
public float speed = 5.0f;

Also, change this:

rb.AddForce(movementDirection, ForceMode.Force);

To this:

rb.AddForce(movementDirection * speed, ForceMode.Force);

Your final code should look like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public float horizontalMovement;
    public float verticalMovement;

    // A field editable from inside Unity with a default value of 5
    public float speed = 5.0f;
    private Rigidbody rb;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
        rb.freezeRotation = true;
    }

    // Update is called once per frame
    void Update()
    {
        // This will detect forward and backward movement
        horizontalMovement = Input.GetAxisRaw("Horizontal");

        // This will detect sideways movement
        verticalMovement = Input.GetAxisRaw("Vertical");

        // Calculate the direction to move the player
        Vector3 movementDirection = transform.forward * verticalMovement + transform.right * horizontalMovement;
    
        // Move the player
        rb.AddForce(movementDirection * speed, ForceMode.Force);
    }
}

Save the script, go to Unity, enter play mode, and test the player movement.
Nice, we have player movement in Unity but when we release the movement keys, the player keeps sliding and we do not want it (unless you do, haha).

Fixing Player Sliding

To fix this, add a new field to the PlayerMovement class.

// How much will the player slide on the ground
// The lower the value, the greater distance the user will slide
public float drag;

Add this code to the end of the Update method.

// Apply dragrb.drag = drag;

While we are at it, let us also change the “horizontalMovement” and “verticalMovement” fields to private so we will not see them in the Inspector view.

This is what your script should look like now.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{

    private float horizontalMovement;
    private float verticalMovement;

    // A field editable from inside Unity with a default value of 5
    public float speed = 5.0f;

    // How much will the player slide on the ground
    // The lower the value, the greater distance the user will slide
    public float drag;

    private Rigidbody rb;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
        rb.freezeRotation = true;
    }

    // Update is called once per frame
    void Update()
    {
        // This will detect forward and backward movement
        horizontalMovement = Input.GetAxisRaw("Horizontal");

        // This will detect sideways movement
        verticalMovement = Input.GetAxisRaw("Vertical");

        // Calculate the direction to move the player
        Vector3 movementDirection = transform.forward * verticalMovement + transform.right * horizontalMovement;
        
        // Move the player
        rb.AddForce(movementDirection * speed, ForceMode.Force);
        // Apply drag
        rb.drag = drag;
    }
}

Save the script, go back to Unity, select the player game object and change the speed and ground drag to the value of 10, and enter play mode.

Change the speed and ground drag to the value of 10

Now we have player movement in Unity and the player is not sliding on the ground, awesome!
Try playing with the speed and drag values and see how it affects the player’s movement.

Recap

In this guide we learned how to:

  • Add game objects to our scene
  • Add a script to a game object
  • Add physics (rigidbody component) to a game object
  • Detect movement
  • Move the player
  • Prevent the player from sliding after a movement key is released.

In the next guide, we will learn how to add sprint and jump to the player movement.

Leave a Reply

Your email address will not be published. Required fields are marked *