Unity: Detecting Collisions with onCollisionEnter
In this tutorial, we'll learn how to detect collisions between two gameObjects using a simple C# script, and how to execute some code when the objects collide.
We'll also learn how to work with game tags and why they're important, and we'll also learn how to use Unity's console to output customized messages that can come handy to us as developers and testers.
To get started, let's open up the project we've been working on so far:
Everything seems to be in order. Now, let's add a new 2D Box Collider to our bullet(fireball) so it can detect collisions (Remember, the Collider is what actually defines a collision, not a Rigidbody).
Want to see how to add a Collider to a game object? You will find it here.
Here's a quick question: If we want all generated bullets (fireballs) to have a box collider, what do we modify? The prefab of course. Attach a 2D box collider to the prefab, and that's about it for the bullet.
Now, let's give our main character something to shoot at. How about a target? We have one around here somewhere.
There we go. Let's import this target into our game project and into our scene (You should be fairly comfortable with adding new sprites to the scene by now).
Now, let's add a 2D circle collider to our target (Since it is, a circle, after all) as well as a Rigidbody2D
.
Now, let's go ahead and write some script to detect a collision between the bullet(fireball) and the target. Once again, copy down the below code, and we will explain what's going on in detail.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TargetBehaviour : MonoBehaviour
{
void onCollisionEnter2D(Collision2D col)
{
// When target is hit
if(col.gameObject.tag == "Bullet")
{
Debug.Log("Target was Hit!");
}
}
}
Remember, we said that the MonoBehaviour
class provides a lot of other default methods alongside start()
and update()
? Well, OnCollisionEnter2D()
(with parameter Collision2D
) is one such method. It's a method that is fired (called) by Unity whenever it detects a collision between the object to which this script is attached to, and any another gameObject.
Note the Collision2D col
parameter we provided. (Using the variable name as col
or coll
is quite popular amongst developers, when using this method). We haven't set or even instantiated any Collision2D
object/variable, how are we using it?
Collision2D
is a set of data about the collision that is generated during a collision, by Unity. It includes stuff like the gameObject that hit, the point where it hit (stored as a Point variable which is, in fact, a Vector3
) and so on. col
is simply the name we gave to this set of data for the collision.
Hence this method will be called upon whenever a collision is detected, and Unity will make sure that the argument col
(instance of Collision2D
) has all the required values stored in it. We just have to use them and operate on them.
Next, have a look at the condition in the if
statement.
(col.gameObject.tag == "Bullet")
What does this line mean? It simply means that the gameObject included in the col
data variable, that is, the gameObject that collided, should have a tag named Bullet in order for the if
statement to fire. Tags? What? Don't worry about tags just yet, we'll be getting to that very shortly.
What is Debug.Log
for?
The next line is quite important, since it's our magic line. The Debug
class is a class that contains tools which are very useful while you're developing your game, and even more when you're testing the code or any other components.
One of the methods included in Debug
class is the Log(string parameter)
method, which we are using in the above code. It simply prints a new message defined by the parameter to the console, whenever you call the method. Save this script, and attach it to the target. Remember to set the Gravity Scale to 0
in the editor, and additionally, you should freeze the X
and Y
coordinates in the constraints menu to prevent your target from flying off.
What are Game Tags?
Before running the game, let's work on tags. Tags are basically a way of identifying and grouping gameObjects together, for you and Unity. By default, gameObjects are untagged, that is, they have no tag on them. We can set tags and create our own, by clicking on the Tag option in the top of the gameObject (or prefab) Inspector:
Unity gives us a bunch of tags to use by default, and we can even add our own by clicking on Add Tag. Clicking on Add Tag takes us to this menu in the Inspector:
Click on the +
button, and you will get an input field for a new tag's name. Since we wrote our collision script to detect a collision with an object having the tag bullet, we'll give this new tag the name Bullet. Once you do that, simply open up your prefab and give it the Bullet tag which will now appear in your list.
If you run the game now, try firing at the target, and you should see something like this:
Have a look at the bottom left corner of Unity's window. You should see your message whenever your bullet hits the target. Of course, the way we have programmed the bullet to move, it will just touch the target and keep on moving forever. We'll fix that up ahead, so for now, we'll focus on what's really going on here.
- Our main character launches a bullet with the tag Bullet
- Once Unity detects a collision with the bullet with the tag name as Bullet, the
if
statement turns true
and the code it has, is executed.
- The code asks Unity to print
Target was hit!
to the console.
NOTE: This repeats every time you shoot the target.
If you want to see the full Console window, where you can also see scripting errors and warnings if Unity detects them, you can easily find it by clicking on the Console tab right above the Assets section.
Practice Exercise
- Try to make multiple targets, which print different messages when hit, to the Console. For example, Target 1 was hit!, Target 2 was hit! and so on. Feel free to explore more functions and components, although try to do these in a separate, fresh project so you know what's changing what in the game, as you explore.