Search Unity

Question If statements & preventing excessive looping

Discussion in 'Scripting' started by abrahadarba, Feb 22, 2024.

  1. abrahadarba

    abrahadarba

    Joined:
    Apr 19, 2021
    Posts:
    20
    I have an if statement that increments a character's score using points from a pool via a button-press; unfortunately, the nature of the if statement is such that if the points pool is sufficient the method will use all available points until the if statement is no longer true. How to put a break on the if once the condition has been met the first time? (no, putting break or return has no effect on the bug)
    Method for comedic effect:

    Code (CSharp):
    1.  
    2. //incrementing uses as many featureXP as possible when Increasing scores instead of incrementing once!
    3. private void IncreaseAmbition()
    4. {      
    5.     int increaseCost = rep.Ambition.TotalScore + 1;
    6.     if (rep.Ambition.TotalScore < 15 && rep.featureXP >= increaseCost)
    7.     {
    8.         rep.featureXP -= increaseCost;
    9.         rep.Ambition.featureXPScore += 1;
    10.        
    11.         Debug.Log("The representative " + rep.repName + "'s Ambition was raised to " + rep.Ambition.TotalScore + "!");        
    12.     }
    13.     else if (rep.featureXP >= 2 * increaseCost)
    14.     {
    15.         //ignore further opportunities to increase Ambition
    16.     }
    17.    
    18. }
     
  2. phamtony037

    phamtony037

    Joined:
    Feb 22, 2024
    Posts:
    3
    It looks like you want to limit the increase in Ambition to only once when the condition is met for the first time, and you want to prevent further increments of Ambition even if there are enough featureXP points available. One way to achieve this is by introducing a boolean flag to track whether the Ambition has already been increased. Here's a modified version of your code:

    csharp
    private bool ambitionIncreased = false;

    private void IncreaseAmbition()
    {
    int increaseCost = rep.Ambition.TotalScore + 1;

    if (!ambitionIncreased && rep.Ambition.TotalScore < 15 && rep.featureXP >= increaseCost)
    {
    rep.featureXP -= increaseCost;
    rep.Ambition.featureXPScore += 1;

    Debug.Log("The representative " + rep.repName + "'s Ambition was raised to " + rep.Ambition.TotalScore + "!");

    ambitionIncreased = true; // Set the flag to true to indicate Ambition has been increased
    }
    else if (rep.featureXP >= 2 * increaseCost)
    {
    // Ignore further opportunities to increase Ambition
    }
    }

    In this modification, the ambitionIncreased flag ensures that the Ambition is increased only once when the condition is first met. Subsequent calls to IncreaseAmbition will check this flag, and if it's already set to true, it will skip the increment.
     
  3. abrahadarba

    abrahadarba

    Joined:
    Apr 19, 2021
    Posts:
    20
    Yeah, that was tried but no dice - the bug is unaffected...
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,812
    This doesn't make sense. If-statements don't run repeatedly. Something else has to be calling this repeatedly.

    To that end, just don't call the code repeatedly.
     
    Bunny83 and Nad_B like this.
  5. abrahadarba

    abrahadarba

    Joined:
    Apr 19, 2021
    Posts:
    20
    sorry, spiney199 - from my end it makes perfect sense
    if the if statement is true for a single increment, it can also be true for subsequent increments, which is where my gremlin lies: depending on the number of points available for score increases, the if can (and does) "auto-spend" points to fulfill the if's parameters...
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,812
    Again, they don't run repeatedly on their own. You have to be calling this repeatedly for that to happen. If you don't want it to run repeatedly... just... don't call it repeatedly.

    This statement here:
    Is 100% NOT how C# works. If-statements do not loop on their own. They are not loops. If the code is running multiple times, something else you are doing is causing that to happen.
     
    Bunny83, Kurt-Dekker and Nad_B like this.
  7. abrahadarba

    abrahadarba

    Joined:
    Apr 19, 2021
    Posts:
    20
    I gotta disagree with you, spiney - in this case, at least
    the if statement checks to see if the score is below 15 AND if the available XP is greater than the increase cost
    if the available XP is more than twice the increase cost the if statement is 'auto-spending' XP on me
    the method is only being called on a button-press, and I'm only pressing the button once - and this bug is happening only if there are enough XP to cover a second (or even third) score increment
     
  8. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    712
    Yes, as @spiney199 said, you're confusing
    if
    with
    while
     
    Bunny83 and spiney199 like this.
  9. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,812
    I cannot help you if you are going to disbelieve me about the fundamentals of C# and of programming in general.
     
    Kurt-Dekker and Nad_B like this.
  10. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    712
    There's not a single programming language in the world (and probably in the universe) where an if/else statement is repeated (looped), on its own. This job is left for loops and co (for, foreach, while, do, goto, recursive calls...)

    Something is calling IncreaseAmbition() repeatedly (from an Update(), or a coroutine...). Just right click on IncreaseAmbition (the word itself) and choose "Find usages" from the menu (or just Shift+F12), it'll show you from where you're calling this method...
     
    Bunny83 and spiney199 like this.
  11. abrahadarba

    abrahadarba

    Joined:
    Apr 19, 2021
    Posts:
    20
    it'll be an update thing, then
    maybe
    thanks Nad_B - I'd agree that an if shouldn't be checking if a condition is true more than once, yet here I am...
    XD

    ...and so I find that IncreaseAmbition() is only being called onClick, as is intended - no references to the method being called in an update...?
     
    Nad_B likes this.
  12. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,812
    I'm sure you can answer how often the code is running with
    Debug.Log
    calls. It gives you a stacktrace too. This should be trivial to debug on your end.
     
    Ryiah and abrahadarba like this.
  13. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,979
    Well, you said it's called on a button press. You never showed this part which is most likely the cause of your issue. Maybe you "think" it's a button press but you may actually use something like Input.GetKey instead of GetKeyDown?

    Well, you can disagree with spiney but you can't argue with the compiler. It's the ultimate authority and decides what your code does. Unfortunately for you, the compiler would be on spineys side ;)

    Right. It literally tells you from where it was called.
     
    spiney199 likes this.
  14. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    In order to solve a bug, you must come up with theories and then try to prove or disprove those theories.

    It seems your first theory is that the if statement is somehow looping. You yourself seems to admit that if statements do not loop and several others have confirmed this. So toss that out the door.

    Now, the next theory is that something is causing it to loop. Since the method is private, that means you're likely calling it from another method. If it's not a gui button and is based off a keyboard key press, then it would be called from Update most likely. If that Update method looks correct, one other possible bug is you have multiple copies of this script in your scene and all target the same instance of rep, thus a keyboard key press would trigger them all until the points run out as you have noted.

    But, the most likely scenario is that you're somehow calling the method in a loop somewhere, which several people have mentioned.

    These are a few possible scenarios. But first thing is to get the idea out of your head that "if" is somehow looping on its own.
     
  15. abrahadarba

    abrahadarba

    Joined:
    Apr 19, 2021
    Posts:
    20
    yeah, turns out I didn't need to initialize my buttons after all
    and I only needed one button object in my script, not each individual button as I originally coded

    gimme a break - I'm largely self-taught...

    ...now if I could only teach myself to change the topic of the post to 'solved' :confused:
     
    Last edited: Feb 25, 2024
    phamtony037 and Nad_B like this.