Cookies   I display ads to cover the expenses. See the privacy policy for more information. You can keep or reject the ads.

Video thumbnail
Hi everyone, welcome to episode 02. In the last episode we discussed variables and methods,
and today we’re going to be looking at classes.
Simply put, a class is a means of grouping related methods and variables together. Creating
a class can be as simple as writing the keyword ‘class’, followed by the name of the class
(for example Player), and then adding an opening and closing brace between which comes all
of the code.
Classes aren’t only for organisation, however, they also allow us to reduce code repetition
through something known as inheritance. Let’s take a look at an example:
Say we’re trying to recreate the animal kingdom in our game. We might have a class
for mammals, and a class for birds. If we start writing code in both of these classes,
we’ll soon realise that they have a lot in common. For example, both birds and
mammals need methods to define eating and sleeping behavior. Rather than have the same
code in both classes, we could create a new class called ‘Animal’, which has this
code in it. Both Mammal and Bird can then inherit from Animal, meaning that they both
get access to this functionality. In the Mammal and Bird classes, we can then focus only on
what is unique about them. For instance, mammals give live birth to offspring, while birds
lay eggs and can also fly.
Now if we wanted to create an elephant in our game, it could inherit from mammal. Straight
away it has all the functionality of other mammals: eating, sleeping and giving live
birth to offspring. All the elephant class then needs to define is its unique ability
to control a trunk.
As you can see, this system of inheritance - going from general, shared behavior, to
specific behavior, can be a very powerful tool.
However, in some cases we’re likely to run into some problems with this system. For instance,
if we were to create a penguin, we’d find that while it shares some behaviour with other
birds, it can’t fly; instead it swims.
Let’s have a look at an alternate way of arranging things using the concept of composition
instead of inheritance. The idea here is to split the classes up so that each one implements
a single behaviour; so one class for swimming, another for flying, and so on. We can now
assemble any animal we like by simply combining the relevant components. Furthermore, if these
components are generic enough, we could use them again in future projects.
Ultimately we aim to keep our code flexible, so that it is easy to introduce changes later
in development, as well as to minimize code repetition. Inheritance and composition are
both tools which enable us to do this.
Alright, now in Unity, we generally use classes in one of three ways. We’re going to discuss
two of them in this video, and the third will form part of a later episode.
The first is as a behavioural component. These are the scripts that we attach to the objects
in our game to drive their behaviour. These classes must inherit from Unity’s MonoBehaviour
class, which simply contains some common object functionality.
One example of this functionality is that if we create a method with the name ‘Start’
in our class, monobehaviour will ensure that it gets called once at the start of the game.
Likewise if we create a method named ‘Update’, monobehaviour will make sure that it gets
called once every frame while the game is running.
So say I create an enemy class. The colon after the class name indicates that this class
inherits from MonoBehaviour. Inside the update method, I might create a bool variable called
canSeePlayer, and set it to false. Then I’d have some code that sets canSeePlayer to true
if the player is within a certain distance. Finally, I’d have an if statement (which
we’ll learn more about later) to say if the canSeePlayer variable is true, then attack
the player.
Now we’ve only written one enemy class, but of course that doesn’t mean that there
can be only one solitary enemy in our game. Each enemy object can have its own copy, called
an ‘instance’ of the Enemy class. Importantly, the variables inside the different instances
can have different values while the game is running. In other words, while the game is
being played, one enemy’s canSeePlayer bool might = true, while at the same time, another’s
canSeePlayer bool is false. These sorts of variables are called instance variables, since
they belong to the individual instances of the class. An instance variable is the default
type of variable, so all variables that we’ve seen up to this point have been instance variables.
The opposite of an instance variable is called a class variable, since it belongs not to
one particular instance, but to the class itself. We create class variables by adding
the keyword ‘static’ when we create the variable.
To illustrate the difference betweeen class and instance variables, I’m going to create
a static integer variable called numberOfEnemiesAlive, as well as a non-static integer variable called
instanceExample, inside the Enemy class.
Say we have 5 enemies, and at the start of the game, each of them adds +1 to both numberOfEnemiesAlive
and instanceExample. Now, when the game is running, the value of numberOfEnemiesAlive
is equal to 5, while instanceExample has a separate value of 1 for each of the 5 Enemy
instances.
Let’s say I wanted to access the numberOfEnemiesAlive variable from another class. First we’d
have to add the keyword ‘public’ in front of it, to make it accessible to other classes.
Now, in my other class, I could access the numberOfEnemiesAlive variable by simply writing
Enemy.numberOfEnemiesAlive. In other words, the class name, followed by a dot, followed
by the variable name.
However, if I wanted to know the value of the instanceExample variable, do you think
I could do the same thing? No. In that case the computer would ask, which instance of
the Enemy class do you want me to fetch the value from? And by ask, of course, I just
mean that there would be an error.
Hopefully this example has made the difference between instance and class variables clear.
Note that the same concept of static and non-static applies to methods as well.
This leads us to ‘way in which classes are used, number 2’. Static classes. Making
an entire class static has two main implications for us to consider at the moment. The first
is that all of its methods and variables have to be made static as well. The second is that
we can’t attach this class to objects in our game since ‘static’ forbids us from
creating instances of it.
On the other hand, as we saw with the numberOfEnemiesAlive example, the restriction of making something
static means that it is very easy to access from other classes. Because of this, static
is extremely well-suited to what we call Utility classes.
An example of a Utility class would be a static class called Maths. Inside of this, we might
define various things, for example a static float containing the first 10 digits of pi,
or a static method to calculate the squareroot of a given number.
Once again these are all made public, so from any other class, if we want to know the value
of pi, we just have to write Maths.pi, or similarly if we need to calculate the square
root of a number, we can write Maths.squareRoot(x);
All right, that’s all the new information for this episode. Let’s do a quick recap:
Classes are used to group together related methods and variables. We can expand on the
functionality of a base class, such as Animal, by inheriting from it. Alternatively, we can
have each class define a single behaviour and build more complex, composite behaviours
out of these elements.
When we attach a class to an object in our game, we are creating an instance of it that
belongs specifically to that object. Values of the variables inside that instance can
be different to the variables of other instances of the same class. The exception to this is
if the variable is static, in which case it belongs to the class, not any specific instance.
Making variables and methods static is especially useful in Utility classes such as a maths
class, as they can be accessed from other classes without having to get a reference
to a specific instance.
I hope you enjoyed the episode. As always, feel free to ask me anything you’re unsure
of in the comments.
Until next time, cheers.