Private bool is being set true by event, but is being read as false in the update thread.

I am trying to set up a script that turns off audio listeners depending on the game’s state. To do this I have my function subscribed to an event.

   public class ActivatePlayerAudioListener : MonoBehaviour
    {
        [SerializeField]
        AudioListener listener;

        Directory directory;
        Transform player;
        Transform rootTransform;

        GameFlow gameFlow;

        bool startTriggered;

        bool amInBattle = false;
        // Start is called before the first frame update

        private void OnEnable()
        {

            if (startTriggered == true)
            {
                gameFlow = Directory.GetDirectory().GetGameFlow();

                //Debug.Log("Game Flow : " + gameFlow.name);

                gameFlow.GameStateChangeEvent += CheckMode;
            }
        }

        private void OnDisable()
        {
            if (gameFlow == null)
            {
                return;
            }

            gameFlow.GameStateChangeEvent -= CheckMode;
        }

        void Start()
        {
            gameFlow = Directory.GetDirectory().GetGameFlow();

            //Debug.Log("Game Flow : " + gameFlow.name);

            gameFlow.GameStateChangeEvent += CheckMode;

            startTriggered = true;
        }
        // Update is called once per frame

        void CheckMode(object sender, GameFlow.GameStateEventArgs eventArgs)
        {
            GameFlow.GameState state = eventArgs.currentGameState;
      

            Debug.Log("Activate Audio Listener Checking Game Mode... " + state);

            if (state == GameFlow.GameState.Battle)
            {
       
                SetInBattleState(true);
                return;
            }
            else
            {
                SetInBattleState(false);
                return;
            }

    


        }


        private void SetInBattleState(bool state)
        {
            Debug.Log("Setting In Battle " + state);
            amInBattle = state;
        }

        void Update()
        {

            listener.enabled = false;

            Debug.Log("amInBattle is " + amInBattle);

            if (!amInBattle)
            {
                return;
            }

            //Debug.Log("Audio listener in battle...");

            directory = Directory.GetDirectory();

            rootTransform = this.transform.root;

            player = directory.GetBattlefieldInfo().GetPlayerTransform();
           // Debug.Log("PLAYER POS: " + player.position);
          

            if (player == rootTransform)
            {
                //Debug.Log("AM PLAYER");
                listener.enabled = true;
            }
        }
    }

The bool “amInBattle” is private. Nothing outside of “CheckMode()” should have the ability to set “amInBattle.” I can tell from my debug logs that when I enter battle, “amInBattle” does get set to true. Therefore, all my code does atm is switch all the audio listeners off. However, the debug log in the update function never reads “amInBattle” as true. Is there something I am missing about how events, and our booleans work?

I would guess that you probably have the Collapse option enabled in your console, which can cause the ordering of logs in your console to appear in a confusing order. The other possibility is that you have multiple copies of either ActivatePlayerAudioListener and/or Directory/GameFlow in your scene and you have perhaps one instance where amInBattle is being set to true and another where it’s false.

Your GameFlow script could also be sending another event in which the game state is no longer the Battle state in quick succession. There’s not enough information here to know for sure.

In terms of general advice, to be perfectly frank with you I’m struggling to understand why this script even has an Update function? Couldn’t you just do everything from line 97 down inside SetInBattleState itself? Update seems wasteful here.

Another wasteful thing here is the use of the EventArgs pattern. It would be more efficient (less memory allocation and garbage collection) to simply write a custom delegate type for your event such as:
public delegate void GameStateChangeHandler(GameFlow.GameState newState);

You don’t specify any access to your bool startTriggered, so it is private by default. You don’t specify a value for your private bool startTriggered, so it is false by default. OnEnable() is actually called before Start(), so when OnEnable runs, you skip that condition, and thus never subscribe to the event.

When in doubt, liberally sprinkle your code with print()/Debug.Log() statements to see your variables’ values and inside various functions to see what order things are actually happening. You can always take them out later once you know they’re working as you intended.

“Start Triggered” is actually working as intended. It’s “amInBattle” that seems to remain false even though it is set in the event. To Praetor Blue’s point I am doing a lot of unusual stuff because I cant get the directory on enable. Tbh, I can’t remember exactly why I have all that stuff going on in update. I think I was not able to access the player’s transform otherwise. I have to rush to my other job now, but I’ll check back when I return to try and give a better answer.

In addition to what I wrote above, a listing or screenshot of your console window as this is happening would be useful.