- Home /
Help with Making A Variable Global in a Scene
The game I'm developing currently is basically a board game with hexagonal spaces, but what type of space they are is randomized, so I need to keep a 2D array of their positions and what's on them. This variable needs to be instanced to the scene and not persist through scenes, and be able to have its value edited and have that changed throughout all of the other scripts that have referenced it. I've been looking online for a solution but what I've found so far has persisted through scenes or been unable to be edited. So far I've been using a GameManager script that contains this, and I've attached that to an empty GameManager object. However, when it comes to getting this array from other scripts, I haven't figured out a good way to do it. I think that I could use GameObject.Find("GameManager").GetComponent<GameManagerScript>().hexagonIndex
but I've had experience with programming before and that seems messy and bad practice. Is there any way that I could allow the hexagonIndex
array variable to be accessed by other scripts in the scene, and when I change the value of hexagonIndex
in one script, have it change in another? Could I use scriptable objects for this? (I've looked online and I'm not sure if they're the best for this)
Answer by unity_ek98vnTRplGj8Q · Feb 01, 2021 at 09:10 PM
I would say that using GameObject.Find("GameManager").GetComponent<GameManagerScript>().hexagonIndex
is kind of bad practice, but not that bad if you are using it correctly. If it was me making the game I wouldn't feel to bad about using this line of code, you just have to make sure you only use it in the start method of each object as calling this line of code in the update method is going to chew resources. You can save off the resulting reference as a private variable in each script so that it doesn't have to re-find the GameManager object each time you need it. To clarify, you need to cache the GameManager component: GameManager gm = GameObject.Find("GameManager").GetComponent<GameManagerScript>();
then grab the array out whenever you want to use it: gm.hexagonIndex
. Don't cache the array itself as it won't be updated.
This will get you basically what you want but there are some improvements you could make as you see fit:
Instead of calling GameObject.Find use GameObject.FindObjectOfType so that it finds the GameManager script directly, and so that it doesn't get confused if another game object is accidentally named GameManager
Wrap your 2D array in a class so that it is easier to modify from other scripts. Since a 2D array is a primative type in C# it is pass by value, so to modify it from another script you would have to do something like
var hexArray = gm.HexagonIndex; //Modify hexArray gm.HexagonIndex = hexArray; //Save it back to the gameManager
Whereas if you were to use something like a list of lists List<List<GameObject>>
then you could just modify it without having to save it back at the end, since Lists are classes and therefore pass by reference.
You could make you GameManager a Singleton, where you save the reference to the GameManager as a static variable so that other scripts could access it statically instead of having to find a reference to the GameManager object by looking in the scene, replacing your GameObject.Find() call with GameManager.Instance()
Your answer
![](https://koobas.hobune.stream/wayback/20220613024356im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
custom defines not reflected in Mono 1 Answer
Global Variables 3 Answers
how to: make global variable 2 Answers
keep static/global object through scenes 1 Answer
Static variables and Design Fundamentals (singleton) 1 Answer