CTIN 483
Week 5 Tuesday
Today
-
Smarter collisions (review)
-
Layers
-
Raycasting
-
Visualizing raycasts
Smarter Collisions
Smarter Collisions
Here are three ways to decide what the other object is, in a collision:
- What is its name?
- What is its tag?
- Does it have a certain script attached?
Note that there are many others.
if (collision.gameObject.name == "Goomba") { Die(); }
- likely to break because people change GO names a lot
- level designers work quickly, make copies of GOs with names like "Goomba (1)"
- easy
Pros:
Cons:
- one tag per GO, but a GO might belong to multiple groups
- difficult to wrangle more than a couple dozen tags
- easy
Pros:
Cons:
if (collision.gameObject.tag == "Goomba") { Die(); }
Another way to know whether some GO is the kind of GO you care about: ask for its script components.
collision.gameObject.GetComponent<Goomba>()
If the other GO has a Goomba script attached, you can assume it's a Goomba.
collision.gameObject.GetComponent<Goomba>()
If the other GO has a Goomba component, this will get you a reference to it.
If the other GO does not have a Goomba component, this will return the special value null, which is nothingness.
So to determine whether the other GO has the script, you ask if the result is not null.
Not-nothing is something. So it must be a Goomba.
Goomba potentialGoomba =
collision.gameObject.GetComponent<Goomba>();
if (potentialGoomba != null) { Die(); }
- a little annoying to set up
- sometimes GOs don't really need scripts and it's awkward to add them just for this
- reliable
- tells you what you probably really want to know, which is how the other object acts
- now you have a reference to the other script
Pros:
Cons:
if (potentialGoomba != null) { Die(); }
Even Smarter Collisions
with Layers
Stretch Break
Raycasting
is useful
Raycasting is drawing an invisible line (the "ray") out into the game world to see what game objects are in that direction.
?
You can use raycasting to answer questions like:
- Where will the player's grappling hook hit the ceiling?
- Can that guard see the player character?
- Is Mario standing on solid ground?
- Is the mouse over that object?
Where will the grappling hook hit the ceiling?

Can that guard see the player character?

Can that guard see the player character?

Sometimes it's not enough to know whether two objects are colliding.
For example, Mario can only jump when he is standing on something.


Is Mario standing on solid ground?
You could use collisions to
answer this. But...



Is Mario standing on solid ground?



You could draw a ray
down from his center and
see whether it hits
something.
But...


In old 2D platformers like Mario, having even a small part of the character over solid ground is enough.


So you'd do something like this, with two raycasts.
If either of the raycasts
hits solid ground, then
Mario doesn't fall.


The mouse doesn't exist in the game world. It's just a position on a 2D screen.
Image source: Sha Qian via Noteworthy

So you convert the mouse's screen position into a world position. Then you send a ray forward into the game world to see what it hits.

The syntax (what you have to type) is annoying.
And you can't see a raycast so it can be hard to know if you're doing it right.
But it's a key tool.
Stretch Break
Raycast Syntax (2D)
RaycastHit2D hit2D = Physics2D.Raycast( startOfRay, direction, distance );
This is the basic form of the 2D raycast function:
The 2D raycast function needs at least three pieces of information:
- where to start the ray
This is a point, so a
- which direction it goes
A direction, so a
- how far the ray should go
A length, so a
Vector3
Vector3
float
- Returns a RaycastHit2D, which is a package of information about what happened with the raycast. Here's the documentation.
- Very similar to a Collision object
This is how you can get to the GameObject that the ray hit:
hit2D.collider.gameObject
Then you can ask that other GO for its components, tag, and so on:
GameObject otherGO = hit2D.collider.gameObject;
otherGO.GetComponent<SpriteRenderer>()
otherGO.gameObject.tag
otherGO.SetActive(false)
- Returns a RaycastHit2D, which is a package of information about what happened with the raycast. Here's the documentation.
- Very similar to a Collision object
The RaycastHit2D itself will never be null. So you might think you can do something like this:
Beware
if (hit2D != null) { print (hit2D.collider.name); }
But this code will always run, whether or not the raycast actually hit something.
!
!
To find out if the ray hit something:
if (hit2D.collider != null) {
print (hit2D.collider.name);
}
Beware
By default, the raycast will hit the same GameObject that is casting the ray. You can fix this:
- by starting the ray outside of the GameObject's collider
- or by setting up a layer mask.
[SerializeField] LayerMask layerMask;
This will show a dropdown in the Inspector. The raycast will hit the layers with checks.

RaycastHit2D hit2D = Physics2D.Raycast( startPosition, direction, distance, layerMask );
[SerializeField] LayerMask layerMask;
RaycastHit2D hit2D = Physics2D.Raycast( startOfRay, direction, distance );
RaycastHit2D hit2D = Physics2D.Raycast( transform.position, directionToPlayer, playerCheckDistance );



RaycastHit2D hit2D = Physics2D.Raycast( transform.position, Vector2.down, groundCheckDistance );

Stretch Break
Raycast Syntax (3D)
RaycastHit raycastHit;
Physics.Raycast(
startOfRay,
direction,
out raycastHit
);
This is the basic form of the 3D raycast function:
This function needs at least three pieces of information:
- where to start the ray
This is a point, so a
- which direction it goes
A direction, so a
- an out parameter to hold the result
This is a
Vector3
Vector3
RaycastHit
???
Unity wrote this raycast function to use something called an out parameter. You don't need to understand anything about the why or how.
To use it:
- Declare a RaycastHit variable.
- For the third parameter of Physics.Raycast, type the word "out" and then your variable name.
This is how you can get to the GameObject that the ray hit, just like with the 2D function:
raycastHit.collider.gameObject
Stretch Break
Visualizing Raycasts
It can be hard to set up raycasting correctly because the ray is invisible.
You can't directly make the ray visible, but you can draw a line where the ray is using Debug.DrawRay.
It is almost the same as the raycast function...but slightly different.
Debug.DrawRay( startPosition, directionAndDistance, color );
Vector3 dirToPlayer = player.transform.position - transform.position; Debug.DrawRay( transform.position, dirToPlayer, Color.red );
But dirToPlayer is a vector that points directly to the player. If you want to look in the player's direction, but only a certain distance, you will normalize the vector.
Stretch Break
CTIN 483 - W5 Tu Sep 21 - 2021 Fall
By Margaret Moser
CTIN 483 - W5 Tu Sep 21 - 2021 Fall
Smarter collisions. Layers. Raycasting.
- 279