With our player movement finished and limited to a boundary, we’re now ready to have some fun making our player attack!
Let’s get started.
Our challenge is to create a prefab representing a projectile that we can then instantiate when the Player presses the space bar (we’ll add specifics for gamepads later). Once a projectile travels off-screen, we’ll destroy it to clean up resources that we no longer need.
For the prototype, let’s use a simple 3D capsule to represent the Projectile; I’ll scale it down to 0.2 for our purposes.
You can skip this step if you’d like, but I want to give this capsule some color. To do that, I’ll create a new Material within a new Materials directory and name it "Projectile". I’ll give the new material an albedo color of
#67F3F3 and set it on the Mesh Renderer.
To instantiate new projectiles at runtime, we need to make a Prefab from our Projectile. If you’re not familiar with Prefabs, I recommend reading through the documentation linked. I’ll create a new Prefabs folder, then drag-and-drop the Projectile GameObject into the folder to create a Prefab.
Instantiating Projectiles On Input
On to the fun part! Let’s fire some projectiles.
What do we need to accomplish this?
As the Player, we need to know:
- What a projectile is
- Under what condition we should instantiate it
- Where it should be positioned upon instantiation
Let’s tackle these one at a time.
Firstly, we need to make the Player script aware of the existence of a projectile prefab. To do this, I’ll create a private GameObject variable where we’ll reference the prefab. I’ll initialize it with
null and add a SerializeField attribute to assign it from the inspector.
I’ll switch to Unity, wait for the compilation to complete, and then click the target button beside the "Projectile Prefab" field in the inspector and select our Projectile Prefab. Now that the reference has been made, the Player script will have a value set for this field at runtime. You could optionally add a conditional in the Player Start method to check for null, but I won’t be bothered to do that everywhere for our prototype.
Here’s where we will invoke the Instantiate method to create a new prefab instance. We’ll provide the following arguments:
Let’s head back to Unity and test it out!
Technically, everything is working, which is excellent! However, our projectiles don’t have any behavior yet. Let’s fix that next.
Now we’ll add some movement to the Projectile. I’ll created a new Projectile script in our Scripts folder and add a speed field with the SerializeAttribute and initialize it to 8.0f.
Next, I’ll add the following code so that the Projectile translates upward when they are instantiated.
Now, if we playtest back in Unity, you’ll see that we have shooting projectiles!
We have one more thing to clean up here. If you notice in the hierarchy, our prefab instances travel off screen forever! They never get destroyed.
Destroying Off-Screen Projectiles
Just before we wrap up this post, I’ll clean up the off-screen projectile instances.
transform.Translate line, I’ll add a condition to check for the
y position, and if it is greater than X, I’ll invoke the Destroy method providing the projectile instance
gameObject as the argument.
Now you can see the projectile clones being removed from the hierarchy as they travel off-screen.
We’re done! Now our prototype has a basic attack mechanic for our Player.
Stay tuned as we build more of our prototype in the next post.