Communication between Scripts – Examples in Unity

Introduction

In this article we are going to see how to use functions that are defined in a Script from any other Script.

Communication between Scripts is an informal name for this problem, it means that being in one Script we will be able to access the context of another Script.

This is important, especially for creating object-oriented solutions, as it allows us to have specialized scripts that take care of specific tasks and allow other scripts to make use of that functionality.

English subtitles available for the video about communication between scripts.

What should we take into account?

Before looking at a particular application, I leave a list of points to keep in mind that I think are important to understand the whole foundation behind the communication between Scripts.

About the Scripts

In this case we are going to see an example in Unity, so the two Scripts we are going to use are going to be an extension of the MonoBehaviour class. This in practical terms means that when the game starts, a Start() method will be executed and in each frame of the game the Update() method will be executed.

About the execution of Scripts

For these scripts to run, they must be assigned to one or more GameObjects in the hierarchy. In other words, there must be an Instance of the class defined in the Script.

Instances of a class

When we add the same Script to two different GameObjects we are creating two separate instances of the class, i.e. two objects that are going to be similar because they belong to the same class, but their state will not necessarily be the same.

Having the reference of an object

This is one of the fundamental points to pay attention to and try to understand in depth.

Objects are the instances of a class and in order to access its functionality we must have the reference of this object, that is to say to find it among all the objects present in the program and to have it stored in a field to be able to use it.

This is similar to when we want to use a variable, we need to have that variable defined to use it in the Script.

The Dot Operator

The dot operator in several programming languages allows us to access the fields and methods defined as public within a class.

If we have the object reference, we can use the dot operator to execute any of its public methods or read and write any of its public fields.

Practical example of Communication between Scripts in C# – Unity

Previous Steps

In any Unity project we create two Scripts, ScriptA and ScriptB, in the first one we define the function that will be executed from the other Script.

c sharp scripts that communicate with each other in unity
Fig. 1: We create two scripts called ScriptA and ScriptB.

In the hierarchy we are going to create two empty GameObjects to be able to create instances of both Scripts.

hierarchy of a project in unity, gameobjects
Fig. 2: Create two Empty GameObjects in the hierarchy to contain both Scripts.

In the GameObjectA we add as component the ScriptA and to the GameObjectB the ScriptB. We can do this from the inspector with the Add Component button or doing drag and drop.

add component button to add components to the gameobjects in unity
Fig. 3: Select object A and in the inspector, using Add Component, add ScriptA to its components.
inspector of a gameobject in unity, drag and drop of components
Fig. 4: Another way to add components is to drag them directly into the GameObject inspector.

Code inside the Scripts

Let’s write the instructions we’ll use to resolve communication between Scripts. In this case I use Visual Studio as a code editor.

We opened both scripts and found some code already written.

c sharp default scripts in unity
Fig. 5: We open both Scripts in some editor. We can see some code already written.

In the first Script we are going to write the following code:

communication between two scripts in unity, a script executes a function defined in another script
Fig. 6: Fields and methods belonging to Script A.

A public string called “name” that will help us identify which instance it is.

Two methods called Function1 and Function2, the first public and the second private.

The public method will be the function that we will be able to execute from any other Script using the dot operator.

As we can see in figure 6 what it does is to print in console what the Function2 method returns. This method returns a concatenated text that allows us to see who is executing the Function1 method and which instance of the ScriptA class it is. This will be better understood later.

Now we are going to work on Script B, which will be the one that calls the function defined in the other Script A. In figure 7 we see the ScriptB instructions.

communication between two scripts in unity, a script executes a function defined in another script
Fig. 7: Fields and methods belonging to Script B.

We define a string to assign a name and know which instance it is.

To be able to execute functions defined in another Script we must have the reference of the object that is instance of that class. So we have to define a ScriptA type object to which we give the name “scriptA” (first letter with lowercase), as we see in line 13 of figure 7.

This is only half of the work, we have declared that the ScriptB is going to have a reference of a ScriptA type object, but we have not yet found such a reference.

To find the reference of an object in a Script there are several ways, in this case I will use the method FindObjectOfType<> of MonoBehaviour, to this method we enter the type of object you have to look for and will return the reference of the first object of that type that you find in the hierarchy. See line 18 of figure 7.

See other ways to find references in Unity (YT)

Finally, we execute the function defined in the other Script A from this Script B (line 20 of figure 7).



Dot Operator

As mentioned before, the dot operator will allow us to access all the fields and public methods defined within the class.

In figures 8 and 9 we see that using the reference of the object of Script A followed by a point, we can see the list of fields and methods that we can use.

In figure 8 we see the name field that was the string defined as public in the ScriptA and in figure 9 we see the Function1 method, also defined as public. What we don’t see is the Function2 method since it was declared as private.

operator point to access fields and public methods defined in a script, basic programming, unity
Fig. 8: The dot operator allows us to read and write the “name” field, which is a string defined as public.

operator point to access fields and public methods defined in a script, basic programming, unity
Fig. 9: The point operator allows us to execute the “Function1” method defined as public.

First exectution test

Before hitting the Play button, we select GameObjects A and B and enter names in the “name” fields that let us know what the object is.

The Script A instance will be called “George (A)” and the Script B instance will be called “Mike (B)”, as we see in figures 10 and 11.

inspector of a gameobject in unity, scripts that communicate with each other, basic programming in unity
Fig. 10: In the GameObjectA inspector, we put a name to know that it is that instance of the Script A class.

inspector of a gameobject in unity, scripts that communicate with each other, basic programming in unity
Fig. 11: In the GameObjectB inspector, we put a name to know that it is that instance of the Script B class.

When running the game we see in the GameObjectB inspector that the ScriptA field now shows an object (unlike figure 11 where it said “none”).

This means that the ScriptB was able to find the ScriptA reference.

Figure 13 shows the on-screen message, printed by the ScriptA Function1 method, which was called from the ScriptB.

The message says: “Mike(B) has executed my Function1. I’m George(A), by the way.

inspector of a gameobject in unity, scripts that communicate with each other, basic programming in unity
Fig. 12: When running the game, the ScriptA object reference is found due to the FindObjectOfType<> instruction.

print console messages in unity, scripts that communicate with each other, basic programming unity
Fig. 13: This message is printed because a method defined in ScriptA is executed from the ScriptB.


Second exectution test

Let’s go a little deeper into the concept of programming object as an instance of a class.

Choose GameObject A from the hierarchy and add a second instance of the ScriptA class using the “Add Component” or drag and drop button.

This second instance will be called “Luke (A)”, in figure 14 we see both instances of the class.

inspector of a gameobject in unity, scripts that communicate with each other, basic programming in unity
Fig. 14: A second instance of the ScriptA class is added to the GameObjectA with a different name.

When running the game as it is, we see in the console that Mike (B) has executed the Function1 method of Luke (A), see figure 15.

What has happened here is that the FindObjectOfType<> instruction in line 18 of figure 7, has found the reference of a single ScriptA type object, which we have called Luke (A).

print messages in console in unity, communication between scripts, basic programming unity
Fig. 15: When running the game we now see that the Function1 method of the instance called Luke is being executed.

We are going to modify the code in ScriptB so that it is able to find all the ScriptA references in the scene and execute the Function1 method of each one of them.

The problem solved is shown below:

c sharp script that executes functions defined in other scripts, e.g. in unity, communication between scripts
Fig. 16: We modify the ScriptB in this way so that it executes the functions of the two instances of ScriptsA.

In the object declaration we have now defined an array or vector of ScriptA type objects (line 13 figure 16), this means that we will be able to save many references of ScriptsA objects.

In line 18 of figure 16 the change is rather subtle, instead of running FindObjectOfType<> FindObjectsOfType<> is executed, this makes that all the references of that object are found.

The last thing we do is go through the array of ScriptA objects using a foreach loop and execute the Function1 method to all of them, as can be seen in lines 20 to 23 of figure 16.

inspector of a gameobject in unity, scripts that communicate with each other, basic programming in unity
Fig. 17: When running the game we see that the two references of the ScriptA objects are found and we have them stored in the array.

When running the game again, we see that now in the GameObjectB inspector we have the ScriptA object references (figure 17), we have an array of dimension 2.

As can be seen in figure 18, two messages are now printed on the console, the first corresponds to the execution of Luke’s Function1 method and the second to George’s Function2 execution.

print messages in console in unity, communication between scripts, basic programming unity
Fig. 18: In the console we see that the Function1 methods of each ScriptA object are executed.


Third execution test

We are going to modify the ScriptB again to see another way to obtain the references of the objects and thus to be able to call their functions from another Script.

In this case, in the ScriptB, we are going to declare two serialized ScriptA objects (they can also be public, the idea is that they appear in the inspector). These objects will be called “scriptALuke” and “ScriptAGeorge”.

Then in the Start method we are going to execute the Function1 methods directly using these objects. In this case it is not necessary to find the references since we will assign them directly in the inspector.

The modified ScriptB is shown below.

c sharp script that executes functions defined in other scripts, e.g. in unity, communication between scripts
Fig. 19: We modify the ScriptB in this way to try another way of having the reference of the objects.

In the inspector we can see the new fields for ScriptA objects (figure 20).

inspector of a gameobject in unity, scripts that communicate with each other, basic programming in unity
Fig. 20: In the inspector we have fields for two ScriptA objects.

We will modify a little the GameObjects of the hierarchy, we will have an Empty GameObject called A-Luke and another called A-George.

hierarchy of a project in unity, gameobjects
Fig. 21: Instead of the GameObjectA we will have two empty GameObjects for each instance of the ScriptA class.

In each GameObject we assign the ScriptA component and complete the corresponding name, see figures 22 and 23.

inspector of a gameobject in unity, scripts that communicate with each other, basic programming in unity
Fig. 22: In the GameObject A-Luke we add the ScriptA component and enter the corresponding name.

inspector of a gameobject in unity, scripts that communicate with each other, basic programming in unity
Fig. 23: In the GameObject A-George we add the ScriptA component and enter the corresponding name.

Now let’s take the GameObjects from the hierarchy and assign them in the corresponding fields of the ScriptB

hierarchy of a project in unity, gameobjects
Fig. 24: With these GameObjects we will drag and drop in the ScriptB fields.

In figures 25 and 26 we see that the references have been assigned manually, this means that their respective Function1 methods can be executed.

inspector of a gameobject in unity, scripts that communicate with each other, basic programming in unity
Fig. 25: We can assign the GameObject directly to the corresponding field whenever there is such an object among its components.

inspector of a gameobject in unity, scripts that communicate with each other, basic programming in unity
Fig. 26: The references of both ScriptA objects have been assigned to the corresponding fields.

In console we see that the messages are printed product of the execution of Function1.

print messages in console in unity, communication between scripts, basic programming unity
Fig. 27: When running the game we see that the Function1 methods of both instances are executed.

Before finishing I would like to change the order of execution of the Function1 methods in the ScriptB, as seen in figure 28.

c sharp script that executes functions defined in other scripts, e.g. in unity, communication between scripts
Fig. 28: Reverse the order of the instructions and perform another test.

When we do this and run the game again we see that the messages on the console change places, figure 29.

print messages in console in unity, communication between scripts, basic programming unity
Fig. 29: We see that the messages change the order of appearance in the console.


Conclusion

We have seen how to call functions that are defined in one Script from another Script, to which we gave the informal name “Communication between Scripts”.

In order for this to be done, the method or function to be performed must be declared as public, which allows access from external contexts.

In addition we must have the reference of the object that contains that method to execute, this can be achieved in several ways, in this article we saw three ways to do it, bearing in mind that there can be more than one object that contains the method to execute.

Understand in depth the concept of programming object, which is the instance of a class and that to access its fields and public methods we must have the reference of that object, we can build more complex solutions and we are entering the subject of object-oriented programming.

Leave a Comment

Your email address will not be published. Required fields are marked *