Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

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

Discussion in 'Scripting' started by T0byCat, Aug 17, 2020.

  1. T0byCat

    T0byCat

    Joined:
    Aug 17, 2020
    Posts:
    14
    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:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class FlashlightToggle : MonoBehaviour
    6. {
    7.    
    8.     public Light flashLight;
    9.    
    10.     private bool isActive;
    11.     private float currentPower;
    12.     public float maxPower;
    13.     public float EnergyRate = 0.5f;
    14.  
    15.     public AudioSource audiocontroller;
    16.     public AudioClip OnOffSound;
    17.    
    18.     // Start is called before the first frame update
    19.     void Start()
    20.     {
    21.         isActive = false;
    22.         currentPower = maxPower;
    23.     }
    24.  
    25.     // Update is called once per frame
    26.     void Update()
    27.     {
    28.  
    29.         currentPower = maxPower;
    30.  
    31.         if(Input.GetKeyDown(KeyCode.F)){
    32.  
    33.             if(isActive == false && flashLight)
    34.             {
    35.                 flashLight.enabled = true;
    36.                 isActive = true;
    37.                 audiocontroller.PlayOneShot(OnOffSound);
    38.             }
    39.             else if(isActive == true)
    40.             {
    41.                 flashLight.enabled = false;
    42.                 isActive = false;
    43.                 audiocontroller.PlayOneShot(OnOffSound);
    44.             }
    45.        
    46.         }
    47.         if(isActive == true && (currentPower > 0))
    48.         {
    49.             currentPower -= EnergyRate * Time.deltaTime;
    50.         }
    51.         else if(isActive == false)
    52.         {
    53.             currentPower += EnergyRate * Time.deltaTime;
    54.         }
    55.     }
    56. }
    57.  
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,947
    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.
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,777
    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:
    Code (csharp):
    1. currentPower = Mathf.Max(0f, currentPower);
     
  4. T0byCat

    T0byCat

    Joined:
    Aug 17, 2020
    Posts:
    14
    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?
     
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,777
    Just use it every time you modify the value.
     
    PraetorBlue likes this.
  6. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,947
    Whenever you do a modification that would potentially push the value past whatever limit you care about.
     
  7. T0byCat

    T0byCat

    Joined:
    Aug 17, 2020
    Posts:
    14
    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"
     
  8. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,777
    See the line I posted in my first comment?

    Just.... paste in that line. As is.
     
    PraetorBlue likes this.
  9. T0byCat

    T0byCat

    Joined:
    Aug 17, 2020
    Posts:
    14

    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()

    Code (CSharp):
    1.     void Update()
    2.     {
    3.         // Check if the values are too high or too low
    4.         currentPower = Mathf.Max(0f, currentPower);
    5.         currentPower = Mathf.Min(100f, currentPower);
    6.  
     
  10. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,947
    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.
     
  11. T0byCat

    T0byCat

    Joined:
    Aug 17, 2020
    Posts:
    14
    So by at the end, you mean at the bottom after everything been changed? That still produces weird floats at minimum and maximum values.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class FlashlightToggle : MonoBehaviour
    6. {
    7.    
    8.     public Light flashLight;
    9.    
    10.     private bool isActive;
    11.     private float currentPower;
    12.     public float maxPower;
    13.     public float EnergyRate = 0.5f;
    14.  
    15.     public AudioSource audiocontroller;
    16.     public AudioClip OnOffSound;
    17.    
    18.     // Start is called before the first frame update
    19.     void Start()
    20.     {
    21.         isActive = false;
    22.         currentPower = maxPower;
    23.     }
    24.  
    25.     // Update is called once per frame
    26.     void Update()
    27.     {
    28.  
    29.  
    30.         if(Input.GetKeyDown(KeyCode.F)){
    31.  
    32.             if(isActive == false && flashLight)
    33.             {
    34.                 flashLight.enabled = true;
    35.                 isActive = true;
    36.                 audiocontroller.PlayOneShot(OnOffSound);
    37.             }
    38.             else if(isActive == true)
    39.             {
    40.                 flashLight.enabled = false;
    41.                 isActive = false;
    42.                 audiocontroller.PlayOneShot(OnOffSound);
    43.             }
    44.        
    45.         }
    46.         if(isActive == true && (currentPower > 0))
    47.         {
    48.             currentPower -= EnergyRate * Time.deltaTime;
    49.             Debug.Log(currentPower);
    50.         }
    51.         else if(isActive == false)
    52.         {
    53.             currentPower += EnergyRate * Time.deltaTime;
    54.             Debug.Log(currentPower);
    55.         }
    56.        
    57.         // Check if the values are too high or too low
    58.         currentPower = Mathf.Max(0f, currentPower);
    59.         currentPower = Mathf.Min(100f, currentPower);
    60.     }
    61. }
    62.  
     
  12. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,947
    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.
     
  13. seejayjames

    seejayjames

    Joined:
    Jan 28, 2013
    Posts:
    692
    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.