First Person Movement Controller

Step 1
Start by creating an empty GameObject called Player
Step 2
Create an empty GameObject as a child of Player. Call it PlayerCollider

Add a CapsuleCollider with a radius of 1 and height of 3 to the GameObject.

Also add a Rigidbody component.

Step 3
Place the Main Camera inside the Player GameObject
Step 4
Create a new Script called PlayerController, and add it to the PlayerCollider GameObject
Step 5
Declare a public variable which controls the speed the Player walks at

Making this variable public let's us change it in the inspector. (But do this later, once your script has been saved)

Step 6
Declare a reference variable to a Rigidbody called rb

We'll also need to control the Player's Rigidbody to get it to move. So let's create a Rigidbody type variable called rb (or rigidbody).

Step 7
Declare a Vector3 which holds the direction the player is moving in
Step 8
Store a reference to the Rigidbody component in your code

We use the Awake() function to assign references to GameObject components.

Now anytime we want to refer to the Rigidbody, we simply use the variable rb

Step 9
Add an Update and a FixedUpdate function to your code

Update is a function which is called every frame. We use it for anything which needs to be updated every frame- except for physics-based functions

FixedUpdate is called every physics step and is used to update any Physics-based actions.

Unity has provided a quick video on the topic of FixedUpdate vs Update which you should watch

Step 10
Store the user input for horizontal and vertical movement in two temporary floats

You don't have to use GetAxisRaw if you would prefer to use GetAxis

Here is a quick video about using GetAxis to control how it feels to move your character

Step 11
Combine the inputs and store them in the moveDirection Vector

A visualization of this code will be shown in the next step

Step 12
Visualizing the Vector math in the above step

Vectors are very important in Unity and understanding them is a key which unlocks a great deal of potential.

You don't have to understand everything now, but here's a visualization of what we just did

  1. The Player's Transform component tells us which direction is forward and which is right.

  2. We scale these Vectors by multiplying their magnitude by the horizontal and vertical inputs from the user.

  3. We then add these directions together

  4. Normalizing vectors make sure they all have a magnitude of 1. Since adding the two vectors together produces a vector whose magnitude is larger than 1, it means the player will move faster going diagonally. So we normalize it

Step 13
We know the direction we want to move in. Now we need to actually make the player move

In the next steps we will tell our Rigidbody to move in this direction with a speed of walkSpeed

Step 14
Create a function named Move and call it from within FixedUpdate

Remember we are using FixedUpdate because Rigidbody motion is a physics-action

Step 15
Move the player in the direction given by the user at a speed equal to walkSpeed

Time.deltaTime helps to give speed more manageable units. Think of it like appending "per second".

If walkSpeed is 100 units, we will be walking with a speed of 100 units per second

Check Your Work
Step 16
Let's go back to the Editor and hit play

You'll first want to add a surface for your player to walk on. You can just use a cube or a plane if you don't have something already.

If you do, you'll notice something like this happens

Okay, that's not so pretty. When forces act on our Rigidbody it just falls over and rolls around.

Let's fix that in the next step!

Step 17
Use RigidbodyConstraints to prevent rotation

Let's see, we'll eventually want our player to turn and look around, so we need roation around the y-axis, but never around the x or z-axes.

Now let's try!

Check Your Work
Step 18
Your player should now be walking around without falling

At this point you may want to play with your walkSpeed

Step 19
One more thing to fix

Speaking of falling. There is one thing we need to fix in our Move function.

You might notice if you walk off an edge, the Player falls extremely slowly. No it's not because gravity is set too low...

Let look at our Move function again

Step 20
Our moveDirection Vector is setting our Y-velocity to 0 every FixedUpdate step

Remember that moveDirection is made out of a forward facing and a rightward facing vector.

Thus the y-component is always 0

So every FixedUpdate step we are setting our rb.velocity.y back to 0 despite gravity trying to pull it down

Step 21
Here's a simple yet ugly way to fix this

There are many ways to fix this problem, but a simple idea is to store the y-velocity in a Vector3 and then add it back on after it gets set to 0

Step 22
Now you may play with the gravity all you want

You may want to do this later, for now all you need to know is that you can change the gravity by going to Edit>ProjectSettings>Phyics

Step 23
In the next lesson we will get the Camera to look around based on the Mouse's position on the screen

Try one of these lessons next:

First Person Movement Controller Info



Created By



First Person Exploration

Access Level


For Teachers and Schools

Teach coding to your students with MVCode Teach

MVCode offers an integrated product designed to teach coding to students.

Learn more about MVCode Teach