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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

How to define a Global Boolean that can be checked from another script

Discussion in 'Scripting' started by weight_theta, Dec 31, 2020.

  1. weight_theta

    weight_theta

    Joined:
    Aug 23, 2020
    Posts:
    65
    Hello Everyone and Happy New Years,

    I am currently working on a small task, where I have two scripts; Script A and Script B.
    In Script A a collision happens and in Script B a robotic agents receives sensory input.
    Now when the collision happens I would like to stop or suspend the sensor for 20 frames.
    I was thinking of setting up a global Boolean, which turns true after collision occurs in Script A and then check every frame in script B via Void Update, whether this global Boolean is true.
    Now how could I define such a global variable that checks in Script B whether its true or false ?

    Script A Collision:
    Code (CSharp):
    1. if (touchedSphere == targetObjects[checkActive(gameSequence)])
    2.             {
    3.               Global Bolean = True
    4. }
    5.  
    Script B :
    Code (CSharp):
    1.  
    2. void Update()
    3.     {
    4.        Check whether global Boolean is True
    5.     }
    6.  
     
    zhisaoka likes this.
  2. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,498
    Code (CSharp):
    1. public class ClassA : MonoBehaviour
    2. {
    3.   public static bool theGlobalBool = false;
    4. }
    5. [...]
    6. public class ClassB : MonoBehaviour
    7. {
    8.   void Start()
    9.   {
    10.     ClassA.theGlobalBool = true;
    11.   }
    12. }
     
    weight_theta likes this.
  3. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,498
    Note that using a static variable means ALL instances of ClassA share the same value, as static means the variable is part of the class itself (an instance of it that says
    theGlobalBool = true
    is setting the "global value"). If you want each to have their own value AND be globally accessible you'll need to create something like this..
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. public class ClassA : MonoBehaviour
    4. {
    5.   public bool individualBool = false;
    6.   public static List<ClassA> instances = new List<ClassA>();
    7.   void Awake()
    8.   {
    9.     instances.Add(this);
    10.   }
    11.   void OnDestroy()
    12.   {
    13.     instances.Remove(this);
    14.   }
    15. }
    16. public class ClassB : MonoBehaviour
    17. {
    18.   void Update()
    19.   {
    20.     // hit spacebar to list all instances
    21.     if (Input.GetKeyDown(KeyCode.Space))
    22.     {
    23.       Debug.Log("instances of ClassA:");
    24.       foreach (ClassA instance in ClassA.instances)
    25.       {
    26.         Debug.Log("- " + instance.name + ": " + instance.individualBool);
    27.       }
    28.       /* ..or this way, to iterate with an index:
    29.       for (int i = 0; i < ClassA.instances.Count; i++)
    30.       {
    31.         Debug.Log("- " + ClassA.instances[i].name + ": " + ClassA.instances[i].individualBool);
    32.       }
    33.       */
    34.     }
    35.   }
    36. }
    Edit: corrected where I didn't use ClassA.instances in ClassB
    Edit 2: corrected something else (sorry, just wrote this for u in the forum edit box)
     
    zhisaoka and weight_theta like this.
  4. weight_theta

    weight_theta

    Joined:
    Aug 23, 2020
    Posts:
    65
    If I copy the game objects would they interfere with each other when using a global static ? That is would both objects reference the same boolean value or does each object reference their own boolean independent of each other ?

     
  5. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,498
    Yes if you want the easy way, the value is global but shared by all instances. If you want a value of a specific instance, you'll need a reference to it. By using List as demonstrated, you avoid needing to traverse any hierarchy or otherwise search for matches by tag and so on (either of which would be very slow performance by comparison).
     
    weight_theta likes this.
  6. weight_theta

    weight_theta

    Joined:
    Aug 23, 2020
    Posts:
    65
    So if Object A performs an action that turns the condition True, Object B will as a result also think that the condition is True? That is problematic. Is there a way to make sure that they each reference their own Boolean ?
     
  7. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,498
    Yes - each instance's value of individualBool in the above example would belong to that object only and if you change the value in either ClassA or in ClassB by saying
    instance.individualBool = true;
    , no other object's individualBool value would change at the same time.. each object has it's own individualBool value.
     
    weight_theta likes this.
  8. weight_theta

    weight_theta

    Joined:
    Aug 23, 2020
    Posts:
    65
    Mh I am not that knowledge about this, but I just tested the public static boolean and since both objects run their own script, I think both objects define their own static variable. Could that be the case ? I see two distinct true and false prints for each. Could I be wrong?
     
  9. seejayjames

    seejayjames

    Joined:
    Jan 28, 2013
    Posts:
    685
    Only declare one static bool of a given name. It can be in any script, and will persist through the entire game (even if the script is destroyed).

    In this case, you don't need a global/static, you could simply have a bool in script B called isSuspended, and when script A senses the collision, set it to true. In Update() in script B, if the bool is true, start a counter, etc. Lots of ways to do it.
     
    adamgolden likes this.
  10. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,498
    +1

    I have a bad habit of answering by topic and just skimming OP :rolleyes:

    Code (CSharp):
    1. void OnCollisionEnter(Collision collision)
    2. {
    3.     ClassA hitClassA = collision.collider.GetComponent<ClassA>();
    4.     if (hitClassA != null)
    5.     {
    6.       hitClassA.yourBool = true;
    7.     }
    8. }
    The above assumes your collider is attached to the same GameObject as your ClassA component, and the OnCollisionEnter function is in your ClassB class.
     
    seejayjames likes this.
  11. zhisaoka

    zhisaoka

    Joined:
    Feb 27, 2021
    Posts:
    1
    How do I add or change bools? Or if I were to reference a bool added which class would I take it from? ClassA or ClassB?

    In my case, I have 2 teams, TeamA, and TeamB. TeamA is controlled by a UI, there is "Attack", "Defend", and "Retreat. How it works is once you get more resources and gold you can buy or summon troops just like the game "Stick War Legacy".

    My problem is, in order to give them orders I need to change a bool value and I want to be able to change their orders all at once using the UI, And individually by clicking on them individually. But the bool is in the AI script and I can't reference all the troops at once in the Button seen in the UI.

    So far I added an empty, renamed it "BlueUnitHandler" and gave it the script you made, but how do I access this in the AI script for the units so they detect if the bool changes and follow orders? And how do I change the bool value by pressing a button in the UI?

    I have been trying to fix this for 2 days, any help would be greatly appreciated. I am new to Unity and C# so I'm sorry if there is an obvious answer
     
  12. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    Please don't necro post to old threads. It's against forum rules. Make your own new post, it's FREE.

    Referencing variables, fields, methods (anything non-static) in other script instances:

    https://forum.unity.com/threads/hel...-vars-in-another-script.1076825/#post-6944639

    https://forum.unity.com/threads/accessing-a-gameobject-in-different-scene.1103239/

    REMEMBER: it isn't always the best idea for everything to access everything else all over the place. For instance, it is BAD for the player to reach into an enemy and reduce his health.

    Instead there should be a function you call on the enemy to reduce his health. All the same rules apply for the above steps: the function must be public AND you need a reference to the class instance.

    That way the enemy (and only the enemy) has code to reduce his health and simultaneously do anything else, such as kill him or make him reel from the impact, and all that code is centralized in one place.
     
  13. seejayjames

    seejayjames

    Joined:
    Jan 28, 2013
    Posts:
    685
    "For instance, it is BAD for the player to reach into an enemy and reduce his health.
    Instead there should be a function you call on the enemy to reduce his health."

    I mostly agree, but at some point, isn't that the same thing? Except that the function could be called by other actors, which could be handy, sure. But if you know you never need those, why not just change the property directly, since that's what the function is doing? Just curious.
     
  14. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    What if you suddenly decide that enemy should flash when he gets hit?

    With a function you know you can do it in one spot (generally).

    With 27 different call sites all going
    enemy.health--;
    the solution becomes more difficult. Not impossible... because enemy could observe the health loss on its next Update() and flash, but that would be a deferred effect.

    Besides, it isn't the attacker's business what the enemy does with the damage... the enemy could say "HA! Magic damage? I'm 50% immune to that!" You don't want THAT code splattered around 27 different call sites.

    What if you implement shields that must be stripped away first, then damage happens?

    etc.
    I could go on.