A Class and an Object can be considered as a fundamental part of how you code a game using C# and Unity Game Engine.
In this article, we will take a deep dive into
- What a Class in C# represents and How you can Define a Class in your C# Scripts
- What is an Object and How can you create Objects in C#
- How are Objects and Classes connected to each other in C#
- We will then make a C# Script in Unity and Create Classes and Objects within it based on the RPG Analogy for this article
- After that we will learn how to modify the values within variables of an Object in C#
- And Finally we will go over, What a Constructor is and What are the benefits of using a Constructor in your C# Scripts.
So, let’s get on with it!
This Post is Part of : How To Make A Game Series where I’ll be showing you how to become a game developer and will be going over the basics of Game Development, Step by Step, using the Unity Game Engine and C# Scripting Language to script the Game Logic.
If you are new to Game Development or Programming in general you should definitely go through this Unity Tutorials article series as it will set give you a kick-start towards becoming an exceptional Unity 2D or 3D Video Game Developer.
The Design Stage of your Game can be considered as one of the most crucial part of your Game Development Cycle and also the hardest to stay focused in
because of the variety of ideas and concepts that keep on coming to your head, all pushing and pulling your in different directions.
This can be a huge problem as if you lose focus of what’s important for you particular Game,
you might commit yourself to something wholeheartedly, only to realize your efforts towards that committed idea did not add much to your overall Game.
This can really be heart wrenching for any Game Developer and to stop that from happening to you, I’ve written this article on 3 Points To Focus On When Designing A Game
in which I’ve talked about 3 Points that will help your stay focused on what’s important for your Game when making Game Design and Game Development Decisions.
What is a Class in C# | Unity Game Development Tutorial
Now when you are programming in C#, you follow the Object Oriented Programming System or OOPs in short.
The OOPs paradigm is built around the concept of Objects, hence the name.
These Objects contain some data in form of Variables and ways to modify these pieces of data in form of Methods.
Now, before working with Objects, you will first need to create an Object and you can do that by using Classes.
You can think of a Class as a Template which can be used to create an Object.
Let’s go to the RPG analogy, so that i can give you some context.
Think about the weapons in you game,
So let’s say at this moment, you are thinking about swords and want to implement swords in you game.
Thinking About The Common Properties Between All The Swords
So what you would do is, think about the Properties that every sword in your game will have in common.
As you think about it, you will come up with a list like
- Sword Name
- Piercing Damage
- Slashing Damage
- Bleeding Damage
- Weapon HP
Then suppose it’s an elemental sword then you would have other properties like
- elemental Damage
- Mana Consumption
- and what not.
So, now you know the common properties that the Sword in your game will have.
Thinking About The Common Actions Between All The Sword
Next, what you need to think about is what Actions can be performed with or on the sword
either by your player or by a game mechanic that you made for your game.
Again when you think about this, you will come up with something like,
- Attack1
- Attack2
- Parry
- Defend
- etc
Now with that we know what Properties all the swords will have
and the Actions that can be done with these swords in your game.
So what we can do next is create a Template which has these particular properties and actions
and can be used to create these swords.
This template of sword that we are creating is what we call a Class in the OOPs paradigm
and the Properties and Actions of the sword will be defined inside the sword class using Variables and Methods respectively
I hope that i was clear enough.
What is An Object in C# | Unity Game Development Tutorial
Now let’s say that you want to spawn 2 swords in your Player’s Inventory when the game starts.
One of them is a Rapier that is good at Thrusting
while the second is a War Sword which is good at Slashing
To do this we will use the sword template that we have created and make instances of this template.
Creating instance is just a fancy way of saying that
we will be taking this template with these variables and make copies out of it.
and these copies that we make are what we call Objects in the OOPs paradigm.
When creating these Objects, we will also give every single Object a name
and then we will fill in the data inside these Objects based on the template that we have created i.e. The Class.
So in our case we have a sword template with various variables and we will make 2 Objects of it.
Then we will give each of them a unique name like Rapier001 and WarSword001
and after that we will fill in the variables with appropriate details
So, as Rapiers are good at thrusting, it will have High Piercing Damage
while as War Swords are good at slashing, it will have High Slashing Damage.
So, to reaffirm, Classes are the blueprints for your Objects.
Basically, in Unity, all of your scripts will begin with a Class Declaration.
Unity automatically puts this in the script for you when you create a new C# script.
This automatically created Class shares the same name as the C# Script File that it is in.
This is very important as both of them should be the same name and if you change the name of one, you need to change the name of the other.
So, try to name whatever script you make sensibly when you create it.
Moving forward, one of the principles of OOPs is to split your larger scripts that do a lot of different things into multiple scripts
that each take a single role or responsibility and therefore be dedicated ideally to a single task.
The main aim of object-oriented programming is to allow the programmer to develop software in modules
and this is accomplished through Classes and Objects.
Creating Your First C# Class in Unity | Unity Game Development Tutorial
With that explained, let’s go to Unity and create a new C# Script named template_sword
To do this you have to navigate to the Asset Directory or any of it’s Sub-Directories.
Assets Directory will contain all your Game Assets from your 2D and 3D Art Assets, Sounds Files, Game Logic i.e. your C# Scripts, etc.
To keep things organized, I’ve made a sub-directory named Scripts within the Assets Directory.
Now inside the Scripts Directory, you have to Right Click -> Create -> C# Script
as shown in the image below
and then type the name for your new C# Script which in my case is template_sword.
Now let’s open it in VS Code.
If you have not installed a Code Editor yet you can take a look at this article on Game Development Softwares (Game Engines, 2D Art, 3D Art, Code Editor, DAW)
in which i have given a couple of options for Code Editors for you to use.
While if you want to set whichever Code Editor that you selected as your Default Code Editor for Unity Game Engine
then you can take a look at this article on 5 Ways To Develop Games On Low End / Low Spec PCs with Unity in which i show you how to do that.
This article also contains other Game Development Tips to greatly improve you experience with Unity Game Engine.
Inside VS Code, as you can see above, Unity automatically generated some code inside the C# Script
which also contains a Class with the same name that we gave to our C# Script.
Now, let’s declare some private variables based on what we thought before about the common properties between multiple swords as shown below
// Everything below is inside the template_sword Class
private string _swordName;
private byte _piercingDamage;
private byte _slashingDamage;
private byte _bleedingDamage;
private byte _elementalDamage;
private byte _manaConsumption;
private short _weaponHP;
In the code block above, I’m prefixing the variable name with an underscore to differentiate between private variables from other type of variables.
Doing this is quite common and if you are looking at other people’s code base you will see this a lot.
With these variables declared, now let’s Declare the Actions that can be perform using a sword or on a sword with methods.
// Everything below is inside the template_sword Class
private string _swordName;
private byte _piercingDamage;
private byte _slashingDamage;
private byte _bleedingDamage;
private byte _elementalDamage;
private byte _manaConsumption;
private short _weaponHP;
// Start is one of the inbuilt methods in Unity
public void Start()
{
}
public void Attack()
{
Debug.Log("Player Attacked Using: " + _swordName);
}
public void Parry()
{
Debug.Log("Enemy Parried Using: " + _swordName);
}
public void Defend()
{
Debug.Log("Player Defended Using: " + _swordName);
}
So with that we have created a new C# script named template_sword from scratch
and then inside that C# Script we have an automatically generated template_sword Class
in which we defined the necessary variables and methods for swords in our game.
Creating Objects Of The template_sword Class | Unity C# Game Development Tutorial
Now let’s go to the Start Method and create a Rapier and a War Sword by creating 2 instances of the template_sword Class
So, to do this we have to first type the Name of the Class which in our case is template_sword.
After that, we have to give this variable a name which I’ll be giving Rapier001
Then we have Equal To ( = )
After that we have to type the new keyword
and then we have to type the class name again i.e. template_sword but this time with opening and closing parenthesis after it.
and Lastly, to end the statement we will use a Semi-Colon ( ; )
template_sword Rapier001 = new template_sword();
With this statement we have created an instance of template_sword Class
i.e. we have created an Object with the name Rapier001.
Now let’s create another instance named WarSword001 below it.
// Everything below is inside the template_sword Class
private string _swordName;
private byte _piercingDamage;
private byte _slashingDamage;
private byte _bleedingDamage;
private byte _elementalDamage;
private byte _manaConsumption;
private short _weaponHP;
// Start is one of the inbuilt methods in Unity
public void Start()
{
template_sword Rapier001 = new template_sword();
template_sword WarSword001 = new template_sword();
}
public void Attack()
{
Debug.Log("Player Attacked Using: " + _swordName);
}
public void Parry()
{
Debug.Log("Enemy Parried Using: " + _swordName);
}
public void Defend()
{
Debug.Log("Player Defended Using: " + _swordName);
}
So with that, we have used the template_sword Class and Instantiated two Objects of that Class.
Important Things To Understand About Objects in C# | Unity Game Development Tutorial
Now before moving forward and adding data to these two objects, i need to explain some things.
First is that, each object that you create will have it’s own copy of variables that we have defined in it’s Class
So, if we change the value of _bleedingDamage variable in Rapier001,
it will have no effect on the value of _bleedingDamage variable in WarSword001.
Second, the methods that we defined inside the class are shared between all the Objects of that Class,
Objects do not have copies of these methods.
Now, some of you might be thinking that, wouldn’t sharing the methods between Objects make the code ambiguous
when we try to access a variable inside the Method’s code block
like we have done for _swordName in the Attack, Parry and Defend Methods.
And the answer to that is, No it would not be problem and No this code will not be ambiguous.
The reason why this is not a problem is that
any variable that you are accessing from within a method using an instance of a class, refers to that variable of that particular instance.
This is why even though methods are shared between all the instances i.e. Objects of a Class, they are not ambiguous.
If you want to explicitly refer to the current instance inside the method you can use this and the dot ( . ) before the variable name.
Adding Data To The Variables Inside An Object | Unity Game Development Tutorial
With that explained, now let’s add some data to these two Objects.
To do this we will type the name of the Object then dot ( . )
and then the name of the variable that we have defined inside the Class
So in this case _swordName
After that we have Equal To ( = )
and then the value that we want to set to this variable.
That’s it.
// Only showing the Start Method
public void Start()
{
template_sword Rapier001 = new template_sword();
template_sword WarSword001 = new template_sword();
Rapier001._swordName = "Rapier001";
}
Now let’s quickly set values to all the variables for both the swords
and then Debug.Log all the variables of both of these Objects
as shown in the code block below
// Everything below is inside the template_sword Class
private string _swordName;
private byte _piercingDamage;
private byte _slashingDamage;
private byte _bleedingDamage;
private byte _elementalDamage;
private byte _manaConsumption;
private short _weaponHP;
// Start is one of the inbuilt methods in Unity
public void Start()
{
template_sword Rapier001 = new template_sword();
template_sword WarSword001 = new template_sword();
Rapier001._swordName = "Rapier001";
Rapier001._piercingDamage = 5;
Rapier001._slashingDamage = 1;
Rapier001._bleedingDamage = 3;
Rapier001._elementalDamage = 0;
Rapier001._manaConsumption = 0;
Rapier001._weaponHP = 100;
WarSword001._swordName = "WarSword001";
WarSword001._piercingDamage = 1;
WarSword001._slashingDamage = 5;
WarSword001._bleedingDamage = 3;
WarSword001._elementalDamage = 0;
WarSword001._manaConsumption = 0;
WarSword001._weaponHP = 150;
Debug.Log("Sword Name : " + Rapier001._swordName + " Piercing Damage : " + Rapier001._piercingDamage + " Slashing Damage : " + Rapier001._slashingDamage + " Bleeding Damage : " + Rapier001._bleedingDamage + " Elemental Damage : " + Rapier001._elementalDamage + " Mana Consumption : " + Rapier001._manaConsumption + " Weapon HP : " + Rapier001.weaponHP);
Debug.Log("Sword Name : " + WarSword001._swordName + " Piercing Damage : " + WarSword001._piercingDamage + " Slashing Damage : " + WarSword001._slashingDamage + " Bleeding Damage : " + WarSword001._bleedingDamage + " Elemental Damage : " + WarSword001._elementalDamage + " Mana Consumption : " + WarSword001._manaConsumption + " Weapon HP : " + WarSword001.weaponHP);
}
public void Attack()
{
Debug.Log("Player Attacked Using: " + _swordName);
}
public void Parry()
{
Debug.Log("Enemy Parried Using: " + _swordName);
}
public void Defend()
{
Debug.Log("Player Defended Using: " + _swordName);
}
With that done, now let’s make a call to Attack method from the WarSword001 Object
To do this we will type WarSword001 then dot ( . )
and after that we have the method name and the two opening and closing parenthesis, like this
WarSword001.Attack();
This is all you need to do to call a Parameter-less Method.
If your defined method has parameters then you will pass Arguments for these said Parameter between the parenthesis
as i have shown in the articles about Methods.
Now let’s make one more method call but this time from Rapier001 to the Parry Method instead, like this.
// Everything below is inside the template_sword Class
private string _swordName;
private byte _piercingDamage;
private byte _slashingDamage;
private byte _bleedingDamage;
private byte _elementalDamage;
private byte _manaConsumption;
private short _weaponHP;
// Start is one of the inbuilt methods in Unity
public void Start()
{
template_sword Rapier001 = new template_sword();
template_sword WarSword001 = new template_sword();
Rapier001._swordName = "Rapier001";
Rapier001._piercingDamage = 5;
Rapier001._slashingDamage = 1;
Rapier001._bleedingDamage = 3;
Rapier001._elementalDamage = 0;
Rapier001._manaConsumption = 0;
Rapier001._weaponHP = 100;
WarSword001._swordName = "WarSword001";
WarSword001._piercingDamage = 1;
WarSword001._slashingDamage = 5;
WarSword001._bleedingDamage = 3;
WarSword001._elementalDamage = 0;
WarSword001._manaConsumption = 0;
WarSword001._weaponHP = 150;
Debug.Log("Sword Name : " + Rapier001._swordName + " Piercing Damage : " + Rapier001._piercingDamage + " Slashing Damage : " + Rapier001._slashingDamage + " Bleeding Damage : " + Rapier001._bleedingDamage + " Elemental Damage : " + Rapier001._elementalDamage + " Mana Consumption : " + Rapier001._manaConsumption + " Weapon HP : " + Rapier001.weaponHP);
Debug.Log("Sword Name : " + WarSword001._swordName + " Piercing Damage : " + WarSword001._piercingDamage + " Slashing Damage : " + WarSword001._slashingDamage + " Bleeding Damage : " + WarSword001._bleedingDamage + " Elemental Damage : " + WarSword001._elementalDamage + " Mana Consumption : " + WarSword001._manaConsumption + " Weapon HP : " + WarSword001.weaponHP);
WarSword001.Attack();
Rapier001.Parry();
}
public void Attack()
{
Debug.Log("Player Attacked Using: " + _swordName);
}
public void Parry()
{
Debug.Log("Enemy Parried Using: " + _swordName);
}
public void Defend()
{
Debug.Log("Player Defended Using: " + _swordName);
}
With that done, now let’s execute this piece of code in Unity and check the logs.
Unity Log | Setting Values To An Object’s Variables And Calling Methods From An Object of A Class in C#
As you can see in the first two log, the values were set as expected
and in the last two logs, we can see the WarSword001 attacked while Rapier001 Parried that Attack.
So everything is working as we intended.
Constructor For A Class in C# And Benefits Of Using A Constructor | Unity Game Development Tutorial
Now let’s move on and talk about Constructors.
A Constructor is a Special Type of Method that is called whenever an Instance of a Class i.e. an Object is created.
Unlike normal methods that you can name whatever you want,
The Name of the Constructor must match The Name of the Class
and it cannot have a Return Type like void, int, etc.
All classes have constructors by default,
if you do not create a class constructor yourself, C# creates one for you automatically.
// Syntax of a Constructor.
<Access Modifier> <Constructor Name i.e. Class Name>(<Parameters>)
{
// Code Block.
}
So to define a constructor, all you need is the Access Modifier
and then the Constructor Name which will be the Class Name.
After that we have the two Opening and Closing Parenthesis
and lastly we will have the Code Block to be executed.
Now, after we created the two Instances of the template_sword Class i.e. Rapier001 and WarSword001,
we are assigning values to them and Logging these values to the Unity Console in the Start Method
All this code can be moved to the Constructor’s Code Block as shown below
// Everything below is inside the template_sword Class
private string _swordName;
private byte _piercingDamage;
private byte _slashingDamage;
private byte _bleedingDamage;
private byte _elementalDamage;
private byte _manaConsumption;
private short _weaponHP;
// Start is one of the inbuilt methods in Unity
public void Start()
{
template_sword Rapier001 = new template_sword();
template_sword WarSword001 = new template_sword();
WarSword001.Attack();
Rapier001.Parry();
}
private template_sword()
{
Rapier001._swordName = "Rapier001";
Rapier001._piercingDamage = 5;
Rapier001._slashingDamage = 1;
Rapier001._bleedingDamage = 3;
Rapier001._elementalDamage = 0;
Rapier001._manaConsumption = 0;
Rapier001._weaponHP = 100;
Debug.Log("Sword Name : " + Rapier001._swordName + " Piercing Damage : " + Rapier001._piercingDamage + " Slashing Damage : " + Rapier001._slashingDamage + " Bleeding Damage : " + Rapier001._bleedingDamage + " Elemental Damage : " + Rapier001._elementalDamage + " Mana Consumption : " + Rapier001._manaConsumption + " Weapon HP : " + Rapier001.weaponHP);
}
public void Attack()
{
Debug.Log("Player Attacked Using: " + _swordName);
}
public void Parry()
{
Debug.Log("Enemy Parried Using: " + _swordName);
}
public void Defend()
{
Debug.Log("Player Defended Using: " + _swordName);
}
and then whenever a new instance will be created the constructor will be called automatically.
I’ve also removed the duplicate code for setting values of WarSword001 as we won’t need it anymore.
Now, this code will not work right now as there a couple of problems with it.
To make this code work, we will need to define some Parameters inside the Constructor
and modify how we are setting values to the variables inside the Constructor as shown below.
// Only showing the Constructor
private template_sword(string swordName, byte piercingDamage, byte slashingDamage, byte bleedingDamage, byte elementalDamage, byte manaConsumption, short weaponHP)
{
// this. means the current instance of the Class.
this._swordName = swordName;
this._piercingDamage = piercingDamage;
this._slashingDamage = slashingDamage;
this._bleedingDamage = bleedingDamage;
this._elementalDamage = elementalDamage;
this._manaConsumption = manaConsumption;
this._weaponHP = weaponHP;
//... Not Showing The Code Below
}
and then in whichever places, we are creating an instance of template_sword class,
we can pass arguments directly for these parameters inside the parenthesis as shown below.
// Only showing the Start Method
void Start()
{
template_sword Rapier001 = new template_sword("Rapier001", 5, 1, 3, 0, 0, 100);
template_sword WarSword001 = new template_sword("WarSword001", 1, 5, 3, 0 , 0, 150);
WarSword001.Attack();
Rapier001.Parry();
}
What this does is, it moves all the clutter that we had in the Start Method to the Constructor
and as we will reuse the code inside the constructor, the lines of code will directly be halved in this case.
Also we cannot call a Constructor like a Method.
If we try to do it, we will get a Compile Time Error as shown in the image below.
So, let’s remove this method call and modify the Debug.Log inside the Constructor as shown below.
// Everything below is inside the template_sword Class
private string _swordName;
private byte _piercingDamage;
private byte _slashingDamage;
private byte _bleedingDamage;
private byte _elementalDamage;
private byte _manaConsumption;
private short _weaponHP;
// Start is one of the inbuilt methods in Unity
public void Start()
{
template_sword Rapier001 = new template_sword("Rapier001", 5, 1, 3, 0, 0, 100);
template_sword WarSword001 = new template_sword("WarSword001", 1, 5, 3, 0 , 0, 150);
WarSword001.Attack();
Rapier001.Parry();
}
private template_sword()
{
this._swordName = swordName;
this._piercingDamage = piercingDamage;
this._slashingDamage = slashingDamage;
this._bleedingDamage = bleedingDamage;
this._elementalDamage = elementalDamage;
this._manaConsumption = manaConsumption;
this._weaponHP = weaponHP;
Debug.Log("Sword Name : " + _swordName + " Piercing Damage : " + _piercingDamage + " Slashing Damage : " + _slashingDamage + " Bleeding Damage : " + _bleedingDamage + " Elemental Damage : " + _elementalDamage + " Mana Consumption : " + _manaConsumption + " Weapon HP : " + _weaponHP);
}
public void Attack()
{
Debug.Log("Player Attacked Using: " + _swordName);
}
public void Parry()
{
Debug.Log("Enemy Parried Using: " + _swordName);
}
public void Defend()
{
Debug.Log("Player Defended Using: " + _swordName);
}
Now, let’s go to Unity and check the logs
Unity Log | Constructor in C# | Unity Game Development Tutorial
As you can see the constructor was called and the data that we passed as the argument was set as we intended.
Conclusion
Well folks, that does it for this article.
i hope that this information will be helpful to you.
Share this post and follow us on Social Media platforms if you think our content is great, so that you never lose the source of something you love.
If you like the content do go through the various articles in How To Make A Game Series that this post is a part of and also go through the other series we have on Bite Sized Tech.
Also we have a YouTube Channel : Bite Sized Tech where we upload Informational Videos and Tutorials like this regularly. So, if you are interested do subscribe and go through our Uploads and Playlists.
Follow Us On Social Media
Goodbye for now,
This is your host VP
Signing off.
Articles In How To Make A Game Series
Game Development Softwares (Game Engines, 2D Art, 3D Art, Code Editor, DAW)
Methods | Part 1 – Basics of Methods
Methods | Part 2 – Multiple, Required & Optional Parameters + Named Arguments
Methods | Part 3 – Overload Resolution
Methods | Part 4 – In, Ref and Out Keywords