Thursday, December 12, 2013

Keeping track of cooldowns with a helper class in Unity 3D

For my current project, I wrote a simple class to keep track of my cooldowns.

So for example, my character can fire every 2 seconds, jump every 4 seconds and sprint every 3.142 seconds; and this class takes care of the cooldown timers for me.

Here's how I use it:

public class Player : MonoBehaviour 
{
    private CooldownTimer firingCooldown;
    private CooldownTimer sprintCooldown;

    private void Awake() 
    {
        firingCooldown = new CooldownTimer(2f); // the player can fire every 2 seconds
        sprintCooldown = new CooldownTimer(3.142f); // the player can sprint every 3.142 seconds
    }

    private void Update() 
    {
        if (Input.GetButtonDown("Fire") && firingCooldown.CanWeDoAction()) 
        {
            firingCooldown.UpdateActionTime();
            // Do firing logic            
        }

        if (Input.GetButtonDown("Sprint") && sprintCooldown.CanWeDoAction()) 
        {
            sprintCooldown.UpdateActionTime();
            // Do sprinting logic            
        }
    }
}

And this here's the CooldownTimer class:

using System;

public class CooldownTimer
{
    private float? LastActionDone { get; set; }
    private float IntervalSeconds { get; set; }

    public CooldownTimer(float intervalSeconds)
    {
        IntervalSeconds = intervalSeconds;
    }

    public void UpdateActionTime()
    {
        LastActionDone = Time.time;
    }

    public bool CanWeDoAction()
    {
        var canWeDoAction = true;
        if (LastActionDone.HasValue)
        {
            var secondsSinceLastAction = Time.time - LastActionDone;
            canWeDoAction = secondsSinceLastAction > IntervalSeconds;
        }

        return canWeDoAction;
    }
}

Update 1

With a tip from Petr Kolda (Facebook), I've now modified the class to use Time.time instead of DateTime.Now.