Adding Exploding Barrels to Our Prototype in Unity 2021
In this article we’ll extend our damage system to specific game objects that will explode.
I’ll be using the Propane Tank asset from GameDevHQ because it fits my scenario perfectly.
If you don’t have access to GameDevHQ’s Filebase asset system, you can either substitute with primitive game objects or assets from elsewhere.
These should do nicely!
My Prefabs, Not Yours
Whenever possible, I like to unpack asset prefabs and recreate them as my own prefabs.
It never hurts to have the originals in your back pocket for later!
Before I create new prefabs for these game objects, I want to make any changes desired and add any components or scripts needed.
The original sizing for scale 1 on these game objects is a bit small for my scene.
After rescaling each game object individually, I’m pretty happy with the results.
We’ll need to create a new script for our explodable propane tanks and a separate script for the water barrel.
After creating the scripts, assign them to the appropriate game objects.
Now, I don’t want identical stats, animations, or damage to be inflicted for each propane tank.
I want these values and effects to vary by the size of the propane tank game object.
To use the same script while differentiating the game objects the script is attached to, we simply add a class variable that will identify the game object.
Using an Enum is a great solution for this task and leads to very readable code related to these values.
It’s a lot easier to look at months-old code with sizes described by words rather than associated with a particular value of an array.
Additionally, the Unity Editor Inspector gives us a nice dropdown menu for use with Enums.
At this point, I’m ready to turn these game objects into prefabs.
I should have created some organizational folders for my prefabs before creating them.
Once we move the prefab to a new folder, it breaks the connection to existing game objects in the scene which is shown by highlighting those game objects in red text.
Unfortunately, there is only one solution I know of outside of a good utility script that will replace game objects with a prefab while transferring the game objects state information (transform position, rotation, scale, etc).
Drag the prefab into scene hierarchy, copy the original broken game object’s data, and delete the original game object.
If you do have access to GameDevHQ’s Filebase, you can use the Replace with Prefab asset to make this process easier and faster.
So much easier!
My Prefabs folder is looking much cleaner now.
Back on Task
After that slight detour, we can get back to making things explode!
Or at least, placing those explodable game objects into our scene…
I’ve added a new empty game object under the Environment empty game object for organizational purposes.
We want to try and place our explodable game objects in places that make playability sense, if not “realistic” sense.
I mean really, who leaves all these flammable tanks around on their stuff?
I’ve placed them near various cover waypoints the AI use when being shot at.
This will give the player an opportunity to damage the AI when they are out of view.
Because each tank will only be allowed to explode once before being removed from the scene, this won’t throw game balance out of whack.
Stick With What Works
I know an inanimate object can’t have health.
But I also know this approach will work.
You know what, scratch that.
I’m going to rename this to “durability”.
There, fine, the propane tanks don’t have health!
Different vocabulary, same methodology.
We’ll set a value for their heal…I mean, durability, and then we’ll decrement it until there is none left and that will trigger an event.
Except instead of falling to the ground with gurgling noises, we get a sweet explosion!
To make this Game Designer friendly, I’ll add variables for the default values of durability for each size.
A Game Designer can modify these in the Unity Editor without touching a line of code.
Of course, we shouldn’t rely on somebody else to assign these values though.
To make sure these values always have a valid value, I trick for a default value of 0 and assign them accordingly in the DoNullChecks() method which is called from the Start() method.
AssignDurability() method will complete this process of assigning the default values to the _durability value.
We make sure to call the AssignDurability() method after the DoNullChecks() method so that it has a chance to assign values if needed.
Lastly, for the time being, we add the TakeDamage() and Explode() methods.
For now, our explosion will just be a Debug.Log statement confirming the method was called.
Before I forget again, we should add colliders to our propane tanks for hit detection purposes.
Use a primitive type collider rather than a mesh collider to improve performance.
I’m not sure what is more performant, using CompareTag or checking the layer value so I’ve used both on each propane tank.
We’ll need a way to identify these when the player shoots them.
Back to the Player Script
We’ll use the same approach as we did for hitting the AI game objects from the Player script’s FireWeapon() method.
Now that we are up to more than an if and if/elf statement with potentially more tag comparisons to come, I’ve decided to convert this code to a switch statement.
Unfortunately, I think we lose the ability to use CompareTag() for the performance advantage that entails.
Since the propane tanks do not have a parent object with the correct script, I use hitTransform to call the Propane Tank script’s TakeDamage() method.
If we hit play and test this out, we can see the large propane tank is taking damage properly and when its durability reaches < 0, the console prints out the Explode Triggered debug line.
Animated Explosions Are Better Than Text Logs
I’ll use an asset from GameDevHQ, but there are plenty of free ones on the web if you need it.
I’ve thrown it in the scene temporarily just to see how the animation looks and just how big it will be compared to the scene and props.
It looks good, probably even the right size for the largest propane tank, but I’ll scale it down for the smaller propane tanks.
I’m going to create 3 prefabs from the original that will be used for each size of propane tank.
To get the feel right per object, I’ve thrown the original fireball prefab onto a large tank and observed the look.
Looks good to me!
With that decided, I can simply unpack the original prefab from the game object in the Hierarchy window, rename it, and create a new prefab.
With the fireball visual effects prefabs properly sized, I’ve added them to appropriate propane tank prefabs with a default state of disabled.
Triggering the Animation from the Propane Tank Script
We can trigger our animation to play simply by enabling its game object.
In the PropaneTank script we add a variable to hold it and assign it in the Start() method using GetChild() with an index of 0 since there is only one child game object.
Explode() and DelayHide() Methods
Now we can remove our Debug.Log statement placeholder for the explosion replace it with the real deal.
Since the Fireball game object is disabled by default and set to PlayOnAwake with loop disabled, we only need to enable the game object.
We also need to call a coroutine so that we can delay hiding (or destroying, your call) the propane tank game object.
After all, it just exploded…
And when we hit playmode and shoot up our tank, we can see that it is indeed working!
Now the animation could use some tweaking, but as far as coding mechanics go, we’re done for now.
Hope you enjoyed this article!