2.5D Platformer: Wall Jumping
Do not fret, I know how to make a player wall jump!
So I wouldn’t have thought that using hit.normal
would make wall jumping quite simple!
While using Unity’s CharacterController for the player movement, we have the option to use OnControllerColliderHit(ControllerColliderHit hit)
which makes it easier for us to grab data when the player’s collider hits another.
This method is called when the character controller hits a collider while moving.
In the player class, I added:
OnControllerColliderHit(ControllerColliderHit hit)
{
Debug.DrawRay(hit.point, hit.normal, Color.red);
}
I want to debug the hit point and the hit normal for when the player collides with another collider. This will give me valid information that it is working.
Hit-Point
Hit returns a RaycastHit and it stores data of the impact point in world space where the ray hit the collider.
Hit-Normal
Hit normal is the normal of the surface where the ray hit. This will reflect the hit point, causing the player to move in the other direction!
By knowing this information, I can create logic to wall jump with a simple bool and tagging walls where we want the player to wall jump.
If the player is not grounded and the hit point collider has a tag of “Wall”, then set the bool of _canWallJump
to true. Also before setting the bool, I want to reference the hit.normal
to a Vector3 variable so I can use it globally.
private void OnControllerColliderHit(ControllerColliderHit hit)
{
if(!_controller.isGrounded && hit.collider.CompareTag(“Wall”))
{
Debug.DrawRay(hit.point, hit.normal, Color.red);
_wallSurfaceNormal = hit.normal;
_canWallJump = true;
}
}
If the player is grounded, set _canWallJump
to false.
Else if the player is not grounded, I hit the jump key, and _canWallJump
is true, then set the _yVelocity
to equal the _jumpHeight
and set the Vector3 _wallSurfaceNormal
(which holds the hit reference) * the _speed
to its current position.
if (_controller.isGrounded == true)
{
_canWallJump = false;
_direction = new Vector3(horizontalInput, 0, 0);
_velocity = _direction * _speed; if (Input.GetKeyDown(KeyCode.Space))
{
_yVelocity = _jumpHeight;
_canDoubleJump = true;
}
}
else
{
if (Input.GetKeyDown(KeyCode.Space) && !_canWallJump)
{
if (_canDoubleJump == true)
{
_yVelocity += _jumpHeight;
_canDoubleJump = false;
}
} if(Input.GetKeyDown(KeyCode.Space) && _canWallJump)
{
_yVelocity = _jumpHeight;
_velocity = _wallSurfaceNormal * _speed;
} _yVelocity -= _gravity;
}
Now my player can wall jump when the hit.normal
detects a wall!
From this, I learned more about hit.point
and hit.normal
and how important they are for certain mechanics! If you need information about the player colliding another collider, hit.point
is your friend. How about if you need the player or some other game object to reflect the other direction upon hitting another collider? Use hit.normal
! This could be used when a car collides with another car for example.
Gabriel