Updated date:

Working With Custom Classes in C# and Unity3D

John is a fervent writer, gamer, and guitar lover. Former automatic-transmission repairer, welder and hobbyist game developer.

In simple terms, a function is a block of code that can be called upon to execute in its entirety. So if you had a few lines of code that you needed to use repeatedly, you can put that code in a function and then you only need to type out the call to that function, rather than write out all of your code over and over, every time you need to use it. It also has the added bonus that, should you change your code, you only have to change the one function rather than every instance of your code.

A class can be thought of as a bigger function. One that contains functions of its own. In Unity the most readily available example of a class that even novices will quickly become familiar with, is MonoBehaviour.

It is MonoBehaviour that contains the main game loop related functions, such as Start, Update, FixedUpdate, etc. There are also other types of classes you may be familiar with, such as ScriptableObject, and Editor, but the real point of this article is to get into how you can write your own classes to make your code cleaner, more optimised, and generally more fun to write!

A Brief Note on Structs

This article, as the name suggests, is dealing with classes, not structs. There is more to be said on the differences between structs and classes and when to use them, but for the purposes of this article, it’s enough to just point out the main difference. Structs are pass-by-copy, whereas classes are pass-by-reference.

What this means is that if you create a new instance of a custom class and set it like newInstanceOfClass = otherInstanceOfClass, the new instance of the class acts like a link, and any changes to it will be passed on to the original instance of the class. With structs the data is copied, and the new instance would become its own thing, disconnected from the original.

C# Structs Vs Classes

Creating a Custom Class

You can create a new custom class in an existing .cs file in your Unity project, or in a new file all of its own. If you decide to use an existing script, remember to make sure you put your custom class outside of any other classes that are in there. Your custom class can inherit from other classes (such as MonoBehaviour) however, for now, we’ll keep this simple, so let’s assume your class is going to be a stand alone affair. Here is a basic class;

public class CustomClass {

	public float someFloat;
	public string someText;

}

This class simply holds two values—a float and a string—which are publicly accessible from outside of the class. This is important; if the value is not set as public, it will not be accessible from outside of the custom class itself. In order to initialise and assign data to this class somewhere else in your project, you might type;

CustomClass newCustomClass = new CustomClass();
newCustomClass.someFloat = 4.7f;
newCustomClass.someText = “Testing”;

And you could then access those variables the same way, as well as pass around the whole class object with its variables intact. It’s not the most elegant way of initialising a class, however. Fortunately, we can tidy things up using a constructor.

Constructors

A constructor allows you to set a method by which a class can be initialised with or without certain values. They can be overridden, meaning you can have multiple different constructors, and they can contain code, so you are not just limited to passing in data. The above example with a constructor might look something like this;

public class CustomClass {

	public float someFloat;
	public string someText;

	public CustomClass (float _someFloat, string _someText) {

		someFloat = _someFloat;
		someString = _someString;

	}

}

Now, to initialise the custom class, you would only have to type;

CustomClass newCustomClass = new CustomClass(4.7f, “Test”);

And, if needed, you could have a constructor that takes in no values, or takes in only a float, or only a string, or takes some other value that is used for something other than directly setting a variable. For example, say your custom class held an array but you don’t know how big that array needs to be until you initialise. Your constructor could look like this;

public class CustomClass {

	public float[] array;

	public CustomClass (int size) {

		Array = new float[size];

	}

}

In this case, the initialisation value is not handing over any data, but passing necessary information about how this instance of the class needs to be set up. You could then also have code to populate that array, or handle any number of other processes that you might need.

Proper use of classes and functions can greatly increase the readability of your code, making it easier for others, and yourself, to understand.

Proper use of classes and functions can greatly increase the readability of your code, making it easier for others, and yourself, to understand.

Functions

Custom class functions work the same way as everywhere else in C#. One particularly good use for functions in this scenario is for accessing custom class data. You see, while you can have an array set to public, as above, it’s not exactly the best practice. Especially if you start modifying that array from different locations. It’s much better to have the array be private, and have access to that array be handled via functions, like so;

public class CustomClass {

	private float[] array;

	public CustomClass (int size) {

		Array = new float[size];

	}

	public SetArrayValue (int index, float value) {

		Array[index] = value;

	}

}

Using this method, your SetArrayValue function could also have checks in place to avoid potential OutOfBounds exceptions if, for some reason, the given index is not within the range of the array.

Operators

Initialising and calling functions are not the only things you might want to do with a custom class, however. Operators are crucial more often than not in handling data. The most common of which is a simple addition; CustomClass + CustomClass = CustomClass.

In the case of an integer, this is simple. 2 + 2 = 4. Things can get a little more complicated when handling other data types, however. For example, adding two strings together can be dealt with by appending one string to the other. “Test” + “Data” = “TestData”. But what about classes with multiple data types?

In Unity, one of the most commonly used classes is Vector3. This is a collection of three floats, X, Y, and Z. Vector3s can be added, subtracted, multiplied and divided. This is actually one of the more simple examples of operator overriding, because ultimately you are still just handling numbers. The operator code for addition in a struct like Vector3 might look something like;

public static Vector3 operator+ (Vector3 a, Vector3 b) {

	Vector3 result = new Vector3();
	result.x = a.x + b.x;
	result.y = a.y + b.y;
	result.z = a.z + b.z;

	return result;

}

And so, if you were to attempt to add two Vector3s together, the above function would run, using the first Vector3 as “a”, and the second as “b”. There are a vast range of operators to consider, such as the aforementioned +, -, *, and /. But also comparison operators, such as ==, >, <, and so on. You should only worry about operators that are relevant to your data class, however. For example, it would likely be impractical to assign a ++ operator to a string in almost all cases.

Properly setting up your custom classes with relevant constructors, functions, and operators can save you many lines of unnecessary code.

Properly setting up your custom classes with relevant constructors, functions, and operators can save you many lines of unnecessary code.

That should be enough to get you started on creating your own custom classes in C# and Unity3D. If you’re more of a video person, check out the video below for an overview of what is covered here. Remember, this is only a beginners look, and as such, barely scratches the surface of what can be done with classes.

There is always more to learn.

This content is accurate and true to the best of the author’s knowledge and is not meant to substitute for formal and individualized advice from a qualified professional.

© 2019 John Bullock

Related Articles