9. Projectile Attack

In this section, we'll finish our gameplay mechanics with a projectile attack.

Once the player grabs a lightning bolt, it'll be able to throw bolts at enemies, instantly killing them.

1. Add a HasProjectiles variable

The first thing we need to do is add a variable on the player to determine whether it has a projectile.

  1. Open the Level4 scene
  2. Select the Player object
  3. Add a boolean object variable called HasProjectiles, default false
  4. Apply the changes to the prefab

2. Projectile pickup

Then, we need to add a graph so that the lightning bolt on the ground enabled this variable. This will be very similar to the key pickup graph.

  1. Select the ProjectilesPickup object
  2. Add a new flow machine component
  3. Create a new macro for it called ProjectilesPickup
  4. Apply the changes to the prefab

In the graph, simply add these units:

3. Projectile graph

Next, we'll create the flow graph for the projectile itself. It should move forward in a direction while spinning, and trigger a death event on enemies when it collides with them. If it collides with anything else, it should simply disappear.

  1. Select the Projectile prefab under Prefabs
  2. Add a new flow machine component
  3. Switch its source to Embed

Here, we can use an embed graph because while this is a prefab, it will only be instantiated at runtime. Note that a macro would have worked just as well, if you prefer.

3.1 Launch

When launching, we will assume that the object has been assigned a Direction variable, representing the normalized X axis in which to launch. Then, we set the velocity of the projectile to match that direction with a constant speed of 8 units per second, and to self destruct in 10 seconds in case it didn't hit anything:

3.2 Rotation

For visual effect, we make the lightning bolt spin like a shuriken:

Here, we use the Per Second unit, located under Math > Scalar. It allows us to specify a framerate normalized value, here in degrees. Without it, the speed of the spin would depend on the framerate of the game, because Update is called exactly once per frame. Therefore, on faster computers, the projectile would spin faster than on slower computers, which is something we want to avoid.

3.3 Kill

Finally, if the projectile hits something, we check if it's an enemy. If so, we trigger its Death event (which we will implement later) then destroy the projectile. If we hit another object than an enemy, we simply destroy the projectile.

4. Throwing a projectile

Projectiles should be thrown when the player presses the Fire button mapped in the input settings of Unity (default Left Ctrl or Left Click). When that button is pressed, we will check if the player has projectiles, then if so, instantiate the projectile prefab at the position of the player with a default rotation.

This new projectile expects a direction in which to go (the Direction object variable we used in the projectile graph earlier). We set that to the scale of the player in the X axis, meaning the direction in which it is facing. Open the PlayerController graph and add this group:

  • Instantiate is located under Codebase > Unity Engine > Game Object
  • Get Identity is located under Codebase > Unity Engine > Quaternion. It just means "no rotation".

5. Enemy Death

Now, we'll implement the Death state in the enemy state machine we created in the last section.

5.1 Death State


When the enemy dies, it should:

  • Stop moving, by setting its velocity to zero
  • Stop colliding with anything so it falls down, by disabling its collider
  • Become semi-transparent, by lowering its sprite color alpha
  • Switch back to its idle animation, by setting its animator speed variable to zero
  • Self-destruct after 5 seconds
  • Sequence is located under Control. It allows you to order a list of steps vertically instead of horizontally.
  • Set Enabled is located under Codebase > Unity Engine > Box Collider 2D
  • Set Color is located under Codebase > Unity Engine > Sprite Renderer. Here, we set it to white but with a lower alpha value:

While it falls, we also want it to spin:


5.2 Death Transition

To transition to the death state, we'll simply listen for the Death custom event to be triggered on the enemy:


Rename the transition to Death. The final root enemy graph should now look like this:

6. Showing the projectile in the HUD

Finally, we need to show the lightning bolt in the HUD when it gets picked up by the player.

  1. Open the HUD scene
  2. Select the Projectiles object
  3. Add a new flow machine, leave its source at embed

This graph is even simpler than the one for the key, because we'll directly hide the lightning bolt if it's not in the player's inventory:


And we're done with gameplay! If you test the game now in level 4, you should be able to shoot and kill enemies:


This article was helpful for 15 people. Is this article helpful for you?

+2

It would be awesome if On Button Input had a drop down menu that showed/allowed you to select the items from the InputManager.

I can't seem to get the projectile to Instantiate. It returns Null... What am I missing?

Your graph looks exactly like mine and mine works. The error must be in your ProjectilesPickup Prefab Flow Machine graph... want to post it?

or something is wrong with your Projectile prefab since it returns Null on your graph...

+1

My mistake was on 3.1 Launch. I did Game Object Destroy (obj) instead of (obj, T). So the projectile was destroying as soon as it was instantiated.

I can't throw projectile when I pick it up.What am I missing?

According to this graph, HasProjectiles is false. Are you sure you set it to true when picking it up?

+1

Hi Wang. Your Fire Projectile sequence has to be in PlayerController and not in Projectile. Hope i helped you !

Hi. I can't get the one-eyed pig-alien to shoot. It is just moving back a little when I press fire. I have rebuilt several times.

Here is the Fire Projectile on the PlayerController graph. Everything moves here, but the object coming from Instantiate seems to be null. If I change the Projectile in Instantiate to e.g. Player it starts to multiply the player when I press fire. Is something wrong with the Projectile asset?:


Here is the Launch on the Projectile graph. Nothing is happening here when I press fire. Should variable Direction be visible in the Variables window, because it is not:


Hey! I´ve got the same problem! the script is exactly the same like in the tutorial.
Did you find out what the problem was?

I'm having the same problem at "theisvh" - I cannot seem to instantiate the projectile.  I've tried following the written tutorial and the video tutorial, but I cannot see a projectile either in game or in the hierarchy, so it seems like nothing is actually being instantiated, and the "instantiate Game object" node returns null, except if I rapidly fire I can sometimes see that it flashes "projectile(Clone)" on the graph right before it changes to "null".  The destroy timer is set to 10 seconds, so I just can't figure out what's going on.  Has something changed with Bolt or the newest version of Unity that breaks something in these graphs / tutorial?

Hey! I´ve got the same problem! Did you solve the problem and how did you solve it?

Nope, and I just gave up on it for now.  I posted here, on the discord channel multiple times in different places, and wasn't able to get any help.  I realize the devs are working hard on other things, but I think it's pretty discouraging to beginners (likely a large chunk of their potential users) when the tutorials don't work or aren't updated when things change...Anyway, I was really trying to learn Wwise and Bolt together, but decided to leave Bolt alone for now and just learn Wwise instead.  Good luck!