Hitboxes and Hurtboxes in Unity

May 14, 2018
protect

Hitboxes and Hurtboxes in Unity


Explanation

So what are hitboxes and hurtboxes anyway? Aren’t they the same thing?

Well... The answer can differ depending on who you ask, but here we will abide to the notion that hitboxes and hurtboxes are two different things and have different uses, as any fighting game worth mentioning does.

Hitbox is an invisible box (or sphere) that determines where an attack hits.

Hurtbox on the other side is also an invisible box (or sphere), but it determines where a player or object can be hit by a Hitbox.

 

In this image from SFIV, the red box is the hitbox and the green one the hurtbox

 

It’s worth mentioning that the size and position of both hitboxes and hurtboxes change depending on the frame of animation that is playing:

 

Gif from Killer Instinct. Look how the hitboxes only appear on hitting frames and move with the sword

 

In the Killer Instinct example we can also see a third type of box, the Pushbox (the yellow one, the Hurtbox is the empty green box). A Pushbox is a box that represents the physical occupied space by a character, and keeps characters from overlapping.

In most fighting games or brawlers there’s two other types of boxes that for simplicity we will not cover:

The grab or throw box, that determines where a character can be grabbed or thrown, and the block box that determines where an attacked player that’s pressing the back button will start blocking a certain attack instead of walking backwards.

 

All these boxes are really important from a design point of view. Hitboxes and Hurtboxes of an attack determine not only how many frames an attack hits but also the blind spots of that attack and how vulnerable it leaves the player.

For a great explanation on this focused on Street Fighter check this video

 

So now that we have our terminology straight, let’s start working.


What we want

Let’s check every type of box we’ll cover and see what we want from them:

 

Pushbox: We need for two pushboxes to collide with each other and not overlap (that’s why it’s called a pushbox, it pushes the other character). Pushboxes should only interact with other pushboxes.

Hurtbox: It can register a hit, but it should not collide in the physical sense. Hurtboxes should only interact with Hitboxes.

Hitbox: It should be able to check if it’s overlapping a Hurtbox in arbitrary frames. It should only interact with Hurtboxes.


Using Unity default components

The first approach one could do is map every kind of box that we talked about to a Unity default component. The obvious choice is some type of Collider.

The Pushbox can be directly mapped to a Collider plus a Rigidbody. That behaves exactly as we want it, it collides with things and doesn’t overlap.

The only part we need to worry about (besides setting our Rigidbody as we want it) is the part about only colliding with other Pushboxes. If you’re familiar with Unity physics system, you already know that the solution is to use Layers and the Layer Collision Matrix. For clarity we can create a layer called Pushbox, assign it to our object and set the collision matrix so Pushbox only collides with Pushbox.

 

 

 

 

For Hurtboxes we can use a Collider using isTrigger. This ensures that it won’t collide in a physical sense and will only register other colliders entering it’s area. For actually registering the hit we will need to add a script in the same object that implements OnTriggerEnter, probably check the tag of the incoming collider to check that the one that triggered the event is the one we want and then do whatever damage and health calculations our game needs. You are probably familiar with this approach.

We also need to create the layers Hurtbox and Hitbox, and use the Layer Collision Matrix again to make Hurtbox only collide with Hitbox and vice versa.

 

  • Note that we don’t need a Rigidbody, but only because I’m assuming that every trigger we will add is a child object of the Pushbox object that already has a Rigidbody. This is important because Colliders without a Rigidbody in itself or some of its parents will be set as Static by Unity and moving them will be really inefficient.

  • Also, we will probably need to distinguish between a Hitbox from the player or one from the enemies. The same goes for Hurtboxes. This way we can make the Hitbox from the player only hit the Hurtbox from the enemies, and the Hitboxes of the enemies only hit the Hurtboxes of the player. You don’t need this if you want to allow friendly fire, but you gotta be careful to avoid a player hitting its own Hurtbox.

 

Hitboxes are maybe the least clear in how we should implement them. What we can use is a Collider using isTrigger to avoid a physical collision, but there are really no colliders that “enter” a Hitbox. Actually is the other way around: A Hitbox “enters” (or checks if it’s overlapping) a Hurtbox. Nevertheless, we need a Collider or Unity will never call OnTriggerEnter in our Hurtbox.

For dealing damage to the Hurtbox we will need to add a script in the same object, so that our Hurtbox can use GetComponent<T> and get it to know how much damage needs to be dealt. You can also do it the other way around, OnTriggerEnter gets called for both Colliders. We also need a way to make our Hitbox active only when we want to and not in every frame or when the character is not attacking for example. For this we can’t just disable our script because as the documentation says: “Trigger events will be sent to disabled MonoBehaviours, to allow enabling Behaviours in response to collisions”.

What we can do is enable and disable the collider, or add a boolean property to our script that handles if it should hit or not.

 

Problems

  • Hierarchy: we need to have a script in every object with a Collider to be able to respond to OnTriggerEnter. If you like to have your scripts in the same place for organizational reasons, you will need to create a script just to delegate the call to your other object. 

  • Overhead: With this approach our Hitboxes have a lot of functionality we don’t need. 

  • Events: We rely on OnTriggerEnter for our functionality. Using Unity events may not be a problem, but there’s reasons to at least think if we should. You can also check this (in the section“Avoiding expensive calls to the Unity API”) to know more.

  • Visuals: If you want to use different Hitboxes for different attacks, not only will the aforementioned problems repeat a lot, but you will have a lot of visual clutter on your editor window.

JikGuard.com, a high-tech security service provider focusing on game protection and anti-cheat, is committed to helping game companies solve the problem of cheats and hacks, and providing deeply integrated encryption protection solutions for games.

Read More>>