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

Changing bools in other GameObject scripts with if statements

Discussion in 'Scripting' started by JD_Designer, Jun 8, 2016.

  1. JD_Designer

    JD_Designer

    Joined:
    Sep 1, 2015
    Posts:
    111
    Hello,

    Thanks in advance for your help. I'm very new to this but one has to start somewhere. I'm trying to write two C# scripts on two separate game objects that will let me toggle a bool via an IF statement in one of the scripts. I've read a lot of posts about GetComponent and GameObject.Find and it all seems pretty intuitive. However when I try and write my own code Unity throws me errors. I'm sure I'm just breaking a syntax rule (or several) but as a rookie It's eluding me. My code is bellow.

    This is the first script which holds the bool I want to flip with an IF statement in the second script. This script is named BoolKeeper and is attached to an object named BoolKeeper. Maybe it's not great that I named the game object and script the same name? Anyway, have a look.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class BoolKeeper : MonoBehaviour
    5. {
    6.     public bool rightRacketCollision;
    7.  
    8.      void Update ()
    9.     {
    10.         Debug.Log ("rightRacketCollision is " + rightRacketCollision);
    11.     }
    12. }
    This is the second script that is a component of a different game object. In this script I try and use an IF statement to flip "rightRacketCollision" in the first script (to no avail).

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class SetRightRacketBool : MonoBehaviour
    5. {
    6.     public bool test;
    7.     bool rRacketCollision = GameObject.Find(BoolKeeper).GetComponent<BoolKeeper>().rightRacketCollision;
    8.    
    9. void Update ()
    10.     {
    11.         if (test = true)
    12.         {
    13.             rRacketCollision = true;
    14.         }
    15.         else
    16.         {
    17.             rRacketCollision = false;
    18.         }
    19.     }
    20. }
    I'm hoping that when I toggle the public "test" bool in the inspector (on script two), I should see my log ("rightRacketCollision is true/false") from the first script. What am I doing wrong? Many thanks.
     
  2. magnite

    magnite

    Joined:
    Dec 12, 2012
    Posts:
    125
    1. In your second script, you should do your GameObject.Find in the start method. After you find the object store it in a variable and make sure what you got was not null, if it was then you will not be able to get any components and it will throw and error.
    2. BoolKeeper in the Find parameters needs to be in quotes because you are looking for a GameObject not a Type.
    3. Your in your If statement boolean expression you are using the wrong operator.

    "test = true" will always just set test to true. then evaluate the new value of test which will always be true. Instead you will want to use "test == true" to check if test is the value true.
     
    JD_Designer likes this.
  3. JD_Designer

    JD_Designer

    Joined:
    Sep 1, 2015
    Posts:
    111
    Thanks so much for the quick response! I'm a bit confused though...

    Here is the revised script.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class SetRightRacketBool : MonoBehaviour
    5. {
    6.     public bool test;
    7.  
    8.     void Start()
    9.     {
    10.         bool rRacketCollision = GameObject.Find("BoolKeeper").GetComponent<BoolKeeper>().rightRacketCollision;
    11.     }
    12.  
    13.     void Update ()
    14.     {
    15.         if (test == true)
    16.         {
    17.             rRacketCollision = true;
    18.         }
    19.         else
    20.         {
    21.             rRacketCollision = false;
    22.         }
    23.     }
    24. }
    This is still not working. Isn't it true that if I define the bool rRacketCollision with GameObject.Find in the Start method, it's no longer a member variable and cannot be accessed by Update? Thank you so much for your help!
     
  4. nelson218

    nelson218

    Joined:
    Jun 7, 2016
    Posts:
    11
    Your confuessed..
    Code (CSharp):
    1. bool rRacketCollision = GameObject.Find("BoolKeeper").GetComponent<BoolKeeper>().rightRacketCollision;
    these line will return you the value of rightRacketCollision.
    you don't want that. What you want is reference of that script and then change bool value using that reference.
    Other thing is
    Code (CSharp):
    1. bool rRacketCollision
    is Local variable. you won't be able to use it Inside Update

    Do it like these

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class SetRightRacketBool : MonoBehaviour
    4. {
    5.     public bool test;
    6.     private BoolKeeper _refBoolKeeper;
    7.     void Start()
    8.     {
    9.        //first take the reference of that scipt
    10.        _refBoolKeeper= GameObject.Find("BoolKeeper").GetComponent<BoolKeeper>();
    11.     }
    12.     void Update ()
    13.     {
    14.         if (test.== true)
    15.         {
    16.             _refBoolKeeper.rRacketCollision = true;
    17.         }
    18.         else
    19.         {
    20.             _refBoolKeeper.rRacketCollision = false;
    21.         }
    22.     }
    23. }
     
    payalzariya and JD_Designer like this.
  5. JD_Designer

    JD_Designer

    Joined:
    Sep 1, 2015
    Posts:
    111
    @nelson218: Perfect! This makes complete sense and it worked like a charm. Many thanks! I have a quick question though. When you declare the variable for the script reference (private BoolKeeper _refBoolKeeper) I'm confused why you have to use the name of the script (BoolKeeper) to indicate the the variable type is a class. I'm new to scripting obviously but is there not a generic variable type for class like there is for int, float, string, etc? In any case thank you so much.
     
    Last edited: Jun 8, 2016
    payalzariya likes this.
  6. nelson218

    nelson218

    Joined:
    Jun 7, 2016
    Posts:
    11
    @JD_Designer see it's just a name. You can call it anything from xyz or JD_Designer also. But its good practice that the variable name should be meaningful. And I use ref in front of any variable if its a reference of any custom class eg class BoolKeeper.
    I didn't understand what your trying say with int, float
     
  7. JD_Designer

    JD_Designer

    Joined:
    Sep 1, 2015
    Posts:
    111
    Thanks. Yes, I understand that _refBoolKeeper is the name we are assigning to a variable that holds my script. My confusion is about the use of BoolKeeper when we declare that variable.

    From what I understand so far, when declaring a variable you must first define the type/kind of variable it is.
    Eg: int myInt = 5;
    By inserting "int" we are declaring a variable that will be an integer. So what is happening when we insert BoolKeeper?
    Code (CSharp):
    1. //we declare a bool and name it test
    2. public bool test;
    3.  
    4. /*we declare a variable that will refference the script named BoolKeeper
    5. and we give that variable the name _refBoolKeeper.  But why are we using the
    6. name of my script (BoolKeeper)as the type of variable to be declared?  Especially
    7. since we assign BoolKeeper (the name of my script) to _refBoolKeeper in Start
    8. with GameObject.Find and GetComponent?*/
    9. private BoolKeeper _refBoolKeeper;
     
    Last edited: Jun 9, 2016
  8. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,146
    BoolKeeper _refBoolKeeper just means its an instance of the BoolKeeper class.

    So just like you could have
    int x = 1;
    int y = 2;

    You could have
    BoolKeeper bk1;
    BoolKeeper bk2;

    That way if you change something in bk1, it doesn't change values in bk2.
     
    JD_Designer likes this.
  9. JD_Designer

    JD_Designer

    Joined:
    Sep 1, 2015
    Posts:
    111
    Thanks for the response! So sorry. I'm trying to wrap my head around this. So when we insert BoolKeeper as part of our variable declaration, we are creating a variation of my script BoolKeeper and naming it _refBoolKeeper. But if this statement means _refBoolKeeper = an instance of BoolKeeper, then why do I have to GetComponenet<BoolKeeper>(); in Start?
     
    Last edited: Jun 9, 2016
  10. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,146
    You have to assign a value to your BoolKeeper variable, or in this case, your instance, which is on your object.
    BoolKeeper bk1 doesn't reference anything, it's just a variable, so it's not usable as it is. You need it to point towards something. You use getcomponent to tell it what it references.

    If you have two objects with BoolKeeper on them

    BoolKeeper bk1 = target1.getComponent<BoolKeeper>();
    BoolKeeper bk2 = target2.getComponent<BoolKeeper>();

    Would be an example of how you might use it. Now, you can do a singleton which would allow you to not use getComponent if you only have one copy of that script in your scene, but you'll have to look that up if you're interested.

    The use of variables, classes, and instances are probably good things to learn since they are apart of many programming languages.
     
  11. JD_Designer

    JD_Designer

    Joined:
    Sep 1, 2015
    Posts:
    111
    Thanks Brathnann! I'm going to have to let this percolate a bit, but I think it's starting to click.