Search Unity

disabling a bool after time

Discussion in 'Scripting' started by monstergrunt09, Feb 13, 2020.

  1. monstergrunt09

    monstergrunt09

    Joined:
    Aug 15, 2018
    Posts:
    122
    so in my script. i made bone breaking feature, and i want after time (5 minutes) the bool will disable so it meant it healed.

    Code (CSharp):
    1.     void Bonebroke()
    2.     {
    3.         if (boneBreak)
    4.         {
    5.             canRun = false;
    6.             canStand = true;
    7.             grounded = true;
    8.             crouch = false;
    9.             prone = false;
    10.             audiosource.PlayOneShot(boneBreakSound);
    11.         }
    12.     }
    the bone break feature so far.

    by the way the bone breaks everytime a player falls so it enables the bool but i want it to disable.

    heres the bool

    Code (CSharp):
    1. public bool boneBreak = false;
     
  2. streeetwalker

    streeetwalker

    Joined:
    Jun 4, 2013
    Posts:
    150
    create and run a "timer coroutine" that will, when time is up, reset your bool. You can google that to find plenty of examples.
     
    monstergrunt09 likes this.
  3. SparrowsNest

    SparrowsNest

    Joined:
    Apr 6, 2017
    Posts:
    1,971
    While both previous solutions will work, I find them to be hacky at best - no offense.
    The way you'll want to go about it is using (what I call) "time stamps", when a bone breaks, don't set a bunch a bool and then reset them(and you don't need the special treatment for simultaneous stuff like you do the timer solution), set a float to the current time and derive a bool from it.

    IE:
    Code (CSharp):
    1. const float timeToHeal;
    2.  
    3. float lastBreak;
    4.  
    5. bool boneBroken {
    6. get {
    7. return Time.time > lastBreak + timeToHeal;
    8.  
    9. void BreakBone(){
    10.  
    11. lastBreak = Time.time;
    12. }
     
    monstergrunt09 and streeetwalker like this.
  4. streeetwalker

    streeetwalker

    Joined:
    Jun 4, 2013
    Posts:
    150
    Nice solution - thanks for posting that! I haven't seen that before, and definitely helpful. "Hacky" isn't the adjective you should use, but "elegant" - yours definitely is.

    However, you are missing a couple of closing braces. I believe your code should be this?

    Code (CSharp):
    1. bool boneBroken {
    2.      get {
    3.           return Time.time > lastBreak + timeToHeal;
    4.      }
    5. }
    6.  
    7. void BreakBone(){
    8.      lastBreak = Time.time;
    9. }
     
    monstergrunt09 and SparrowsNest like this.
  5. SparrowsNest

    SparrowsNest

    Joined:
    Apr 6, 2017
    Posts:
    1,971
    Yes, I forgot to close the property, thanks.

    "hacky" is be a bit harsh, but what I meant is when you want to scale the system up the coroutine approach can become very convoluted, both slower to run and harder to maintain.

    BTW - was I extra high last night or was there another post here?
     
    monstergrunt09 and streeetwalker like this.
  6. Ardenian

    Ardenian

    Joined:
    Dec 7, 2016
    Posts:
    200
    Would you mind going into detail here, please? I would not call myself a "coroutine fanboy", but if I had to choose, I would choose coroutines despite them being slower, mainly because it is very easy to add additional conditions and branching if you need to, without the timer being put into place with all the other code.
     
    monstergrunt09 likes this.
  7. SparrowsNest

    SparrowsNest

    Joined:
    Apr 6, 2017
    Posts:
    1,971
    Well, the time stamp is just a set & forget thing, you set the time of impact and that's it, if you set it again while injured - no problem.

    If you do it with a coroutine, you'll have to do extra stuff like when a bone breaks check if there's already a timer running, if there is - disable it so it won't trigger the healing sooner then expected.
    And it's just more stuff the CPU has to process, it may seem like a trivial thing (and it probably is in a small project)
    let's say you wanna differentiate between leg bones(effects movement), arm bones(effects accuracy) and torso bones(critical state), that means up to 3 coroutines running times the amount of characters, that can add up real easy if you just apply this kind of solution to every thing in the project.

    What kind of "additional conditions and branching" you think coroutines can cover that this approach cannot?
     
    monstergrunt09 likes this.
  8. monstergrunt09

    monstergrunt09

    Joined:
    Aug 15, 2018
    Posts:
    122
    thanks for showing me how to do it. (i didnt knew i could have used timer coroutine)
     
  9. monstergrunt09

    monstergrunt09

    Joined:
    Aug 15, 2018
    Posts:
    122
    I'm using streeetwalker's script he fixed for the missing braces.

    So for the boneBroken part.

    Where do i put it?

    Because anywhere i put it i get error's.
     
  10. monstergrunt09

    monstergrunt09

    Joined:
    Aug 15, 2018
    Posts:
    122
    Also
    const float timeToHeal;
    is an error for me, the error is error CS0145: A const field requires a value to be provided
     
  11. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    994
    This is a bit off-topic, but i dont like the way you use your bools. If you want to use convenience-bools like canCrouch and canStand, then you need to evaluate them at the beginning of each update cycle, based on all conditions that may affect them. Currently your system may make sense.
    If a bone breaks, you cannot stand, when it heals you can stand again.
    However, what happens if more than one condition affects the canStand bool? What if the player has a broken bone and is also caught under a net? He cannot stand because of the net, but that doesnt mean he can stand again as soon as the net is gone (since his bone is still broken). Thus you need a place to summarize and evaluate all of these conditions, and this step needs to happen at the beginning of each update cycle. Then you can use bools like canStand with ease of mind for the rest of the frame.

    You could for example do something like:
    Code (CSharp):
    1. private void EvaluateConditions(){
    2.     canStand = !caughtUnderNet && !brokenLeg;
    3.     canCrouch = ...
    4.     canRun = !brokenLeg && ...
    5. }
    Now you have it all in one place and your logic for each condition only needs to deal with that condition and nothing else (ie brokenBone true or false). You'd call this method at the start of each frame and that's basically it. Depending on what you do you may want to check for changes in the conditions (brokenLeg, caughtUnderNet, ..) before calling this method. If you can live with a potential 1-frame delay that's not necessary tho.
     
  12. streeetwalker

    streeetwalker

    Joined:
    Jun 4, 2013
    Posts:
    150
    Yes, I didn't catch that either. SparrowsNest's code was written quickly and perhaps he figured you'd know how to fill it in - we're all tying to help people, ripping off messages as fast as possible and it's easy to make mistakes.

    You need to provide a value for the time to heal. For example:

    const float timeToHeal = 20f; // 20 seconds to heal


    As for your previous question:
    Where are you trying to put it? We'd have to see your code at this point.
     
  13. Ardenian

    Ardenian

    Joined:
    Dec 7, 2016
    Posts:
    200
    Maybe not as straight as I said, but stuff like WaitForSeconds looks diffcult to me. In a greater context, once it is not just a timer counting down, you know, but more complex branching and conditions. I could imagine that a simple timer is a lot less readable then.
     
  14. monstergrunt09

    monstergrunt09

    Joined:
    Aug 15, 2018
    Posts:
    122
    I put it here
     

    Attached Files:

  15. monstergrunt09

    monstergrunt09

    Joined:
    Aug 15, 2018
    Posts:
    122
    I fixed the timeToHeal just like you posted the code on your post
     
  16. streeetwalker

    streeetwalker

    Joined:
    Jun 4, 2013
    Posts:
    150
    That should be fine there. The error was probably being thrown because timeToHeal wasn't defined. You'd get an error for both. I mean, have you given timeToHeal a value and you're still getting the error? If so, what is the exact error code?
     
  17. monstergrunt09

    monstergrunt09

    Joined:
    Aug 15, 2018
    Posts:
    122
    Only timeToHeal was an error, Before boneBroken was a error too but then i had to change it a bit and now its working.
     
    streeetwalker likes this.
unityunity