Flashlight Cooldown and Timer

Hi there - Unity noob here. So in the Indie horror game I’m working on, I have a flashlight attached to my player. So far, I have scripted the flashlight to activate and deactivate with ‘E’, and it has a cooldown of 10 seconds before you can activate it again. However, before scripting the cooldown, my flashlight had a ‘limit’ where it would last for 30 seconds and then turn off. However, after adding my cooldown code, the limit is not working and the light stays on forever unless I press ‘E’. Can somebody point me in the right direction? Thanks.

Here’s my code:

using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;

public class FlashlightCooldown : MonoBehaviour
{

public float battery = 30;

// Start is called before the first frame update
void Start()
{
    //Light is automatically off on initialise
    GetComponent<Light>().enabled = false;
}

// Update is called once per frame
public float FlashlightCoolDown = 10f;
private bool FlashlightOnCooldown;

void Update()
{
    //If flashlight is not on cooldown, use flashlight when 'E' is pressed
    if (!FlashlightOnCooldown && Input.GetKey(KeyCode.E))
    {
        StartCoroutine(UseFlashlight());
    }
}
IEnumerator UseFlashlight()
{
    FlashlightOnCooldown = true;

    battery = battery - Time.deltaTime;

    //If the battery is more than 0, it can be activated with 'E'
    if (Input.GetKeyDown(KeyCode.E))
    {
        if (GetComponent<Light>().enabled == false)
        {
            if (battery > 0)
            {
                GetComponent<Light>().enabled = true;
            }
        }

        else

        //Light is not activated
        {
            GetComponent<Light>().enabled = false;
        }
    }

    //If battery is 0, do not activate light when 'E' is pressed
    if (battery < 0)
    {
        battery = 0;
        GetComponent<Light>().enabled = false;
    }

    yield return new WaitForSeconds(FlashlightCoolDown);
    FlashlightOnCooldown = false;
}

}

Your use of the coroutine here is a bit off and is what is causing your issue. Right now what is happening when you press E, the coroutine is being launched once, is getting to the yield return statement and hanging for 10 seconds, then exiting. If you wanted to fix this code you would have to add a while loop to the coroutine so that it runs multiple times, put the yield return inside the while loop, and change it to yield return null as you don’t want to wait 10 whole seconds to have the logic be called again. HOWEVER I think use of a coroutine here is a bit overkill and just over-complicates things.

public float maxBattery = 30;
public float flashlightCoolDown = 10f;

private float cooldownTimer;
private bool flashlightOnCooldown = false;
private bool flashlightIsOn = false;
private Light light;
private float battery = maxBattery;

void Start () {
    light = GetComponent<Light> ();
    light.enabled = flashlightIsOn;
}

void Update () {

    //Read input
    if (Input.GetKeyDown (KeyCode.E)) {
        ToggleFlashlight ();
    }

    //Do flashlight logic
    DoFlashlightLogic ();
}

private void DoFlashlightLogic () {
    if (flashlightIsOn) {
        light.enabled = true;
        battery -= Time.deltaTime;
    } else {
        light.enabled = false;
        if (cooldownTimer > 0) cooldownTimer -= Time.deltaTime;
        else flashlightOnCooldown = false;
    }

    if (battery <= 0) {
        flashlightIsOn = false;
    }
}

private void ToggleFlashlight () {
    if (flashlightIsOn) {
        flashlightIsOn = false;
        cooldownTimer = flashlightCoolDown;
    } else {
        if (!flashlightOnCooldown && (battery > 0)) {
            flashlightIsOn = true;
        }
    }

}

well, it’s seem like you forgot to set the battery value back to 30 after the cool down time. However, I think you can use something like void TurnOnFlashLight() and void TurnOffFlashLight() to make it easier (if you want).