7. Collisions – Beginning Unreal Game Development: Foundation for Simple to Complex Games Using Unreal Engine 4

© David Nixon 2020
David NixonBeginning Unreal Game Developmenthttps://doi.org/10.1007/978-1-4842-5639-8_7

7. Collisions

David Nixon
(1)
West Palm Beach, FL, USA
 
Collisions are an integral part of game development. In this chapter, you will learn how Unreal Engine handles collisions and how to apply that knowledge. First, you will get a high-level technical overview of collisions and the various collision settings available in UE4. Then, you will be shown an example to demonstrate how these settings work. Finally, you will be shown how collisions can be applied in a real-world example, where colliding with an enemy causes damage to the player.

Collisions Overview

In the Details Panel, under the Collision category, you can edit the Collision properties of an Actor.

Hit Events and Overlap Events

If two Actors are set to block one another when they come into contact, then, when they collide, they will impede each other’s movement, and a Hit Event will be generated if Hit Events are enabled for that Actor.
To enable Hit Events for an Actor, check the Simulation Generates Hit Events checkbox under the Collision category, as shown in Figure 7-1. For an Actor’s Hit Event to fire, only the Simulation Generates Hit Events checkbox for that Actor needs to be checked. The other Actor’s checkbox only needs to be checked if you want that Actor’s Hit Event to fire as well.
Figure 7-1
To enable Hit Events for an Actor, check the Simulation Generates Hit Events checkbox
On the other hand, if two Actors are set to overlap with one another, then, when they collide, they will not impede each other’s movement and will overlap with one another instead. This will generate an Overlap Event if Overlap Events are enabled for both of the Actors.
To enable Overlap Events for an Actor, check the Generate Overlap Events checkbox under the Collision category. Again, for an Actor’s Overlap Event to fire, both the Actors involved in the collision must have Generate Overlap Events checked.
Hit Events and Overlap Events can be used like any other Event Node and thus can be used to define what should happen when a collision occurs.

Collision Presets

When you expand the menu under the Collision Presets property, you will find a long list of collision properties that can be automatically set by choosing from a list of presets. Or they can be individually set by choosing “Custom” and setting them one by one.

Collision Enabled Property

The Collision Enabled property is another way to set the block and/or overlap behaviors of the Actor (Figure 7-2). This has four possible settings. When this is set to Collision Enabled, it means that the Actor is enabled for both Query Collisions and Physics Collisions. Query Collisions just refer to overlap collisions and Physics Collisions refer to blocking collisions.
Figure 7-2
The Collision Enabled property
With Collision Enabled set to Physics Only, the Actor will be able to block other Actors, and fire Hit Events, but it won’t be able to fire Overlap Events. If it is set to Query Only, the Actor will be able to fire Overlap Events but won’t be able to block other Actors and won’t be able to fire Hit Events. If it is set to No Collision, the Actor won’t be able to block other Actors and won’t be able to fire Overlap Events or Hit Events.

Object Type Property

If the Actor is a Pawn or a Pawn sub-type, such as a Character, you would set the Object Type (Figure 7-3) to Pawn. If the Actor is a Vehicle, you would set the Object Type to Vehicle. If the Actor is a Destructible Mesh, a topic that hasn’t been covered, you would set it to Destructible.
Figure 7-3
The Object Type property and Collision Responses
For all other Actors, if the Actor doesn’t move, you would set the Object Type to WorldStatic. If the Actor does move, you would set it to either WorldDynamic or PhysicsBody. You would use WorldDynamic for Actors that move due to an animation or a Blueprint script and PhysicsBody for Actors that will move due to physics, such as gravity or the force of another object.
The Object Type doesn’t do anything itself inherently. Its purpose is simply to be able to place each Actor into a specific group, so that you can use the section below it to specify how the different types should interact with each other when they collide.
This section has a row for each of the six Object Types. Each row is used to specify the behavior that should occur when the Actor collides with the Object Type of that row. You can set each row to either Ignore, Overlap, or Block. The first row of checkboxes, labeled Collision Responses, can be used as a “select all” for each column. For example, if you click the Overlap checkbox, it will check the Overlap box in every row.
So if you wanted blocking and Hit Events to occur when the Actor collides with an Actor of the type WorldDynamic, you would check the Block column of the WorldDynamic row. If you wanted the two Actors to overlap and to generate Overlap Events, you would check the box in the Overlap column instead. If you wanted the two Actors to overlap, but not generate any Overlap Events, you would check the Ignore checkbox.
Note that the behavior that will actually occur depends on the preceding settings for both the Actors involved in the collision. For example, both Actors must be set to block the other’s type in order for blocking to actually occur and for Hit Events to fire. Similarly, if one of the Actors is set to Ignore the other, then Overlap Events won’t fire even if the other Actor is set to Overlap.

Trace Responses

The Trace Responses section is used to determine the Actor’s visibility to other Actors. If the Actor doing the looking is a camera, you would use the Camera row, and for all other Actor types, you would use the Visibility row.
If the Actor is set to Ignore, it will be invisible to other Actors. If it is set to Overlap, it can be seen by other Actors, but it can also be seen through. So you would use this for a glass wall, for example. If it is set to Block, then it can be seen, but it cannot be seen through. So you might use this for a brick wall, for example.

Collision Preset Property

Again, if you want to be able to set the preceding properties manually, you need to set the Collision Preset to Custom. But you can also use the dropdown to select from a long list of presets. Each preset will automatically select some combination of the properties.
For example, with BlockAll as the preset, it will automatically set the Collision Enabled property to Collision Enabled, it will set the Object Type to WorldStatic, and it will set all of the responses to Block. If OverlapAll is selected, it will set Collision Enabled to Query Only, it will set the Object Type to WorldStatic, and it will set all of the responses to Overlap. If OverlapAllDynamic is selected, it will choose the same settings as OverlapAll, except it will set the Object Type to WorldDynamic.

Can Character Step Up On Property

The Can Character Step Up On property (Figure 7-4) is used to specify whether or not a Character will step onto the top of the Actor when it walks into it or if it will block the Character’s movement. This is assuming that the two Actors’ Object Types are set to Block one another. Otherwise, this property doesn’t apply. Also, at very small heights, a Character will step onto an Actor when it walks into it regardless of what this property is set to.
Figure 7-4
The Can Character Step Up On property
So if the Actor is tall enough, with Can Character Step Up On set to No, if a Character walks into the Actor, it will block the Character’s movement. But if it is set to Yes, when a Character walks into the Actor, it will step onto the Actor instead.
If Can Character Step Up On is set to (Owner), then the Actor will use the same setting as its parent. If it doesn’t have a parent, then setting this to (Owner) is the same as setting it to Yes.

Block vs. Overlap Example

The interaction between Object Types, Collision Responses, Hit Events, and Overlap Events that was covered in the previous section can be confusing, so let’s take a look at an example. Imagine there is a cube mesh resting on the ground and that a sphere mesh, that has Simulate Physics and Enable Gravity checked, is placed above the cube, as shown in Figure 7-5. When the Level starts, the sphere will fall, and whether the cube blocks its movement or not will depend on the collision settings of the two Actors.
Figure 7-5
Whether the cube will block the sphere or not depends on the two Actors’ collision settings
So now, imagine the sphere’s Object Type is set to PhysicsBody and its WorldStatic Collision Response is set to Block (Figure 7-6). Also imagine that the cube’s Object Type is set to WorldStatic and its PhysicsBody Collision Response is set to Block (Figure 7-7). With these Actors set to block each other’s type, when the Level begins, and the sphere falls, its movement will be blocked by the cube, and it will come to rest on top of it, as shown in Figure 7-8.
Figure 7-6
The collision settings of the sphere
Figure 7-7
The collision settings of the cube
Figure 7-8
The cube will block the sphere’s movement because both Actors are set to block one another
Also, because these Actors block one another, this will cause any Hit Events to fire at the moment that the two objects collide. Imagine that the cube has its Simulation Generates Hit Events property checked. Also, imagine that the cube is an instance of a Blueprint and that it has the nodes shown in Figure 7-9 in its Event Graph. The Event Hit Node, which will be covered in detail later in the chapter, will fire anytime the Actor has a blocking collision with another Actor. In this case, when the sphere collides with the cube, it will print the word “Hello” to the screen, and it will actually print it several times as the sphere bounces on top of the cube before coming to rest (Figure 7-10).
Figure 7-9
When the Event Hit Node fires, the word “Hello” will be printed to the screen
Figure 7-10
The word “Hello” is printed to the screen multiple times as the sphere bounces on the cube and causes multiple collisions to occur
Now imagine that the cube’s PhysicsBody Collision Response is set to Overlap (Figure 7-11). When the Level begins, the sphere will now fall right through the cube, as shown in Figure 7-12, even though the sphere is still set to block WorldStatic objects. Again, this is because both Actors must be set to block one another for blocking to occur. Also, because an overlapping collision occurred, and not a blocking collision, the Event Hit Node won’t fire, and the word “Hello” won’t be printed to the screen.
Figure 7-11
The PhysicsBody Collision Response of the cube is now set to Overlap instead of Block
Figure 7-12
The two Actors now overlap with each other instead of blocking each other
Now let’s say that, instead of an Event Hit Node in its Blueprint, the cube had an Event ActorBeginOverlap node in its place (Figure 7-13). Also, assume that Generate Overlap Events is checked for both the cube and the sphere. Now when the sphere falls through the cube, the word “Hello” will be printed to the screen as soon as the two Actors first overlap with one another (Figure 7-14).
Figure 7-13
The same logic as before but with an Event ActorBeginOverlap node instead of an Event Hit Node
Figure 7-14
The word “Hello” is printed to the screen as soon as the overlap collision occurs
Finally, imagine that the sphere’s WorldStatic Collision Response was now set to Ignore (Figure 7-15). In this case, the sphere will fall through the cube just like before, but this time, the word “Hello” won’t be printed to the screen. This is because if either Actor is set to ignore the other, no collision events will occur.
Figure 7-15
The sphere’s WorldStatic Collision Response is now set to Ignore instead of Block

Causing Damage Due to Collisions

This section will demonstrate a practical use for collisions by showing you how you could deduct health from a Character when it collides with an enemy or some harmful object. Before we get to the example, however, let’s learn about a couple of nodes in detail – the Event Hit Node, which we saw earlier, and the Apply Damage Node.

Event Hit Node

An Event Hit Node , inside an Actor’s Blueprint, will fire any time that Actor registers a Hit Event. The Node contains several output pins, as you can see in Figure 7-16.
Figure 7-16
The Event Hit Node
The My Comp pin will return which Component of this Actor was hit. The Other pin will return the other Actor that collided with this Actor. The Other Comp pin will return the Component of the other Actor that was hit.
The Self Moved pin is a Boolean that will tell you if the collision was directly caused by the player. If the player collides with the Actor, or if a projectile fired from the player collides with the Actor, this will return False. For any other collisions, this will return True.
The Hit Location pin is a Vector value that will return the X, Y, and Z coordinates of the location where the hit occurred. The Hit Normal pin is a Vector value that will return the direction of the impact. So it will return the angles relative to the X, Y, and Z axes. The Normal Impulse pin will return how much force the impact had in the X, Y, and Z directions.
The Hit pin contains even more data about the collision. If you drag off the pin and select “Break Hit Result,” it will create a Break Hit Result Node containing many more details about the collision should you need to access that information (Figure 7-17).
Figure 7-17
The Break Hit Result Node

Apply Damage Node

The Apply Damage Node (Figure 7-18) will activate a Damage Event for whatever Actor is passed into its Damaged Actor pin. The Apply Damage Node will also pass the data from its other pins to the Damage Event. It is then up to the Actor receiving the Damage to define in its Blueprint how it should handle that incoming information.
Figure 7-18
The Apply Damage Node
The Base Damage pin is used to specify how much Damage should be applied. So you would specify higher Base Damages for Actors that should be more powerful or harmful. Note that this value is arbitrary until you give it some meaning with further logic.
Imagine that the Damage is supposed to be the result of a Character firing a projectile and hitting an Actor with that projectile. In that situation, the Character who fired the projectile would be considered the Event Instigator, and the projectile itself would be considered the Damage Causer. So if you needed to pass that information into the Damage Event, you would use those pins.
Using a Damage Type Class is optional, but if you want, you could create Blueprints that specify different types of Damage and then use this pin to specify which type of Damage this is supposed to be.

Damage Example

In this example, we will use a Cube Mesh to represent an enemy or some sort of object that would cause harm upon contact. The cube’s Simulation Generates Hit Events property has been checked, and it is set to block all other Actor types.
The cube has been converted into a Blueprint Class by clicking the blue “Blueprint/Add Script” button in the Details Panel. In the cube’s Blueprint, an Event Hit Node has been added that will cause an Apply Damage Node to fire, as seen in Figure 7-19. The Other pin of the Event Hit Node has been connected to the Damaged Actor pin of the Apply Damage Node, meaning that whatever Actor collides with the cube will register a Damage Event.
Figure 7-19
The logic in this Cube’s Blueprint will cause Damage to be applied to any Actor that collides with it
In the Character Blueprint, a Float variable named “Health” has been added and given a default value of 100. An Event AnyDamage Node has been added that will fire any time the Character registers a Damage Event. The Event AnyDamage Node will trigger a Set Node that will set the Health variable to whatever its current value is minus the amount of Damage received in the Damage Event. This calculation is performed by a Float Minus Float Node. See Figure 7-20.
Figure 7-20
When this Character takes Damage, the value of that Damage will be subtracted from the Character’s Health variable
After the new value of the Health variable is set, a Print String Node will print this value to the screen so the player can see how much health the Character has remaining. When connecting the pin containing the value of the variable to the In String pin, a Node was automatically created in between to convert the data from a Float to a String.
However, there is still a slight problem with this example. If the Character runs into the cube even for a half-second and the game is running at 30 frames per second, that means that the Event Hit Node is going to fire 15 times, because that is the number of frames of gameplay that is occurring during that half-second. With the current logic, this will cause the Character to get health deducted 15 times.

Making a Character Temporarily Invincible

The solution is to make your Character temporarily invincible after every time they receive Damage. You’ve probably noticed in several games that when your Character takes damage, there is a split second where they are immune to additional damage. This is to get around this problem of the game registering multiple collisions for what you and I would think of as just a single collision.
This can be accomplished by using a DoOnce Node and a Delay Node, as shown in Figure 7-21.
Figure 7-21
This will make the Character invincible for a half-second after it takes Damage
Now when the Character takes Damage, after it deducts the Damage from the health and prints the health to the screen, there will be a half-second delay during which the DoOnce Node will be closed. Any Damage Events that fire during that half-second will be blocked by the closed DoOnce Node. Then, after the half-second has expired, the DoOnce Node will get reset, and Damage Events will once again affect the Character.

Destroying a Character

The logic shown in Figure 7-22 can be added to the preceding example to destroy the Character once the Character's Health reaches zero.
Figure 7-22
This logic will destroy the Character when its Health reaches zero
Instead of going straight to the Print String Node after setting the new Health value, the Blueprint will first check to see if the Health has reached zero yet. It does this by using a Float Less-Than-Or-Equal-To Float Node that will look at the Float value in its first input pin and tell you if that value is less than or equal to the Float value in its second input pin.
If the Health variable is less than or equal to zero, the Branch Node will route execution to a DestroyActor Node which will destroy the Actor in its Target pin. Otherwise, the Branch Node will route execution to the Print String Node as before.

Summary

In this chapter, you learned about collisions in Unreal Engine, how to work with them, and how to configure various collision settings. In the next chapter, you will learn how to use the UMG Editor to create menus, HUDs, and other user interfaces for your game.