Using CapsuleCast for collision detection

Planning
Step 1
Introduction

In the next lesson, you will be asked to create a function which detects if there is ground beneath the player's feet.
To do this you will need an understanding of Unity's CapsuleCast function.

Temp1468193357

This lesson will be a tutorial of using Unity's Raycast system to prevent the player from sticking to walls.

The material covered can be a bit dense, and you arent expected to understand everything right away but it is something you will come across again and again

Planning
Step 2
Before we begin

Tag all of your wall and ground GameObjects with a new tag called "Wall"

This will become necessary later

Temp1468210789
Planning
Step 3
The problem we are solving in this lesson

We controlling Rigidbody physics for a GameObject, you will come across a problem where as long as the Player is moving into a wall, it sticks there.

Example:

We will be learning to solve this problem using CapsuleCast

Fixed:

Planning
Step 4
First we create a visualization of what we are going to build

The idea here is that before we move somewhere we must first check to make sure that area does not have a wall in it.

Temp1468194084

If there is a wall there, then we shouldn't let the player move in that direction

Temp1468194509
Step 5
Create a bool type function called CanMove()

Let's make a function right now called CanMove which takes a Vector3 named "direction" and checks if the player can move in that direction.

Temp1468194604

Note that this function is a bool type.

It will return true if we can move in the specified direction, otherwise it will return false if there's a wall in that direction.

Information
Step 6
To check if the player can fit in the area they are trying to move in, we will use Unity's Casting system.
Temp1468194823

Since our player is shaped like a capsule, we'll use a capsule shaped Cast.

Information
Step 7

Casts have the ability to tell us what Colliders they are touching. This data is stored as RaycastHits.

Temp1468195119

...and we are able to check every RaycastHit the Cast creates and see if any of the GameObjects are tagged as walls.

Information
Step 8
Since we can have multiple RaycastHits we need to create an array of type RaycastHit
Temp1468195502

We'll call this array "hits"

Step 9
This array is going to get the RaycastHit data from a CapsuleCast. So let's start
Temp1468195664

CapsuleCastAll lets us check all of the RaycastHits we find, instead of just the first thing

Planning
Step 10
Now we need to define the shape of our cast.

We want this CapsuleCast to be the same size and shape as our Player's CapsuleCollider

Temp1468196141

We therefore need to pull data from our CapsuleCollider, and to do that we need to create a reference to it.

Step 11
Create a reference to the Player's CapsuleCollider
Temp1468196272

We now can refer to the player's CapsuleCollider as col

Information
Step 12
What can we do with CapsuleCollider references

Here is the documentation page for a capsuleCollider, which tells us what information we can get about our capsule.

Temp1468199161

This means we can call:
col.center
col.radius
col.height
...

Planning
Step 13
Now we must figure out what we need to make a CapsuleCast

Here is the documentation page for CapsuleCastAll which tells us we need to define these points

Temp1468199776

It also tells us that this function will return an array of type RaycastHit

Step 14
Finding points 1 and 2.

We need to tell our CapsuleCast the coordinates of point1 and point2

Take some time to look at this diagram showing that data we do know, and see if you can figure out the distance from the center of the cast to point1

Temp1468202307

Try to figure it out on your own first, the answer will be in the next step

Step 15
Solution

The distance from the center to point1 is half the height, minus the radius

Temp1468202662

Let's calculate and store this distance in our code like this:

Temp1468203005
Step 16
Now calculate point1 and point2's locations
Temp1468202967

We scale an upwards Vector3 so that it's as long as distanceToPoints.
To get point1 we add it to the center
To get point2 we subtract from the center

Step 17
Now calculate the radius

The radius of our CapsuleCast should be the same size as our CapsuleCollider.

Except we want it to be just a bit smaller, otherwise it will touch the ground and register that as hitting a wall

Temp1468203280

We multiply the radius by something like 0.95 just to make our cast a little smaller

Step 18
Lastly we need to set the cast distance

The images in this lesson have been exaggerating the cast distance for clarity.

Temp1468203468

Really we want a really small cast distance like this

Temp1468203532

So let's set our castDistance variable to something small, say 0.5

Temp1468203625
Step 19
We need to make point1 and point2 relative to the player

Adding transform.position makes the points relative to the player rather than to the world.

Temp1468437355
Step 20
Now we can fill in our CapsuleCast call
Temp1468437571
Information
Step 21
What about dir?

Notice we haven't told our CapsuleCast which direction to extend out in.

We are going to want to use this function for multiple different directions, so we will have to define dir as a parameter when the function is called

Temp1468437932

For example we might say

if CanMove(forward * 5f) 
{

}

which would set the parameter dir to the Vector3: forward * 5f

Step 22
Now we must check if the CapsuleCast has found a wall

We've sent out a CapsuleCast and it has returned with information of every Collider it found.

Those are now stored in a RaycastHit[] array called hits

Temp1468204801

We're going to use a foreach loop to check each object. That looks like this

foreach (RaycastHit objectHit in hits) {
  if (objectHit.transform.tag == "Wall") {
    return false;
  }
}
Step 23

We're going to use a foreach loop to check each object. Which looks like this

Temp1468205356

This can be read in English as:

For each RaycastHit (which we will call objectHit) in the array "hits"..
if it's tag is "Wall"
end the CanMove function and return "false"

Temp1468205111

So objectHit is a reference to whichever RaycastHit we are looking at. We only look at one at a time

Step 24
If no walls are found return true
Temp1468205617

If we look at each object in the hits array, and none of them are walls. Then we can end the function and return true

Step 25
We're done with the CanMove function

Now all we have to do is edit our Update function.

Here our movement inputs both start at 0 and we only set them to a value if we can move in that direction

Temp1468207609
Planning
Step 26
In the next lesson

This lesson was intended to be a tutorial on making and using CapsuleCasts

In the next lesson you will be on your own a bit. You will be asked to create a function which checks if the player is standing on the ground

Temp1468208136

You'll be using this function so that the player can jump if and only if they are standing on the ground

Try one of these lessons next:

Using CapsuleCast for collision detection Info

Account

MVCode Clubs

Created By

Newprofile jamie

Course:

First Person Exploration

Access Level

public

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