[SOLVED] Why is this bool not changing?

I have a simple lever text that I am building and it has two bools. One is “triggeredByPlayer” and the other is “isSwitched”. I have them set to public so that I can see when they are true or false in the inspector.

The “triggeredByPlayer” bool is switching fine, but the “isSwitched” bool is not. Despite the bool not changing, I am still able to execute both of the animations in the Update function. The bool box just stays unchecked the entire time, even though it appears everything else is working fine. What am I missing here?

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class LeverScript : MonoBehaviour
{
     Animator anim;
     public Canvas leverText;
     public AudioClip lever;

     public bool isSwitched = false;
     public bool triggeredByPlayer = false;


     void Awake()
     {
          anim = GetComponent<Animator> ();
          leverText = leverText.GetComponent<Canvas>();
          leverText.enabled = false;
     }

     void Update()
//the "isSwitched" bool never becomes true after this key press...
     {  
          if (isSwitched == false && triggeredByPlayer == true && (Input.GetKeyDown (KeyCode.R)))
          {
               isSwitched = true;
               GetComponent<AudioSource>().PlayOneShot(lever);
               anim.Play ("Lever1");
          }
//...and even though the bool says false I am able to execute this keypress.
if (isSwitched == true && triggeredByPlayer == true && (Input.GetKeyDown (KeyCode.R)))
          {
               isSwitched = false;
               GetComponent<AudioSource>().PlayOneShot(lever);
               anim.Play ("Lever2");
          }
     }

     void OnTriggerEnter(Collider other)
     {
          if (other.gameObject.tag == "Player")
          {
               triggeredByPlayer = true;
               leverText.enabled = true;
          }
     }
     void OnTriggerExit(Collider other)
     {
     if (other.gameObject.tag == "Player")
          {
               triggeredByPlayer = false;
               leverText.enabled = false;
          }
     }
}

isSwitched would never stay true.
If it’s false you set it to true and then immediately check if it’s true and set it back to false.

shouldn’t the second check require a second keydown or does it not work that way? Each Change should require a key down, at least as I understand it.

It does not work that way.

Although it’s possible that GetKeyDown() will change it’s value within a single Update(), you would have to be very lucky.

Consider how the computer is looking at this code. First it checks that isSwitched is false and then checks that “R” is pressed. It does a few things and sets isSwitched to true. Next, it checks that isSwitched is true and then rechecks that “R” is pressed. It then does a few other things and sets isSwitched to false.

It does all this in a split second.

So, did the “R” button get pressed for only a split second? And did you stop pressing it in the few (probably < 1) milliseconds between the first check and the second check?

3 Likes

Ahhhhhh. Ok thank you that makes sense. I’ll try to figure out how to rewrite this section. Thank you again.

Input.GetKeyDown() should always return the same result during the same frame.

1 Like

Thanks again, eisenpony!

After understanding this, I added an “else” to one of the statements and everything is working fine now.

void FixedUpdate ()
     {
          if (isSwitched == false && triggeredByPlayer == true && (Input.GetKeyDown (KeyCode.R))) 
          {
               isSwitched = true;
               GetComponent<AudioSource>().PlayOneShot(lever);
               anim.Play ("Lever1");
          }

          else if (isSwitched == true && triggeredByPlayer == true && (Input.GetKeyDown (KeyCode.R))) 
          {
               isSwitched = false;
               GetComponent<AudioSource>().PlayOneShot(lever);
               anim.Play ("Lever2");
          }
     }
1 Like