Table of Contents
Learning the Language of Unity - C#
Author: <Nathan Kassai> Email: kassan@unlv.nevada.edu
Date: Last modified on <01/29/2023>
Keywords: <Unity, Tutorial, Step-by-Step>
Time to complete - 1 hour and 30 minutes
In Session #2 of the Unity crash course, we will cover the following:
- Introduction to C#
- Data Types
- Decision-Making Statements (If, else, else if, switch)
- Loops
- Functions
- Final Words
- Refresher Questions
Prerequisites
Please make sure to finish the last session titled “Getting Started” before starting this session! The previous session ensures that you have at least installed Unity, configured it to work with Visual Studio, and then wrote your first “Hello World!” script. If you have already completed the previous session, you may proceed.
Introduction to C#
Last session, we got a chance to write our very first “Hello World” Script in Unity. In this session, we finally get to learn more about the scripting language used in Unity, C#, and how we can start using these scripts to manipulate the behavior of any GameObject! To start, let's talk about C# and why it is used by Unity.
C# is a general-purpose, object-oriented, programming language used to build a variety of programs from Windows applications, mobile apps, cloud-based services, websites, and even game development. Due to its smaller learning curve and access to the .NET Framework (essentially a HUGE collection of libraries developed by Microsoft to develop apps for any program you could think of), C# was the best choice for Unity's core scripting language.
Common questions arise often when learning C#; for instance, Are C#, C++, and C all the same language? How different are they from each other?
While explaining the differences between the three would take quite some time, the core differences are as follows:
- C++ was built off of C. The core difference between these two is that C++ is object-oriented while C is not. In fact, the original name for C++ was actually “C with Classes”
- C#, however, was inspired by C instead of built off of it like C++ was. In fact, the original name was COOL, which was an acronym for C-like Object Oriented Language. The main difference between C# and C++ is that C# was meant to originally rival Java, so its roots and core aspects more closely follow Java than C whereas C++ was meant to be a direct upgrade to C.
If you already have some experience with C++ or Java, learning C# really isn't much different syntactically. If you don't however, that's what this course is for! With that being said, let's get started by learning some of the basics of programming.
Data Types
A variable is a container that stores some sort of value. This value could be anything: a number, a single character, someone's name, etc. Any time you want to create a variable, you have to specify the type to let the script know beforehand what type of value you wish to store. The syntax for declaring a variable is as follows:
dataType variableName = value
The four base data types, also known as the primitive data types, are as follows:
- int - Used to hold whole numbers (1, 1500, 0, 47)
- float - Used to hold numbers with decimals (0.52, 3.14, 0.002, 1.02)
- double - Used to hold double the amount of data of a float (we will discuss what this means later)
- char - Holds a single character (e, h, A, H, y, N)
- bool - Holds a boolean value (true or false)
All other types (such as strings, arrays, lists, vectors, etc) are built off of these types.
Let's work on an example to demonstrate all of these types in a script. Open up the Unity Hub and create a new Unity project with the name Session_2. Once it loads, create a brand new script called DataTypes and double-click on it to open it up in Visual Studio.
Once it loads, you should see the following:
To start, let's write a variable that will hold our age. Right above the Start function, type out the following:
int age;
What this does is declare a variable called age, which we are able to use throughout our entire script! In the start function, let's assign a value to age. In the start function, type your age:
age = 21
Now, this variable has been assigned the value 21. Remember, since we declared this variable as an int, we cannot pass in any other type of value! If instead, you passed 22.5, there would be an error stating that you cannot pass a decimal number to an int.
Now, let us go ahead and declare a series of variables with the remaining above-mentioned primitive data types.
When assigning a value to a float, you'll see that the letter f is appended to the end of the value. In C#, by default, any number containing a decimal is considered a double, regardless of the type that you originally set. To force this value to be a float, we must append the letter f to the end of the value inputted.
With chars, remember that these store single characters; single characters are placed in between single quotes ('') whereas strings are placed in between double quotes (“”).
Additionally, you can initialize your variables outside of Start as seen in the image below.
Decision-Making Statements
Let's say we wanted to write a script that would print out “Out Of Bounds!” if the player's y-coordinate was less than zero. With the knowledge that we have up to this point, if we just write:
Debug.Log(“Out Of Bounds!”);
in the Update function, the script would fill the console with the same line of text, regardless of the y-coordinate of the player. In order to implement the behavior we intended, we are going to start to utilize decision-making statements.
A decision-making statement is a section of code that will only execute if a pre-determined condition is true. The syntax is as follows:
if(condition){
Code to execute
}
Let's try and do the previous example in a new script. Go back to our Unity project and create a new script called DecisionMaking. Once created, go ahead and load it.
In the Update function, let's write and check if the y coordinate of a cube is ever less than zero; if it is, print out “Out Of Bounds!”
transform.position.y will return the y-coordinate of the GameObject that this script is attached to. So, let's go ahead and attach it to a cube!
Head back to the Unity project and spawn in a Cube. Then, click on that Cube and add our new DecisionMaking script to it.
Once you hit play on your Unity scene, switch over to the console tab. Since our Cube spawned at the origin, and our script only checks if the y-coordinate is less than zero, nothing will happen. Using the move tool, go ahead and grab the neon green directional arrow, and start moving it downward. Once the y-coordinate of the cube is less than zero, our script starts printing out to the console!
Now, let's say that we only want our core code to run as long as the first if statement fails (as in, as long as the player is not out of bounds). This is where the else keyword comes in! Go back to our DecisionMaking script in Visual Studio, and make the following modifications to our script:
Essentially, if the condition in the if statement is false, then the else block will execute; if the condition in the if block is true, then the if block will execute. If this is a little confusing, go ahead and go back to our Unity scene and hit play. Anytime the Cube has a y-coordinate greater than or equal to zero, our script prints to the console “Player is within bounds!”, however, if the cube has a y-coordinate less than zero, then our script prints to the console, “Out Of Bounds!”.
Additionally, these if statements can contain more than one condition! Maybe you want to check if a player's y-coordinate was in some range between 5 and 10 or if a button was pressed by a player and the player did it within some time limit, etc. To do so, you will need to make use of the and (&&) operator and the or (||) operator.
The syntax for either is as follows:
if(condition_1 && condition_2)
if(condition_1 || condition_2)
In the first line, in order for the first if block to execute, both conditions must evaluate to true! However, in the second line, only one condition is required to be evaluated to true in order to execute that if block. Let's demonstrate this in our code.
For this example, we will check if two numbers are equal to each other and if the second number is even. Let's declare two int variables above our start function and call them a and b. Then, go into the Start function and set a = 14 and b = 2. After assigning our values to a and b, write the following statements within Start:
Note: The % symbol is known as the modulus operator which checks if a number has a remainder and returns that remainder.
As you can see from the above snapshot, the first if statement fails since one of the conditions evaluated to false hence why the else block gets executed. However, the second if statement executes since at least one of the conditions evaluates to true!
Loops
In Unity, if you wanted to have some sort of code execute for an indefinite amount of time, you would place all of your code in the Update function, as all code in Update will execute once every frame. However, what if we didn't want our code to run an infinite amount of time, but rather for a predetermined amount, or run until some condition were true? Time to start working with our own loops!
A loop is a block that contains code to be executed as long as a condition is true. The first loop we will introduce is a while loop which syntax is the following:
while(condition){
code to run
}
First, the condition is checked prior to executing the code in the block; if the condition evaluates to true, then we enter the while block to execute our code. Once we hit the final bracket at the end of the while block, our script will then check if the condition still evaluates to true; if it does, then it will execute once again, until the condition evaluates to false.
Important Note: It is possible to create what is known as an infinite loop where the condition never evaluates to true; if that were to happen, your while block will never end, which prevents any other code in your script from running! Please make sure that at some point, your condition evaluates to true!!!!
Let's go ahead and create a new script in our Unity project, call it Loops, and double-click it to open it up in Visual Studio. Once it is opened, go ahead and type out the following:
Note: The line valueCheck = valueCheck + 1 just increments the variable by 1. Since this is a very common practice, many languages create a short-hand notation for single increments: (shorthand breaks tutorial?)
Before we run this code, let's ask ourselves what will happen if we run this script? As previously mentioned, when running a while loop, it first checks if the condition is currently true (valueCheck is zero, and zero is indeed less than 10). Since this condition is true, we can enter the while loop and start executing the code. We first print out that we are still in the loop, and the current value of valueCheck, which is zero initially. Then, we increment valueCheck by one, and hit the terminating bracket of the while loop. We then go back to the condition of the while loop to verify if the condition is still true. Since we have added one to valueCheck, the condition is now (1 < 10), which means the condition is still true, so execute once again. The condition will only evaluate to false once the value of valueCheck reaches 10, since 10 is not less than 10. Once the condition is false, we will finally exit the while loop.
At the end of the loop, we also have a Debug.Log function printing out that we have finally exited the while loop. This will only print out after the while loop has finished (hence why infinite loops are dangerous, as the rest of your code cannot execute).
Let's go ahead and attach this script to our Cube, but before we do that, let's also remove the DecisionMaking script that is still attached to our cube (we don't want that script to be running with the Loop script!). To do so, click on the Cube, right click on the DecisionMaking component, and hit Remove Component. After it's removed, go ahead and add our Loops script to it, then run the Unity scene.
Another type of common loop used in programming is known as a for loop. This special type of loop is designed to repeat a block of code a known number of times. Let's say we wanted to print out the elements of an array, one by one. If we know the size of the array, we know how many times we need to run through our code! Here is the general syntax for a for loop:
for(statement 1; statement 2; statement 3){
code to run x amount of times
}
where statement 1 is executed one time before the execution of the block, statement 2 defines the condition for executing the block, and statement 3 is executed every time after the code block has been executed.
It might be a bit confusing at first, but let's program a simple for loop to print out the numbers 0 through 5.
Go back to our Loops script and replace our while loop code with the following:
In this for loop, statement 1 is the variable we will be using to check our condition, statement 2 is the actual condition for this loop, and statement 3 will be executed once all of the code within this for block has executed.
Once this code runs, it first creates this new variable i, it then checks if i is less than six; if it is, then enter the for block and execute the code. Once we hit the terminating bracket, it then executes whatever is in statement 3 (increment i by one). This process will continue until the condition (statement 2) fails.
If we run the Unity scene, we see the outcome of our for loop.
There are other types of loops that you might encounter such as foreach and do-while loops, however, you will not encounter them as much as for and while. Hence, I will not be covering them in this tutorial.
Final Words
In this session, we have learned a lot of the basics of C# from loops, to data types, functions, etc. In the next section, we will talk a lot more about how we could use what we learned from this session to modify the components of other Game Objects from our script, what classes are, and some more advanced programming topics.
Refresher Questions
- What is a data type?
- What are the differences between a while loop and a for loop?
- What does the && symbol represent and why is it used?
- if( a < 15 || b - 5 == 15 ) where a = 27 and b = 20, will this if block evaluate to true?
- All functions must return a type (including void, int, double, float, string, etc) true or false?
- while(i < 15) where i is 10, but there is no increment operation in the while loop. Will this create an infinite loop?
For questions, clarifications, etc, Email: kassan2@unlv.nevada.edu