VFX — Adding an exploding asteroid to start enemy waves
In today’s article, we’re going to implement an asteroid at the start of the scene that once destroyed will trigger the spawning of enemies and powerups.
We’ll give it a nice explosion animation as well.
We’ll start by creating our Asteroid game object.
Let’s set our Y position to 3.5 and select Foreground for the sorting layer.
Create a prefab for the Asteroid.
Let’s add some components. We need a CircleCollider2D and a Rigidbody2D.
Resize the collider as needed and set “Is Trigger” to true.
Set gravity scale on rigidbody to 0 so as not to utilize Unity’s built-in physics engine.
We know we’ll need to add some behavior code, so let’s create a script and assign it to our prefab.
Adding rotation behavior
We’ve used transform.translate for moving game objects before, now we’ll utilize transform.rotate.
Suggest a change Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all…
“Use Transform.Rotate to rotate GameObjects in a variety of ways. The rotation is often provided as an Euler angle and not a Quaternion.
You can specify a rotation in world axes or local axes.
World axis rotation uses the coordinate system of the Scene, so when you start rotate a GameObject, its x, y, and z axes are aligned with the x, y, and z world axes…
Local rotation uses the coordinate system of the GameObject itself.”
We’ll add a couple variables to hold our rotation direction and rotation speed values and use transform.rotate to spin our asteroid around.
We have to remember to use Time.deltatime so that the rotation is based on game time rather than frames rendered in our Update() method loop.
We’ll drag the 1st frame of our explosion animation into the hierarchy and rename it Explosion.
Set the sort order to Foreground.
Create the Explosion animation and drag our explosion sprites onto the Animation window.
Drag the Explosion game object onto our Prefabs folder in the Project window and we have a prefab.
We can now delete the Explosion game object in the hierarchy view.
Since we don’t want the explosion animation to loop, we need to set Loop time to disabled.
We’ll add a couple more variables at this point, a Boolean to track when the asteroid is destroyed for possible future use and an explosion prefab game object.
We add 2 methods, OnTriggerEnter2D() and AsteroidDestroyed().
In our triggerEvent method we want to check if “other” is tagged as “Laser” and if so, instantiate the explosion prefab at the position of this object (transform.position), destroy our laser game object that it collided with, and trigger our AsteroidDestroyed() event.
In our AsteroidDestroyed() method we set our bool variable to true and destroy this game object with a .25 second delay.
Now, the only way to really get the delay number in seconds is to play around with it a bit until your satisfied, I ended up with .25f.
We run into a little hiccup here, where we have this “Explosion(Clone)” game object that is forever left over in our hierarchy view.
It would be more difficult to attempt to destroy this game object from our asteroid script, since the game object the script is attached to dies before we are done with our animation.
Since there isn’t really a conceivable situation that we’d want an explosion game object to linger around, we can simply add a script to the explosion game object prefab and deal with it there.
If we look at our explosion animation, we notice it lasts about 2.4 seconds, so if we set the game object the animation is attached to for a self-destruct 3 seconds after it is created we should be good.
Alright, we’ve got an exploding asteroid.
Using the asteroid explosion to trigger enemy waves
Our current SpawnManager script has our StartCoroutine() calls in the Update() method which triggers automatically every frame that the SpawnManager game object is alive.
We want to control the start of our spawning, so we move all of these coroutines into a new Public method called StartSpawning() that we can call from other scripts.
In our Asteroid script, as we’ve further developed our prototype, that Boolean value _asteroidDestroyed I created earlier is seeming more and more unnecessary.
So, let’s remove it. I’ve shown it commented out here so you can see it, but delete those commented lines out for the variable and setting it to true.
We want to add a new variable to contain a reference to our SpawnManager script, _spawnManager.
In the Start() method we’ll use GameObject.Find() to assign the _spawnManager.
Lastly, in our AsteroidDestroyed() method we call the StartSpawning() method from our _spawnManager.
And I almost forgot to add a null check.
Now our asteroid destruction triggers the spawn waves…
But yeah, there’s a problem. Before our explosion animation has completed, we’ve got enemies showing up on the player screen.
Two ways we could fix this.
One, we could just make the enemies spawn much higher up so it takes them longer to get to the player screen.
Two, we could code in a start delay to the spawn coroutines.
Going with method 2, we add in aWaitForSeconds() call at the beginning of each of our spawner coroutines.
Since our asteroid explosion animation is about 2.5 seconds, 3 seconds should do nicely.
WARNING: Do not put this in the while loop, we only want it to run once and at the beginning.
That’s it for this article, next time we’ll add player thrusters and player damage!
There was a glitch where multiple laser game objects would hit the asteroid and register multiple times to spawn the waves creating 2 or 3 waves at a time.
That _asteroidDestroyed bool variable was needed after all!
With a few minor tweaks to our asteroid script, we can avoid this issue.