Introduction
In this article we are going to see different ways to find the references of GameObject and Components that are in the scene in Unity to use them inside a Script, this is something important because if we can access the object, we can manipulate it and any of its components as we need.
The following video is the introduction to REFERENCES in UNITY
What is our goal?
We are looking to find the reference of a GameObject that is in the hierarchy inside a Script and print the name of this GameObject on the console to check if it was successful. To do this we will use the Script shown in figure 1, simply define a GameObject type data called “objectToFind” in line 8 and then within the Start function print the name of this GameObject in console (line 13).
The hierarchy of the scene that we are going to use is composed by the GameObjects that are observed in figure 2, the object “Script-GameObject” is the one that has assigned the Script of figure 1 and is the one that will be in charge of finding the references, in figure 3 you can see the inspector of this GameObject and the Script.
The object “GDT (Object to Find)” will be one of the objects we have to find, so if we are successful we should see that name printed on the console.
Observation
If we enter the game mode at this point, in the console we will have an error of type “NullReferenceException”, because the object to which we want to read its name is a non-initialized object, ie with null state. In the figure 4 we see an example of the error that would appear in this case.
Method 1: Declaration of the field with public visibility
The fields and variables that are declared within a script can have three types of visibility: “public”, “private” and “protected”. Let’s consider only the cases of private and public visibility. In the first case, the field declared as private will not be accessible from contexts outside the script in which it is defined, while if it is declared with public visibility, this data can be accessed from other scripts and in Unity these fields will also be visible in the inspector.
In figure 1 we declared a GameObject type field called “objectToFind” without indicating its visibility, by doing this we are implicitly declaring it as private, in figure 5 instead we add “public” in front to indicate that it has public visibility.
Comparing figures 3 and 6 we see that now the field “objectToFind” appears in the inspector, which means that we can manually assign the GameObject we want to be in that field, in other words assign the object’s reference. This can be done in two ways, one is by taking the GameObject from the hierarchy and dragging it into the field, while the other way is by using the icon of the circle with the dot on the right of the field (in figure 6 or 7), this will display a window where we can choose the object we want to assign.
When we enter the game mode we see the console message that shows the name of the object that was assigned in the field, this confirms that we have the reference of the GameObject and we can use it inside the Script.
Alternative: Declare the field as private but serialized
If you want to keep the visibility private there is an alternative for the field to appear in the inspector, is to add “[SerializeField]” before the declaration, as shown in Figure 9.
Method 2: Find the reference of a GameObject from the scene by its name
If we know the name of the GameObject we want to find we can use that information to find the reference in our Script. To do this we use the “Find” method from the GameObject class and pass the name of the object we want to find as a parameter, as shown in figure 10.
When that instruction is executed, Unity will go through the whole hierarchy looking for a GameObject with that name, if it finds it it returns it and the reference remains in the variable “objectToFind”, but if it does not find it this variable will have a null value and will give us the error of “NullReferenceException” if we try to access it.
To keep in mind, if we have more than one object that has exactly the same name, Unity will return the first one it finds in its register, this can lead to ambiguities, that is, we could obtain the reference of a different object from the one we are looking for.
To avoid embedding data directly into the functions what you can do is define a string with the name of the object you want to find and then execute the function “Find” passing as a parameter the string, as seen in Figure 11, that way we avoid doing hard-coding.
Method 3: Find the reference of a GameObject from the scene by its Tag
One of the elements that all GameObject has in Unity is a Tag, it is in the header of the inspector, as we see in figure 12. We can use this tag to find the GameObject reference of the scene in our Script.
By default the GameObjects will have assigned the Tag “Untagged”, but we can assign one of the Tags that come predefined or create new Tags, in the figures 12 and 13 I show how to create a new Tag in Unity.
Once we have created the Tag we have to assign it to the object, we select again the GameObject in the inspector and choose the tag from the tag window, as you can see in figure 14.
Now we are ready to find that GameObject using the Tag, for that we execute the “FindGameObjectWithTag” method from the GameObject class and we pass as parameter the name of the Tag we want to search. In the figure 15 we see this instruction in the line 16, notice that the name of the Tag has been defined in a String in the line 11 and then in the line 16 we pass as parameter the variable.
When this instruction is executed, Unity will check all the objects in the hierarchy until it finds a GameObject with that tag assigned, at that point it returns the object and it is stored in the “objectToFind” field. If no object has that tag, the “objectToFind” field will have a null value.
To keep in mind, if we have more than one GameObject that has the same Tag assigned, Unity will return the first one of them that it finds in its register, in this case some ambiguities could arise, we could obtain the reference of a different object from the one we want.
Method 4: Refer to the same GameObject to which the script is assigned
If the GameObject we want to use within our Script is precisely the same GameObject to which the Script is assigned the reference is already defined within an internal field of the MonoBehaviour class, the field is called “gameObject” (first letter with lower case), this name refers to the same object to which the Script is assigned.
In this case it would not be necessary to define the field “objectToFind”, however we will initialize it as we have been doing until now. In line 17 we see that we assign “gameObject” to “objectToFind”.
When entering the game mode we see in the inspector (Figure 17) that the object that is in the field “Object To Find” is the same object that is assigned to the script.
Method 5: Find the reference of a GameObject that is a child of another GameObject
Maybe we are interested in obtaining the reference of a GameObject that we know is as a child of another GameObject whose reference we have, for example in figure 18 we see that the object to be found is as a child of the GameObject that has the script assigned to it, so if we have the reference of the father object we can access it and apply different actions on it, including accesing to its childs.
The “transform” field is another variable that is defined in all MonoBehaviour and refers to the Transform component of the GameObject to which the script is assigned.
We can use the Transformation to access the children that have that GameObject, using the GetChild() method with parameter 0 of the Transform class, this results in the transformation of the first child that has the GameObject to which this script is assigned, but as we are interested in obtaining the reference of the GameObject not its Transformation, we use the dot operator and the “gameObject” field.
The instruction is as shown in line 18 of figure 19.
Method 6: Find the reference of a GameObject that has a specific component
If we know that the GameObject we are interested in finding has a specific component assigned to it, such as a “Camera”, “Rigidbody”, “AudioSource” component or a script we have created ourselves, we can use that knowledge to find the GameObject reference.
I will create a script called “SomeScript” and assign it to the GameObject we want to find, as shown in figures 20 and 21.
Using the instruction “FindObjectOfType()”, where T is the type of object we are looking for (in our case it is “SomeScript” type), we can find the reference of the “SomeScript” instance that is assigned to that GameObject, then using the dot operator we can access the GameObject to which that Script is assigned.
The instruction that does all this can be seen in line 20 of figure 22.
When this instruction is executed, Unity will check all the objects in the hierarchy and each one of its components until it finds a “SomeScript” type object, when it finds it it returns it as a result, but since we are interested in the GameObject to which that Script is assigned, we use the dot operator and access the “gameObject” field. If there is no object that has the “SomeScript” component assigned to it we will have a null reference error.
To keep in mind, if we have more than one GameObject that has assigned the component we are looking for, Unity will return the first component that it finds in its register, in this case ambiguities could arise, we could obtain the reference of a different object to the one we want.