Collision Detection

This is an excerpt chapter from my Weekend Code Project: Unity’s New 2D Workflow book. I hope you enjoy this free content on how to use Unity’s new 2D features. If you like what you see, please pick up a copy of the book to get access to the artwork, source code and a PDF/ePub version of the book.

The Layer Collision Matrix

When we talk about collision detection, we really tend to focus on two types: making things solid and detecting when two objects collide. We have already solved the first problem thanks to Unity’s built-in support for the Box2D physics engine. As far as we are concerned, everything in the game now knows how to collide with each other. The Player doesn’t fall through the floor, and it can collide with the Knights. The big issue we have now is being able to block the Player from moving off the screen, and what to do when he collides with a bad guy. To get started, let’s solve the bad guy issue first, because at this stage of the game, we can’t really move around with all the Knights spawning everywhere.

If you collide into too many Knights, you’ll see they kind of bunch up and form a line.

This happens because they are all colliding with each other and pushing the other ones back. We really don’t want this to happen; Knights shouldn’t collide with each other. We can quickly fix this by taking advantage of Unity’s built-in Layers and Tags.

If you open up the Knight prefab, there are two drop-down menus below the name field.

Let’s start with Tag. Click on the drop-down menu and select Add Tag.

From here we are going to create a few tags for our game. Make one for the Player and one for the BadGuys.

While we are in here, we should also create the layers we need too.

Now reselect the Knight prefab and set it to the BagGuys tag and layer.

Next we should set the Player to the Player tag and layer.

Remember that, since we are doing these in the prefab of each GameObject, it will also be set in any new or existing instances of it in our game Scene. Now we need to set up some collision relationships. Open the Physics 2D settings from the Project Settings menu under Edit.

You will now see the Layer Collision Matrix, among other settings, that represent the Physics 2D settings of your game. We are going to want to uncheck the BadGuys layer, which will disable them from colliding with each other.

Take note that the Player layer is still able to collide with the BadGuys layer. This is what will allow us to still test for collision between the Player and the Knights. Now save the project and we are going to start building the foundation for having the Player attack the Knights.

Making Things Attack

Before we can have each of our main GameObjects attack one other, we need to add the notion of health and what happens when it runs out. To do this we are going to build a simple health script for both of our GameObjects. To get started, go into our Scripts folder in the project window and create a new script called Health. 

It’s also a good time to organize your project. Make sure all of your scripts are in the Scripts folder in our project. You’ll notice that, over time when you add scripts to GameObjects in the Inspector panel, they are automatically put in the root of the Assets folder. You can easily find all the scripts in your project by clicking on the All Scripts Favorites filter. Simply drag the ones not in the correct folder over.

In the Health script we want to add the following properties:

public int maxHealth=10;
public int health=10;

This allows us to publicly define the maxHealth of the GameObject. In the Start method, add the following:

health=maxHealth;

Now when the script runs for the first time, it will automatically set the health property to the maxHealth. Next we need to add two more methods:

public void TakeDamage(int value)
{
 health -=value;
 if (health  transform.position.x)
 AttackTarget(target);
 }
 else
 {
 if (target.transform.position.x < transform.position.x)
 AttackTarget(target);
 }
}

Now, in this method, we are basically testing the direction the GameObject is facing and what side the colliding GameObject is on to make sure we can attack. If it’s valid, we call AttackTarget. At the end, we reset the canAttack flag to false. Now let’s add the AttackTarget method:

void AttackTarget(GameObject target)
{
 var healthComponent=target.GetComponent();
 if (healthComponent)
 healthComponent.TakeDamage(attackValue);
}

Here we test to make sure the target we want to attack has a healthComponent attached to it. If it does, we call TakeDamage and pass in the attackValue. Now all we need to do is add the last method, which is OnAttack:

IEnumerator OnAttack()
{
 yield return new WaitForSeconds(attackDelay);
 canAttack=true;
 StartCoroutine(OnAttack());
}

As you can see, this is what handles our attack delay. We simply use WaitForSeconds to determine when the next attack can happen and set the canAttack value to true. This means that when we have a collision, if the canAttack value is true, the GameObject will attack. After that, we restart the coroutine again.

Add this script to our Player prefab so he can attack the Knights. Before we run the game, we should make one minor modification to the script on the Player; we need to tell it what tag is valid to attack. In the Inspector panel, add BadGuys to the Target Tag field.

 

You can also see I made the Attack Value 5 and the Attack Delay to 0.2, so when I am testing, the Player will kill the bad guys quicker. Play the game and try to run into some Knights and you will see them disappear after a few hits.

Adding Boundaries

At this point, you may have noticed that it’s a lot easier to fall off the level. We can fix that quickly by adding some simple boundaries to keep the Player within the indented area. Create a new empty GameObject and add the Gizmo script to it. Call it LeftBoundary, give it a label, and add a Box Collider 2D component as well. Here you can see I moved mine to just above the LeftSpawnZone.

This will be just high enough that the Knights won’t hit it, but it will stop the Player. Duplicate it, call it RightBoundary, and put it just above the RightSpawnZone.

You may notice that the left and right boundaries abruptly stop the player. This doesn’t look all that great. You can add the GroundBounce Physics Martial 2D we created earlier to the boundary’s Box Collider 2D to give it a little more pushback when the player hits the edges of the screen.

Subscribe To My Mailing List

Want to learn how to make a game? Not sure where to start? Even if you are a seasoned game maker there is still a lot you can learn from my mailing list. I'll be covering tips and tricks for how to build, release and market games each month.

Simply sign up for my mailing list and also get access to a 50% off discount code for my eBooks and other content. I promise to not spam your inbox!

Join Now