Creating a Shooting Game (recap)

Continuing to create and Shooting game that involves Ray Casting, and Nav Mesh Agents.

Simon Truong
7 min readJun 7, 2023

--

From the previous article, in this medium post we will be continuing onward in creating an Shooting game that requires the uses of Ray Casting and Nav Mesh Agents. In the last article we finished off with completing the Hiding function within the Enemy Movement script. Now we will continue on with creating an Spawn Manager.

Creating an Spawn Manager:

Start by creating a new C# script called Spawn Manager, as the name states, this script will focus on everything that has to do with spawning the enemy prefabs, and also keeping count of all spawned objects on the field.

Since this is considered a Manager class script, we shall convert this script into an instance so we can access it anywhere.

Next we are going to create an List for the spawned objects along with the actual game object being spawned and the total amount of spawned objects. They are all serialized because that way we can control their input via the inspector during Unity Game Play.

In the start method, we are going to need to gain access to the waypoint that was created within the Game manager script. Then we are going to create an for loop which will preset the desired amount of spawned units at the start of the gameplay. The for loop will only be function until it hits the preset amount which is have serialized locally within the script. We are also going to preset the spawn unit to be inactive during the initial launch and have the Game Manager slowly turn them active one by one on a set timer.

Next we are going to create an public method which will allow the Game Manager script to set on the game object after a preset timer.

Enemy 3D Model and Animation:

The 3D model:

To get the 3D Model, I decided to hop into the massive GameDevHQ library which houses a giant collection of 3D assets. I decided to use an model that is bright and can be seen easily from far away and also stands out from the gray background.

I applied the 3D model as a child object to the Enemy object so that the model can be changed anytime without affecting the actual parent game object. To finish the enemy prefab, I turned off the capsule mesh and also deleted the capsule collider since the Nav Mesh Agent already comes with an collider.

The Animations:

Since this is still just an prototype game, we need to quickly implement this concept without spending too much time on more complex and time consuming processes. Therefore to use pre-animated skeletal frame from Mixamo is perfectly acceptable in this scenario. I quicky download 5 different types of animation sequences, one for walking, one for running, one for idle, one for hiding and finally one for dying.

Once you have imported and apply the animations sequence to the 3D model, we are going to open up the Animator to link the different animation sequence like so:

We want to trigger the Death sequence at any point during the animation sequence, therefore it is linked to the “Any State”

We are also going to add in 3 parameters to the Animator to toggle the Death and running sequence.

Toggling the Animation:

Once the Animator and Animation has been set into our 3D model, we are going to head into the scripts to set the conditional toggle. Since the 3D model is attached to the Movement script, we shall control all animations within the Movement script itself.

To start, we will add in an serialized field for the Animator.

Then in each Ai State that we have created, we are going to add in the corresponding animation trigger. For the regular movement calculations we are going to input our “Speed” parameter that will trigger the Walking/Running animation.

Just to keep things simple to edit, I decided to have the preset speed be identified by an variable called “animator Movement Speed”. This variable actually is the Nav Mesh Agent’s movement speed. Since the Nav Mesh Agent speed is set to random (meaning it can move fast or slow) I decided to pass in that variable as the “Animation Movement Speed” so the animation can follow the same variable in speed adjustment.

For the Hiding and Death state, since the parameters are not reliant on any integers or float values and are just simple triggers and bools, I can just plot them into the script like so.

The Hiding state needs to start and also revert back to the walking state, therefore I would need to retrigger the walking/running animation after the yield.
Since the Death Animation is a trigger, I just need to set the trigger once during the death sequence.

Adding the HUD and UI Elements:

When assigned this project, there was one section that required the designer to step in and provide a rough sketch to follow and that was the UI/HUD. As a developer we will need to adhere to what the designer wants.

The initial mockup of the HUD placement.

Thankfully we are also been provided with the visual files to create the HUD.

So all we have to do, is download the 2D sprite Editor (if you haven’t so already) and slice the image above to individual images. Then we can apply them into the game UI.

To organized this, I decided to create an UI Canvas and have every individual element have their own container, and also group the text element within the so called container.

The side by side comparison between rough mockup and in game layout.

Scripting the UI:

Now that the placement of most of the UI are complete to what the design envisioned, we can start creating the functions of the UI to the actual game mechanics. (aka, making the elements reflect real time game play)

Since we are going to create a new C# script to control all UI elements, might as well called it the UI manager script and make it an instance.

Then we are going to need serialized fields for all the UI elements.

First we are going to script the timer, in the center of the UI there is an timer which count down from a preset value.

This method basically states that if the time value is higher than 0, then keep subtracting 1 second from the overall timer. Else if the time value is not higher than 0, time value is set to 0 (meaning that we won’t get into the negatives values). There is also an Display Time method with an input of time value within it.

This method basically displays the timer from the the float value to a standard minutes/seconds that we are all accustomed to.

In the update method, we are going to add in the variables from the different scripts, such as total score, ammo count and also enemies left from the corresponding scripts.

Once that is finished, head back to unity and plot in all the required UI elements into the slots. When you hit play, you should be able to see the UI elements working as intended. The Timer will count down, the ammo counter will reduce by one when shooting, and the enemy count will also subtract one whenever you managed to knock one enemy AI down.

--

--

Simon Truong

A Designer, an Illustrator and a massive tech geek aspiring to become a professional Unity Developer.