Create a First-Person Shooter In Godot - Part 2

Create a First Person Shooter in Godot – Part 2

Introduction

Welcome back, and I hope you’re ready to finish creating our Godot FPS tutorial.

In Part 1, we set up our arena, our player character, our FPS camera, our gun, our bullets, and even our red enemies.  However, while we certainly implemented the shooting mechanics, our enemies can’t yet damage players, get damaged themselves, or move.  In addition, we have no pickups to speak of, let alone a UI to give the player essential health and ammo information.  As such, in this tutorial, we will be jumping into setting those up.

By the end, you will have not only learned a lot about 3D game development, but also have a nifty FPS to add to your portfolio!

Project Files

For this project, we’ll be using a handful of pre-made assets such as models and textures. Some of these are custom-built, while others are from kenney.nl, a website for public domain game assets.

  • You can download the assets for the project here.
  • You can download the complete FPS project here.

Don't miss out! Offer ends in
  • Access all 200+ courses
  • New courses added monthly
  • Cancel anytime
  • Certificates of completion

Scripting the Enemy

Create a new script on the Enemy node. Let’s begin with the variables.

In the _ready function, we’ll set up the timer to timeout every attackRate seconds.

If we select the Timer node, we can connect the timeout signal to the script. This will create the _on_Timer_timeout function. We’ll be working on this later on.

In the _physics_process function, we’ll move towards the player.

The take_damage function gets called when we get damaged by the player’s bullets.

The die function gets called when our health reaches 0. The add_score function for the player will be added soon.

The last function to add is the Attack function. We’ll be creating the player’s take_damage function soon.

Finally in the _on_Timer_timeout function, we can check the distance to the player and try to attack them.

Player Functions

In the Player script, we’re going to add in a number of functions which we need right now and in the future. The die function will be filled in later once we have our UI setup.

Now we can go to the MainScene and drag the Enemy scene into the scene window to create a new instance of the enemy. Press play and test it out.

Pickups

For our pickups, we’re going to create one template scene which the health and ammo pack will inherit from. Create a new scene with a root node of Area.

  1. Rename it to Pickup.
  2. Save the scene.
  3. Attach a child node of type CollisionShape.
  4. Set the Shape to Sphere.
  5. Set the Radius to 0.5.

Pickup Node in Godot with CollisionShape

Next, create a script on the Pickup node. First, we’ll create an enumerator which is a custom data type that contains different options.

Then for our variables.

In the _process function, we’re going to make the pickup bob up and down.

Select the Pickup node and connect the body_entered node to the script.

The pickup function will give the player the appropriate stat increase.

Now that we’ve finished the script, let’s go back to the scene and you’ll see that the Pickup node now has two exposed variables.

Godot Inspector with Health Script Variables circled

We’re now going to create two inherited scenes from this original Pickup one. Go to Scene > New Inherited Scene… and a window will pop up asking to select a base scene. Select the Pickup.tscn and a new scene should be created for you. You’ll see that there’s already the area and collider nodes there since they are a parent. This means any changes to the original Pickup scene, those changes will also be applied to the inherited scenes.

All we need to do here is…

  • Rename the area node to Pickup_Health
  • Set the pickup type to Health
  • Drag in the health pack model

Pickup Health Node with model added in Godot

We also want to do the same for the ammo pickup.

Pickup Ammo node in Godot with model added

Back in the MainScene, we can drag in the Enemy, Pickup_Health and Pickup_Ammo scenes and place them around.

Godot FPS level with health and ammo pickups added

UI

Now it’s time to create the UI which will display our health, ammo, and score. Create a new scene with the root node being User Interace (control node).

  • Rename the node to UI
  • Create a new child node of type TextureProgress
  • Enable Nine Patch Stretch
  • Rename it to HealthBar
  • Move the health bar to the bottom left of the screen and re-size it
  • Drag the 4 anchor points (green pins) to the bottom left of the screen
  • Set the Under and Progress textures to the UI_Square.png image
  • Set the Tints as seen in the image.

UI HealthBar created in Godot

For the text, we need to create a new dynamic font resource. In the file system, find the Ubuntu-Regular.ttf file – right click it and select New Resource…

  • Search for and create a DynamicFont
  • In the inspector, set the Font Data to the ubuntu font file
  • Set the Size to 30

Godot Inspector for Dynamic Font

Now we can create the text elements. Create a new Label node and call it AmmoText.

  • Resize and position it like in the image below
  • Set the Custom Font to the new dynamic font file
  • Move the anchor points down to the bottom left

Ammo text for FPS game added in Godot scene

With the node selected, press Ctrl + D to duplicate the text.

  • Rename it to ScoreText
  • Move it above the ammo text

Score UI text added in FPS Godot game

Scripting the UI

Now that we have our UI elements, let’s create a new script attached to the UI node called UI.

First, we can create our variables.

Then we’re going to have three functions which will each update their respective UI element.

So we got the functions to update the UI nodes. Let’s now connect this to the Player script. We’ll start by creating a variable to reference the UI node.

Then in the _ready function, we can initialize the UI.

We want to update the ammo text in both the shoot and add_ammo functions.

We want to update the health bar in both the take_damage and add_health functions.

We want to update the score text in the add_score function.

And now we can go back to the MainScene and create a new node called CanvasLayer. Whatever is a child of this, gets rendered to the screen so let’s now drag in the UI scene as a child of this node.

Godot CanvasLayer with UI added

Now we can press play and see that the UI is on-screen and updates when we take damage, collect pickups, and kill enemies.

Conclusion

Congratulations on completing the tutorial!

If you’ve been following along, you should now have a complete Godot FPS game at your fingertips.  Players will be able to fire on enemies, gather pickups for ammo and health, and even potentially be defeated by our menacing red capsules!  Not only that, but you also have boosted your own knowledge in how Godot’s 3D engine works and how you can utilize 3D’s unique features in a number of ways.  Of course, from here, you can expand upon the FPS game we created in any way you please – adding in new systems, models, sound, etc.

Thanks for following along, and I hope to see you in the next Godot tutorial.