How do i make something add/subtract until it hits a certain point? [SOLVED]

So I’m attempting to do a sort of flashlight power system. (Not batteries, Half-Life 2 ep2 style.). So when it’s on i want it to take power away, then when it reaches zero, the flashlight turns off. But when it reaches 0 it’ll just keep going forever and ever, and when it charges it’ll go above 100. How do i limit these values?

my code so far:

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

public class FlashlightToggle : MonoBehaviour
{
   
    public Light flashLight;
   
    private bool isActive;
    private float currentPower;
    public float maxPower;
    public float EnergyRate = 0.5f;

    public AudioSource audiocontroller;
    public AudioClip OnOffSound;
   
    // Start is called before the first frame update
    void Start()
    {
        isActive = false;
        currentPower = maxPower;
    }

    // Update is called once per frame
    void Update()
    {

        currentPower = maxPower;

        if(Input.GetKeyDown(KeyCode.F)){

            if(isActive == false && flashLight)
            {
                flashLight.enabled = true;
                isActive = true;
                audiocontroller.PlayOneShot(OnOffSound);
            }
            else if(isActive == true)
            {
                flashLight.enabled = false;
                isActive = false;
                audiocontroller.PlayOneShot(OnOffSound);
            }
       
        }
        if(isActive == true && (currentPower > 0))
        {
            currentPower -= EnergyRate * Time.deltaTime;
        }
        else if(isActive == false)
        {
            currentPower += EnergyRate * Time.deltaTime;
        }
    }
}

The following functions can help you limit values to a particular desired range:

Mathf.Min
Mathf.Max
Mathf.Clamp

Apply one of those to your result as appropriate.

Well you existing code is setting the power to max every frame so you’d never even reach zero?

But if not for line 29, you could add this line to the end of Update:

currentPower = Mathf.Max(0f, currentPower);

Oh, i didn’t see that lol. So where would i put the min/max/clamp operations? Would i put them in the parts where while it’s active it subtracts the current power?

Just use it every time you modify the value.

1 Like

Whenever you do a modification that would potentially push the value past whatever limit you care about.

currentPower -= Mathf.Min(0f, currentPower) * Time.deltaTime;

So this is for taking energy away while the flashlight is on, i don’t feel like im doing this correctly because i want to have a rate at which the power decreases, then it reaches a certain point, turns the flashlight off and begins to add power again and it doesn’t seem like theres anywhere i can put “EnergyRate”

See the line I posted in my first comment?

Just… paste in that line. As is.

1 Like

Huh, that worked perfectly, only issue is when it reaches the minimum value it does this, will this be an issue when checking if its zero?

the code right under update()

    void Update()
    {
        // Check if the values are too high or too low
        currentPower = Mathf.Max(0f, currentPower);
        currentPower = Mathf.Min(100f, currentPower);

That code should be at the end of Update, like @StarManta suggested. not the beginning. You want to clamp the value after you make changes to it.

So by at the end, you mean at the bottom after everything been changed? That still produces weird floats at minimum and maximum values.

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

public class FlashlightToggle : MonoBehaviour
{
   
    public Light flashLight;
   
    private bool isActive;
    private float currentPower;
    public float maxPower;
    public float EnergyRate = 0.5f;

    public AudioSource audiocontroller;
    public AudioClip OnOffSound;
   
    // Start is called before the first frame update
    void Start()
    {
        isActive = false;
        currentPower = maxPower;
    }

    // Update is called once per frame
    void Update()
    {


        if(Input.GetKeyDown(KeyCode.F)){

            if(isActive == false && flashLight)
            {
                flashLight.enabled = true;
                isActive = true;
                audiocontroller.PlayOneShot(OnOffSound);
            }
            else if(isActive == true)
            {
                flashLight.enabled = false;
                isActive = false;
                audiocontroller.PlayOneShot(OnOffSound);
            }
       
        }
        if(isActive == true && (currentPower > 0))
        {
            currentPower -= EnergyRate * Time.deltaTime;
            Debug.Log(currentPower);
        }
        else if(isActive == false)
        {
            currentPower += EnergyRate * Time.deltaTime;
            Debug.Log(currentPower);
        }
       
        // Check if the values are too high or too low
        currentPower = Mathf.Max(0f, currentPower);
        currentPower = Mathf.Min(100f, currentPower);
    }
}

That’s because you’re logging the value before you do the clamping. What happens here is your code is pushing the value below the minimum, then the clamping code will bring it back up to the minimum. For example, the value starts at like 0.01. Your code subtracts a little bit and it goes down to something like -0.023. Then the clamping code brings it back to 0 at the end. But you’re doing Debug.Log before the clamp step so you’re seeing that small negative value.

Try doing the log statement after the clamping at the end instead.

If you want something to happen when you reach/go past a certain point, use another if statement right after you increment or decrement the value:
if (value < 0) { do something };
In this case, you might flip the boolean isActive.