Rigidbody Movement & Jump Behaviour
I have realized that I had no article on using the Rigidbody component to make the player move. In the Dungeon Escape game, the main character will be moved by using Rigidbody component (since it’s a 2D game, Rigidbody2D will be used). For more information regarding Rigidbody2D component, you can click here to reach the Unity website about it.
Rigidbody2D.velocity is the method that is going to be used in order to move the Player. To make sure that the Player will not rotate in an irrational way, make sure to check the Freeze Rotation on the Z axis.
The jump part is a little bit tricky. Unlike using a Character Controller, we need to tell the Player that he/she is touching the floor by scripting — using Rays. The idea is simply shooting a ray perpendicular to the floor from the player. The length of the ray will also be crucial. To cast a ray:
RaycastHit2D hit2D = Physics2D.Raycast(transform.position, Vector2.down, 1.0f);
It is possible to observe ray that we are casting by using Debug.DrawRay method. By default, the color of the ray is white but it is possible to customize it.
Debug.DrawRay(transform.position, Vector2.down, Color.green);
As can be seen on the left side, I have casted a green ray from the position of the player towards the ground. As long as this ray hits the ground, we will tell the game that our player is grounded.
Once we send a ray, the ray will be colliding all of the objects along its path, irrelevant of their Layer rankings, including the Player himself. In order to make sure that the jumping system will work flawlessly, we can set the Ray to collide with a Layer of our desire.
Unity uses ints for the Layermasks, which has a size of 32 bits. Thus, we can have up to 32 layers in our game. We can add a Layer of our own by simply clicking on Layer — Add Layer.
Set the Ground objects’ layer to Ground.
RaycastHit2D hit2D = Physics2D.Raycast(transform.position, Vector2.down, 1.0f, 1<<8);
Changing the Raycast line to the above simply tells the game that the ray will only collide with the objects in the Layer 8.
For a perfect floor detection, we need to optimize the ray length. In my case, 0.75f has given the best result.
Additionally, setting the bool for checking ground once it touches the floor causes the player to double jump (since the game runs for 60 fps, the bool immediatly returns to true on the next frame as player did not reach a distance far above the floor in 1 frame). Thus, there is a need for a delay on the setting the floor check boolean.
And it works — I cannot double jump even if I want to.