FPS Mod
In this tutorial, you will learn how to mod ammo into your shooter game.
Creating an Ammo System
In the shooter lesson we created a gun to shoot at on coming enemies. However there is an infinite amount of ammo for the game, which makes it very easy to play the game. Lets modify our old Shooter script.
Open up your Shoot Script and add some new variables,
maxAmmo,
currentAmmo, and
reloadTime. Make sure currentAmmo is private as we should not be able to adjust the current amount of ammo we have.
using UnityEngine; public class ShootScript : MonoBehaviour { public float damage = 10f; public float range = 100f; public int maxAmmo = 10; private int currentAmmo; public float reloadTime = 1f;
Now we need to add our Start function back into the code. We are going to use this to set the current ammo equal to the maximum ammo at the start of the game.
void Start() { currentAmmo = maxAmmo; }
Now we need to subtract the current ammo whenever we fire the gun. Go to the Shoot function and subtract one from the current ammo. This way, every time we fire the current ammo decreases.
void Shoot() { currentAmmo--; RaycastHit hit; //Fires out from the center of the camera and detects objects that connect with the ray if (Physics.Raycast(camera.transform.position, camera.transform.forward, out hit, range)) { //Prints name of object that was hit Debug.Log(hit.transform.name); //Detects if the object it hits has the Script "Enemy" Enemy enemy = hit.transform.GetComponent<Enemy>(); if (enemy != null) { enemy.TakeDamage(damage); } } }
Starting Reloading
Now that we have the ammo decreasing on every shot, we need a way to reload our ammo back into the gun.
Go to the Update function and add an if statement saying, if you are out of ammo, reload. Then create a new function named
Reload.
void Update() { if (currentAmmo <= 0) { Reload(); return; } if (Input.GetButtonDown("Fire1")) { Shoot(); } } void Reload() { }
In that new function Reload add a log that states when you are reloading, and set the current ammo back to the max ammo. This way we have fully reloaded the gun.
The return keyword in the if statement means the rest of the code in the update function will not run. That way, the Update function will never check if the player fired their weapon once they are out of ammo.
void Reload() { Debug.Log("Reloading"); currentAmmo = maxAmmo; }
Now if you test out the gun in the game every 10 shots will immediately reload. However we want some time in between shots for the gun to reload.
Using Coroutines
By using a coroutine we can have the code wait for a few seconds while the gun is reloading. But first we need to add at the very top System.Collections.using UnityEngine; using System.Collections; public class ShootScript : MonoBehaviour {
Now we can use a coroutine. Change the void in the function Reload to an IEnumerator. Then we will be able to add a pause in the code, we will use our reloadTime variable as the amount of seconds it takes to reload.
IEnumerator Reload() { Debug.Log("Reloading"); yield return new WaitForSeconds(reloadTime); currentAmmo = maxAmmo; }
We can't call a coroutine like a normal function. So in the Update function, change the Reload function call to a StartCoroutine.
void Update() { if (currentAmmo <= 0) { StartCoroutine(Reload()); return; } if (Input.GetButtonDown("Fire1")) { Shoot(); } }
Using a Bool
Now the gun will reload every time it is empty. However it will keep constantly reloading once the ammo is zero until the reload time is up. We need to tell it to only reload once during the wait. Add a private bool named
isReloading.
public class ShootScript : MonoBehaviour { public float damage = 10f; public float range = 100f; public int maxAmmo = 10; private int currentAmmo; public float reloadTime = 1f; private bool isReloading = false;
In the Update function we need to add a new if statement that goes on top of the if statement we just made. This one will detect if the gun is currently reloading.
void Update() { if (isReloading) { return; } if (currentAmmo <= 0) { StartCoroutine(Reload()); return; }
Now it's time to tell the script when we are reloading. Go into the Reload function and at the top set the bool to true. Then at the bottom of the function set the bool to false.
IEnumerator Reload() { isReloading = true; Debug.Log("Reloading"); yield return new WaitForSeconds(reloadTime); currentAmmo = maxAmmo; isReloading = false; }
That is all we need to create an ammo and reloading system into our shooter game! Feel free to make changes to the reload time and the max ammo amount. Test out the new feature.
Creating an Animation
We could leave it there, as the code works as needed. However we can't tell if the gun is reloading or not. We can create a quick animation that tells us if we are reloading.
Open up the animation window while you have the gun selected. Create a folder for animations. Then save two animations, one for the idle animation, and one for the reloading animation.
Under our reloading animation create a visual representation of the gun reloading, here we just tilt the gun down slightly. Then for the idle animation make sure you have everything set back to what it normally was. Then, go into the Animator and make transitions from the idle to the reload animation. After you have done that, we need to make a condition that will activate the animations. Make a bool called Reloading, when it's true it will activate the reload animation, and when it's false it will stop the animation.
Now to program the animations into the gun. Open up the Shoot Script and make a public Animator. This is where we will call for the gun's animator.
public class ShootScript : MonoBehaviour { public float damage = 10f; public float range = 100f; public Animator animator; public int maxAmmo = 10; private int currentAmmo; public float reloadTime = 1f; private bool isReloading = false;
In the Reload function, add two lines of code. The first one should be before the wait, and it needs to set the animator's
Reloadingto true. Then the write the opposite after the wait, with the
Reloadingas false.
IEnumerator Reload() { isReloading = true; Debug.Log("Reloading"); animator.SetBool("Reloading", true); yield return new WaitForSeconds(reloadTime); animator.SetBool("Reloading", false); currentAmmo = maxAmmo; isReloading = false; }
Now just add the gun animator to the script and your good to go! Every ten shots your gun will animate your reload, then you will be able to fire more after that!