Let’s create a cooldown system in Unity

Jaime
3 min readApr 25, 2021

--

Without a cooldown, the player’s fire rate would be as many times as the player presses the Fire button. Enemies can be defeated in no time with not much strategy.

Fire rate is as fast as pressing the Fire button

Current implementation of the Fire Laser feature above looks like this:

Laser.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Laser : MonoBehaviour
{
[SerializeField]
float _speed = 8f;
// Update is called once per frame
void Update()
{
transform.Translate(Vector3.up * Time.deltaTime * _speed);
if (transform.position.y > 8f)
{
Destroy(gameObject);
}
}
}

Player.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField]
private float _speed = 3.5f;
[SerializeField]
private GameObject _laserPrefab;
// Start is called before the first frame update
void Start()
{
transform.position = new Vector3(0, 0, 0);
}
// Update is called once per frame
void Update()
{
CalculateMovement();
if (Input.GetKeyDown(KeyCode.Space))
{
FireLaser();
}
}
void CalculateMovement()
{
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
Vector3 direction = new Vector3(horizontalInput, verticalInput, 0);
transform.Translate(direction * Time.deltaTime * _speed);
if (transform.position.x >= 11.3f)
{
transform.position = new Vector3(-11.3f, transform.position.y, 0);
}
else if (transform.position.x <= -11.3f)
{
transform.position = new Vector3(11.3f, transform.position.y, 0);
}
transform.position = new Vector3(transform.position.x, Mathf.Clamp(transform.position.y, -3.8f, 0), 0);
}
void FireLaser()
{
Instantiate(_laserPrefab, transform.position + new Vector3(0, 0.8f, 0), Quaternion.identity);
}
}

The solution is to create a cooldown system where pressing Fire and in this case it’s the Spacebar does not automatically spawn a laser until the cooldown time is finished. The implementation of this is readily available at https://docs.unity3d.com/ScriptReference/Time-time.html . The float Time.time provides the number of seconds elapsed since the game has started. With this float, we can compare the last time the laser was fired successfully with additional offset of the fire rate delay and see if it’s less than the current time. If it is, you can fire a laser. If not, you will have to wait before a laser can be fired again.

However, I’ll just put my own twist on it by placing the implementation of time checking in a method that returns whether the player can fire or not.

First, we need to declare the properties that record the fire rate and last time the laser was fired:

[SerializeField]
private float _fireRate = 0.5f;
private float _lastFire = -1;

As you can see above, the _fireRate can be adjusted from the Unity Editor while _lastFire is initially set to -1 to ensure that there is no cooldown at the start of the game.

Now we will update the FireLaser() method to record the time when this method was executed successfully.

void FireLaser()
{
_lastFire = Time.time;
Instantiate(_laserPrefab, transform.position + new Vector3(0, 0.8f, 0), Quaternion.identity);
}

Here is the implementation of the CanFire() method which returns true if last time the laser was fired together with the cooldown rate is less than the current time and false if cooldown is still in effect.

bool CanFire()
{
if ((_lastFire + _fireRate) < Time.time)
{
return true;
}
else
{
return false;
}
}

Finally, we add that check before we allow the player to fire a laser:

void Update()
{
CalculateMovement();
if (Input.GetKeyDown(KeyCode.Space) && CanFire())
{
FireLaser();
}
}

Now, cooldown is in effect:

Player can now only fire the laser again after the cooldown has been lifted.

Let me know if there are questions.

--

--

Jaime
Jaime

No responses yet