Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Bug with reducing value on movement code

Discussion in 'Scripting' started by LMacalister, Apr 29, 2020.

  1. LMacalister

    LMacalister

    Joined:
    Jul 5, 2017
    Posts:
    9
    So at the moment I'm using a fuel system that reduces when moving and regenerates when not. The issue i'm getting is that sometimes it won't regen if the player is still inputting movement even if fuel is 0. As you'll see from the code it shouldn't make a difference if the player presses anything but it is sometimes. I think it's stuck in the loop?


    Code (CSharp):
    1. //Reduces fuel if input & fuelDepleted is false or makes fuelDepleted = true if fuel is 0
    2.             curSpeed = jetPackPower;
    3.             if (fuel <= 0)
    4.             {
    5.                 curSpeed = 0;
    6.                 fuelDepleted = true;
    7.             }
    8.  
    9.             else if (fuelDepleted == false && movement.y != 0 || movement.x != 0)
    10.             {
    11.                 fuel = Mathf.Max(0f, fuel - fuelDeduct * Time.fixedDeltaTime);
    12.                 lastJetPack = Time.time;
    13.             }
    Code (CSharp):
    1. //Starts regen if enough time has passed since last jetPack usage
    2.         if (lastJetPack >= 0 && Time.time - lastJetPack >= regenDelay)
    3.         {
    4.             RegenFuel();
    5.         }
    Code (CSharp):
    1. //Regens fuel and sets fuelDepleted to false (allowing player to jetpack) if fuel is 20 or more
    2.     void RegenFuel()
    3.     {
    4.         if (fuel >= 20f)
    5.         {
    6.             fuelDepleted = false;
    7.         }
    8.         fuel = Mathf.Clamp(fuel + fuelRegen * Time.deltaTime, 0, maxFuel);
    9.         if (fuel == maxFuel)
    10.         {
    11.             lastJetPack = -1;
    12.         }
    13.     }
    I've tried having the if/else if as two ifs and i've tried them in reverse with no plus. I've also tried putting a return at the end of "if (fuelDepleted == false && movement.y != 0 || movement.x != 0)" with no success
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    You should be using parenthesis in these complex "if" statements with multiple conditionals. Take line 9 in your first block:

    Code (csharp):
    1. else if (fuelDepleted == false && movement.y != 0 || movement.x != 0)
    What I think is happening is it first compares fuelDepleted == false, then does && with movement.y != 0. Then it takes the result of all of that together and does the || movement.x !=0. So basically if movement.x != 0 then the "else if" will always resolve to true, regardless of the value of fuelDepleted. That will of course execute the contained code which just happens to burn fuel. So you're not stuck at 0 fuel, you're just using fuel while you are regenerating. In your RegenFuel method you are clamping negative fuel values to 0, so it always looks like 0.

    That's my theory at least. Add Debug.Log statements all over this to confirm. If you use parentheses it would make these conditionals a whole lot easier to read without looking up their order precedence or how different conditionals are combined in the same line. Below is what I expect you actually think your code does, but I don't think it does.

    Code (csharp):
    1. else if (fuelDepleted == false && (movement.y != 0 || movement.x != 0))
    Again, that's my theory. I don't have Unity or VS on this computer to test.

    Edit: Also I notice that when that "else if" is executed, it will not only burn fuel but also update your lastJetPack, so RegenFuel won't actually get executed later. So I was wrong about RegenFuel probably running. It won't run at all until movement.x is 0 long enough for the regenDelay timer to run out.
     
    Last edited: Apr 29, 2020
  3. LMacalister

    LMacalister

    Joined:
    Jul 5, 2017
    Posts:
    9

    Works perfect thanks for helping again! Makes sense now with the && and the || it's because I added the fuelDepleted bool much later and forgot how to check how it would impact what I already had.
     
    Joe-Censored and Kurt-Dekker like this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,970
    What Uncle Joe wrote above is 100% complete but I'll take it one step further: break it apart so you only test one thing at a time.

    First test: am I thrusting? yes no

    yes thrusting:

    do I have fuel? burn it and apply thrust

    no thrusting:

    is my motion really close to zero ( I would not test against zero, just check if it's slow enough)?
    is there room in my tank? load it

    If you need to check more things, don't add them to a single giant expression otherwise you can't reason about them.

    Source: I do this a LOT in my Jetpack Kurt game:

     
    Joe-Censored and LMacalister like this.