Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question use global variable

Discussion in 'Scripting' started by Silviorakhaf, May 6, 2024.

  1. Silviorakhaf

    Silviorakhaf

    Joined:
    Nov 25, 2023
    Posts:
    9
    I'm new to Unity, I'm trying to use a global variable between classes, but no matter what I do, I can't put the information about this variable in a tmp, the classes that access the variable can read the value, but where it is created, it can't return the value.
    No matter which class, I can't link the global variable to the TMP

    Please Help.....

    classe residencial.....


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using TMPro;
    4. using UnityEngine;
    5.  
    6. public class Residencial : MonoBehaviour
    7. {
    8.     public int populacao = 100;
    9.     public GameObject tela;
    10.     private Grid grid;
    11.     public int pop = 0;
    12.  
    13.  
    14.     // Start is called before the first frame update
    15.     void Start()
    16.     {
    17.         tela.GetComponent<Manager>().Residtotal += populacao;
    18.          grid = FindObjectOfType<Grid>();
    19.      }
    20.  
    21.     // Update is called once per frame
    22.     void Update()
    23.     {
    24.        
    25.     }
    26.     private void OnMouseOver()
    27.     {
    28.      }
    29.     private void OnMouseDown()
    30.     {
    31.    
    32.         tela.GetComponent<Manager>().Residtotal -= populacao;
    33.         Destroy(this.gameObject);
    34.  
    35.     }
    36. }
    37.  

    Class Manager

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using TMPro;
    4. using Unity.VisualScripting;
    5. using UnityEngine;
    6.  
    7.  
    8. public class Manager : MonoBehaviour
    9. {
    10.  
    11.     public TMP_Text populacaotmp;
    12.     //public GameObject tela;
    13.     public int Residtotal = 0;
    14.     public int Comertotal = 0;
    15.     public int Industotal = 0;
    16.     public int utiltotal = 0;
    17.     // Start is called before the first frame update
    18.     void Start()
    19.     {
    20.        
    21.     }
    22.  
    23.     // Update is called once per frame
    24.     void Update()
    25.     {
    26.         // print(Residtotal);
    27.         //   print(tela.GetComponent<Manager>().Residtotal);
    28.         // populacaotmp.SetText(tela.GetComponent<Manager>().Residtotal.ToString());
    29.     }
    30. }
    31.  
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,010
    C# does not support global variables.

    The closest thing is a static variable in a class.

    Unity cannot do anything with static variables vis-a-vis the inspector system because static variables cannot be serialized like instance variables.



    Instead, this is how to do things in Unity3D:

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

    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/

    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.



    Another pseudo-global approach is to create ScriptableObjects containing your "global variables" and drag references to those ScriptableObject instances into all scripts / objects that need them.


    Generally speaking, don't do this sort of code:

    Keep in mind that using GetComponent<T>() and its kin (in Children, in Parent, plural, etc) to try and tease out Components at runtime is definitely deep into super-duper-uber-crazy-Ninja advanced stuff.

    Here's the bare minimum of stuff you absolutely MUST keep track of if you insist on using these crazy Ninja methods:

    - what you're looking for:
    --> one particular thing?
    --> many things?
    - where it might be located (what GameObject?)
    - where the Get/Find command will look:
    --> on one GameObject? Which one? Do you have a reference to it?
    --> on every GameObject?
    --> on a subset of GameObjects?
    - what criteria must be met for something to be found (enabled, named, etc.)

    If you are missing knowledge about even ONE of the things above, your call is likely to FAIL.

    This sort of coding is to be avoided at all costs unless you know exactly what you are doing.

    Botched attempts at using Get- and Find- are responsible for more crashes than useful code, IMNSHO.

    If you run into an issue with any of these calls, start with the documentation to understand why.

    There is a clear set of extremely-well-defined conditions required for each of these calls to work, as well as definitions of what will and will not be returned.

    In the case of collections of Components, the order will NEVER be guaranteed, even if you happen to notice it is always in a particular order on your machine.

    It is ALWAYS better to go The Unity Way(tm) and make dedicated public fields and drag in the references you want.
     
    Silviorakhaf likes this.
  3. Silviorakhaf

    Silviorakhaf

    Joined:
    Nov 25, 2023
    Posts:
    9
    What I was trying to do is a village type game, in this case each building contains a population, and I was trying to show the total. If I can't use global variable, what could I use.
    I just read it quickly, here it's past 10Pm.
     
  4. Silviorakhaf

    Silviorakhaf

    Joined:
    Nov 25, 2023
    Posts:
    9
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,010
    Fine, then I'll just write quickly: Google.

    Imphenzia: How Did I Learn To Make Games:

     
    Bunny83 likes this.
  6. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,455
    There are two basic approaches: static classes and singletons.

    Code (csharp):
    1. public static class Manager
    2. {
    3.     public static int Residtotal = 0;
    4.     public static int Comertotal = 0;
    5.     public static int Industotal = 0;
    6.     public static int utiltotal = 0;
    7. }
    Accessing:
    Code (csharp):
    1. Manager.Residtotal += populacao;

    Code (csharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. // Kurt Dekker's singleton - https://gist.github.com/kurtdekker/775bb97614047072f7004d6fb9ccce30
    6.  
    7. public class SingletonSimple : MonoBehaviour
    8. {
    9.     private static SingletonSimple _Instance;
    10.     public static SingletonSimple Instance
    11.     {
    12.         get
    13.         {
    14.             if (!_Instance)
    15.             {
    16.                 _Instance = new GameObject().AddComponent<SingletonSimple>();
    17.                 _Instance.name = _Instance.GetType().ToString();
    18.                 DontDestroyOnLoad(_Instance.gameObject);
    19.             }
    20.             return _Instance;
    21.         }
    22.     }
    23.  
    24.     public int Residtotal = 0;
    25.     public int Comertotal = 0;
    26.     public int Industotal = 0;
    27.     public int utiltotal = 0;
    28. }
    29.  
    30.  
    31.  
    32. public static class Manager
    33. {
    34.     public static int Residtotal = 0;
    35.     public static int Comertotal = 0;
    36.     public static int Industotal = 0;
    37.     public static int utiltotal = 0;
    38. }
    Accessing:
    Code (csharp):
    1. Manager.Instance.Residtotal += populacao;
     
    Bunny83 likes this.
  7. Silviorakhaf

    Silviorakhaf

    Joined:
    Nov 25, 2023
    Posts:
    9
    Worked. Thank you very much, I had searched but only the singleton appeared, and in what I found, it gave an error (later I'll come back to it), but the static class worked very well. Thank you very much.