The first and relatively simple functionality we can add is the ability to jump. We already have basic physics with gravity working on the Player game object. Before we can make our Player game object jump, we need to know when this should happen. The user always needs some sort of interface in order to interact with the game. On the PC and Mac, in most of cases, it will be the mouse or keyboard. On mobile devices, it will be the touchscreen.
Unity gives us a lot of out-of-the-box functions we can call to check whether user is trying to interact through any input.
As we are writing a standalone game, I think it best if we stick to the mouse control.
Please open the Unity Scripting Reference and search for Input
. You can have a read through the documentation on the Input
class of jump straight to the Input.GetMouseButtonDown
public method. Read it thoroughly.
Input.GetMouseButtonDown
returns true
during the frame when the user pressed the given mouse button. According to the documentation, it's best if we call Input.GetMouseButtonDown
inside the Update
function. Let's write some code to test how it works:
In line 14 Input.GetMouseButtonDown(0)
returns the bool
value so we can use it in the if
statement directly.
if(Input.GetMouseButtonDown(0))
This is in fact exactly same as the next line:
if(Input.GetMouseButtonDown(0) == true)
Line 14 is executed in every frame over and over again when Unity is in Play mode. If the user clicks on the left mouse button, the if
statement value in line 14 will be true in that frame and Unity will execute everything within the if
statement code block. Complicated? If so, I'll try again.
If the user clicks on the left mouse button, Debug.Log("Left mouse button clicked!")
will execute and a message will be displayed in the Console window. Go ahead, save the file and press Play in Unity. Click on the left mouse button on the Game window. You will see the Console populating message every time you click. We can handle the user input now and tell Jake to jump when the user wants it.
I will be sending you to the Unity Scripting documentation many times now to make sure you understand the code before we use it and to learn that it is always a good practice to investigate the documentation if you see something new. Nobody would ever expect you to remember the entire Unity documentation, so it's good to learn how to find stuff you need.
Search scripting reference for Rigidbody2D.AddForce
. This is the way we will apply force on Jake. Let's add more code to PlayerController
so it looks more or less like this:
Lots of new code! Let's go through each new line we have added.
Line 6 should be very easy to understand for you now. It declares the float
type variable jumpForce
. In lines 7 and 10, we will be controlling the character physics in the PlayerController
script, so we need easy access to the RigidBody2D
component on the same game object.
Have a look in the Scripting Reference for GameObject.GetComponent
. It searches the game object our PlayerController
is attached to for the Rigidbody2D
component and returns it so we can assign the rigidBody
private variable for easy access. GetComponent
must be called at runtime, so we are calling it in the Awake
function. After line 10, we can simply say rigidBody
. The RigidBody2D
component will be called on playerGameObject
.
See how simple the Jump
function is. It's just a simple line saying, "Hey RigidBody, apply force with the direction up with this jump force." There are a few force modes we can use for other useful stuff; however, impulse make sense for jumping. We just want to kick the character up and then let him fall back to the ground.
Go ahead, press Play in Unity and then click on the left mouse button a few times in the game view. Hey! Jake is actually jumping but something is wrong. We need him to jump higher. Experiment with the jump force in the inspector to find the right value. I think value 25
looks good for the jump height. It's not too high and not too low.
You probably noticed already we have another issue. We are applying the jump force every time the left mouse button is clicked. This is good. However, Jake should not jump in the air. If you click on the left mouse button many times quickly, he'll simply fly away. We can fix that by adding bit more code. The right behavior will be to only jump when the character is on the ground.
Lets add the following code and edit the Jump method a little:
I will make a little exception from the rule; I won't analyze this code from top to bottom. I want to talk about the IsGrounded
function. In programming and math in general, there isn't any simple way of asking the computer if the character is on the ground or in the air. Game developers must turn complex ideas and into simple programmable parts. Let's not talk about the IsGrounded
method yet. Let's focus on line 31.
Search the scripting reference for Physics2D.Raycast
and have a read through. You should see that raycast is casting a ray against colliders in the scene. It does sound very complicated. Trust me, it isn't. It will all be clear to you in few minutes. Raycast? What is the mystery about raycast? The simplest real-life example for raycast would be a laser pointer. Imagine you are holding the laser pointer and pointing at the floor. This is exactly what are we doing in line 31. We are basically saying "Hey Unity, shoot the laser down from this GameObject
position and check whether the distance to hit any object on the ground layer is less than 0.2."
Have a look at this picture. The green point represents the origin of the ray we are virtually casting. The blue point is the hit point. The ray distance would be the distance between the origin and the hit point. In this case, we are casting the ray down to a maximum distance of 0.2. I have visualized that distance with a yellow line. Looking back at IsGroundedMethod()
, we can see that the method is returning true if the raycast hit happens within a distance of 0.2 or less; otherwise, we return false.
I hope this is fairly clear to you now. Let's look at the parameters in the actual Raycast
function again. Physics2D.Raycast
has lots of different overloads, which means we can pass a few sets of parameters to the method. In this case, we are using an overload with four parameters:
Origin
Direction
Distance
layerMask
You can preview the names and types of the parameters if you hover your mouse for a new seconds above the Raycast
word in the code:
.
We have already covered origin
, direction
, and distance
. Let's talk briefly about layerMask
. We can specify a filter here to detect colliders only on certain layers. This means we can set Unity to make raycast work only on specific layers. In this case, we are simply checking if Player is grounded or not. So, the wise thing to do is to set raycast to work only with objects on the ground layer.
To make sure everything works as it should, we must create the ground layer.
Ground
next to User Layer 8.FloorShort
game object in the hierarchy and set its layer to Ground. Set it up as shown here:IsGrounded()
method returns true, the Jump
method is called; otherwise, we simply ignore the user click.