Jumping (is Grounded)
- To check if you are able to jump, you need to "sense" if there is ground below your player.
- There are many ways to do this, we will use Physics2D.Raycast() to shoot a ray straight down of a certain length and see what it hits
- This tutorial borrows heavily from the great, brief tutorial by Kyle Banks here:
One Major Improvement:
Rather than doing a single raycast down from the center of your sprite, use multiple raycasts.
With a single raycast in the center, if you are on the edge of a platform you cannot jump, as your "center" is not above the ground.
The image to the right shows better locations for raycasts. The bottom two arrows could be used on the side edges of the player.
The left and right sides could be used to detect wall jumps, or detect if you are near something.
Step 1 - Setting Up Physics Layers
First, set up the physics layers in your game so that only a single "Ground" layer will be detected by your ray. These physics layers are completely different than the "Sorting Layers" that the Sprite Renderer class uses to display things on top of one another.
1. In the top right, from the drop down menu, select "Layers --> Edit Layers ... "
2. Type in a new layer titled "Ground" below the default layers that already exist.
3. Then click on your platform/ground GameObject in the hierarchy, and assign it to this layer in the top right of the Inspector window.
Step 2 - The Code
1. Make two public variables.
a. The first variable will be selecting which layers layers are detected by the ray. In Unity, this variable will show up as a drop down menu. You will uncheck all but the newly created "Ground" layer.
b. The second variable will be a float length the ray shoots. You can guess-and-check this one to get the feel right, or use this line of code to detect the exact game unit distance from the center of your sprite to the bottom of your sprite:
- Debug.Log("Distance from center of sprite to bottom of sprite in game world units:" + GetComponent<SpriteRenderer>().bounds.extents.y);
2. Create the "IsGrounded()" method that will return true or false of whether you can jump or not.
a. This creates a ray that:
- Starts at your sprites center (transform.position)
- Shots down (Vector3.down)
- The ray is only of a set length in game world units (rayDistance)
- The ray only detects collisions with certain layers (groundLayer)
b. If the ray hits anything (so it much be a ground object right below you), return true. Otherwise return false.
3. In the Update() method, check if two things happen at the same time:
a. The player hits the "Jump" button ... AND ...
b. The player is on the ground (IsGrounded() returns true)
Step 3 - Test It, Tweak It, and Get the Feel Right
As with anything, playtest this and iterate on it to get the feel right.
- To jump, remember that you can change the mode of the force to be all at once in a single burst instead of a steady push over time.
instead of the normal: rbody.AddForce(Vector3.Up * strength);
add a second parameter: rbody.AddForce(Vector3.Up * strength, ForceMode2D.Impulse);