Using Unity: Passing References

New to C#? Stop! Before you go on, I highly suggest you learn the basics of C#. It is important to understand the difference between Unity and C#, because while you could learn C# while using Unity, it is not suggested. There are certain key differences you need to understand when working in one or the other, even if you don’t plan on working on C# outside of Unity. You don’t need to be a master, but to understand some basic concepts, I suggest you go read my C# tutorials.

One of the most common issues I see for new users of Unity is when they need to get a reference of one of their scripts in another. For example, this might be a case when your UI script needs a reference to your Player script in order to show how much health they have. There are a few common mistakes and troubles I see, so I hope to clear that up very simply here.

Wait… What’s a Reference?

First in order to understand the greater context, make sure you understand what classes are in a basic form. If you’ve forgotten you can check out my C# classes tutorial. A reference then is a sort of link to another class. It is a variable we create that represents a direct link to the data we want to change. For our example, we may have a player class, and so a reference would look like this.

private Player playerReference;

Where Player is our class, we now have a variable to be able to access and change public options on that class. So any public variables or functions can be accessed with this reference, and potentially changed. Be careful of what you’ve made public however, and it’s worth keeping encapsulation in mind.

However, just because we’ve made a variable, doesn’t mean it has any data right now. Currently it is null, meaning there is no data inside. Attempting to access any of it will result in a null reference exception, meaning theres no data to access.

So How Do We Give It Data?

Excellent question. Well in Unity there are a few ways to move data around, but we will be focusing on the most common and simple method.

So if you’ve used Unity for a while, you will be familiar with the inspector. Here is where various classes can display data to be edited in the editor, instead of changing them in code. This can be extremely useful and powerful if done correctly. Take a look at some built-in Unity scripts, such as a box collider, or the camera. Notice all the values in the inspector available to be changed and edited. We can also expose values here, including an area where you can pass a reference.

So how do we do that? There are two main ways. Unity will automatically serialize a value if it is public. In general terms, serializing essentially means making the data into a format to be saved. This way if you change a value in the inspector, it doesn’t revert back to the old value later, it is saved. Making a variable public causes Unity to serialize it, and it will then automatically show up in the inspector, and you can begin editing it. This can be done with values as well, such as ints, strings, etc. Do keep in mind these are not references.

However, making a variable public like this is generally considered bad practice, for more information on why, take a look at my encapsulation tutorial. So what do we do then? We want to keep the variable private, but we also want to show it in the inspector so we can change it, or pass a value inside.

That is what the attribute [SerializeField] is for. We’re able to apply this attribute to a variable, and it will then serialize it (if it’s able) and display it to the inspector. You can do that like so

[SerializeField]
private Player playerReference;

So here we’ve now serialized our Player monobehaviour class. Keep in mind, serializing non-monobehaviour classes will require you to make sure they are serializable. Now if we take a look at the inspector, you should notice a new field that displays a field with your variable name, and a box. Here we’re able to drag a reference inside. So if we took our same example, and say we have our Player class, we can now physically click and drag the player GameObject into the open field. You will notice it gets filled in with the GameObject name.

Also notice if you attempt to drag in any other object (that doesn’t have a Player class on it), it will not fill in the box. Since we specified it as a Player reference, it will only accept objects with the class Player on it. This applies to everything.

Well, What If I Want Multiple References?

So lets say our player has the Player class on it, but it also has a Health class on it, separate from the Player class. Well we want both, but we don’t want to make another inspector variable. Just roll with it.

What we can do is get a reference to the GameObject itself, and from there extract each value. How do we do this? Same way we did before, except using the GameObject class name, and some GetComponent calls. Do keep in mind, we will want to cache these values, we do not want to continually call them.

Here is another example of this in practice.

[SerializeField]
private GameObject playerObject;

private Player playerReference;
private Health playerHealth;

private void Awake()
{
    playerReference = playerObject.GetComponent<Player>();
    playerHealth = playerObject.GetComponent<Health>();
}

So here we have our object that we can pass in, and then two private (not serialized) variables to store (aka cache) our Player class reference, and Health class reference. We do this in Awake, so that as soon as the object is created, it stores these values to be used later.

Extra Practice

The easiest way to get an understanding of this is to try it yourself! Create a script that will print some data from another class. Perhaps call it DataPrinter or something, and put it in the scene. Then make a few more classes with some data retrievable from functions or variables. Maybe let these values (whether they’re ints, strings, or whatever else) be editable from the inspector.

Then let the DataPrinter get references to these scripts, and have it print the values to the screen, or the debug log.

Support

Are you having trouble with understanding this tutorial? Please feel free to contact me via email at KoseckCory@gmail.com or message me on discord at 7ark#8194.

I would love to get feedback from people so I can add and improve these tutorials overtime. Letting me know what you’re confused about will let me update the tutorials to be more concise and helpful.

If you’re interested in supporting me personally, you can follow me on Twitter or Instagram. If you want to support me financially, I have a Patreon and a Ko-fi.

0 comments on “Using Unity: Passing ReferencesAdd yours →

Leave a Reply

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