The Basics of C# in Unity: From Variables to the Game Loop
Introduction⌗
This lesson introduces the fundamentals of C# programming within the Unity game engine. We will cover key concepts such as variables, data types, functions, and Unity’s lifecycle methods (Start and Update). By the end, you will know how to create a simple script that manipulates variables and outputs information to the Unity Console.
Create a New Script⌗
In Unity, right-click in the Project window and select Create > Scripting > MonoBehaviour Script. Name it Player. Double-click the script to open it in your code editor (e.g., Visual Studio or Visual Studio Code).
Namespaces (the using lines)⌗
The lines at the very top beginning with using are namespaces. They tell your script where to find types and APIs. For example, using UnityEngine gives access to Unity-specific classes like MonoBehaviour and components such as Transform. These lines end with semicolons, just like sentences end with periods.
Transform is a class that represents an object’s position, rotation, and scale in 3D space. It’s one of the most commonly used components in Unity. You can find it on any GameObject in the Inspector.
Classes and MonoBehaviour⌗
Every C# script you create in Unity defines a class and, by default, names it NewMonoBehaviourScript. Rename it to Player to match the filename. The Player class inherits from MonoBehaviour, which is Unity’s base class that enables your script to plug into the engine’s lifecycle (e.g., Start, Update). Without inheriting MonoBehaviour, Unity wouldn’t recognize those lifecycle methods. Everything between the curly braces { } is the class body where your data and behavior live.
Variables (Fields): Storing the State of Your Game⌗
In the Player class we’ll add a few fields—these are variables declared at the class level. Each variable has a type, a name, and optionally an initial value. Here are the fields in our example. We’ll add them one by one:
public int Health = 5;
private float Speed = 0.5f;
// bool PlayerIsGrounded = true;
string Display = "Speed: ";
intstores whole numbers. If you don’t assign a value, the default forintis 0.floatstores decimal numbers. In C# for Unity, appendfto mark a literal as a float (0.5f); otherwise it’s treated as a double and can cause type errors.boolcan only be true or false. The default value isfalseif not set.stringstores characters and words; always wrap the literal in quotes. Fields without an access modifier, like this one, are private by default.
A note on access:
Healthis public, so it’s visible in the Inspector and to other scripts.Speedis private, so only this script can access it. A common pattern is to keep fields private and expose them in the Inspector with[SerializeField], which preserves encapsulation as projects scale.
Statements and comments⌗
Each instruction typically ends with a semicolon (;). You can comment out a line with // or block out multiple lines with /* ... */—handy for testing or leaving notes.
// This is a single-line comment
/* This is a
multi-line comment */
int x = 10; // This is also a comment
Unity’s Lifecycle Methods: Start and Update⌗
Unity calls special methods on MonoBehaviour at defined times. These methods are declared with the void keyword, which means they don’t return a value.
Startruns once on the first frame when the script becomes active. It’s perfect for initialization—in our script we setHealthto10and immediately print it.Updateruns once per frame while the script is active. It’s used for per-frame behavior like input handling, animation state, or—in this example—changingSpeedevery frame and logging it.
Setting a Variable and Printing to the Console⌗
Inside Start, we set Health to 10 and log it with Debug.Log(Health):
void Start()
{
Health = 10;
Debug.Log(Health);
}
Inside Update, we double Speed every frame with Speed = Speed * 2 and log it with Debug.Log(Display + Speed):
void Update()
{
Speed = Speed * 2;
Debug.Log(Display + Speed);
}
Debugging: Printing to the Console⌗
Debug.Log(...) is your quickest way to see what’s happening. You can concatenate text and values with +, as in "Speed: " + Speed. Watch the Console tab in Unity to see those messages arrive in real time.
For performance, avoid spamming Debug.Log in shipping builds. Use it while developing, then reduce or gate logs behind conditions.
Running the Script⌗
To test your script, create a GameObject in your scene (e.g., an empty object or a character model), then drag the Player script onto it in the Inspector to add it as a component. Press Play in Unity.
You’ll see Health print once, then Speed doubling and printing every frame. Stop Play Mode to reset the values.
The Finished Script⌗
using UnityEngine;
public class Player : MonoBehaviour
{
public int Health = 5;
private float Speed = 0.5f;
// bool PlayerIsGrounded = true;
string Display = "Speed: ";
void Start()
{
Health = 10;
Debug.Log(Health);
}
void Update()
{
Speed = Speed * 2;
Debug.Log(Display + Speed);
}
}
Quiz: Spot and Fix the C# Errors⌗
Test your understanding! Each code snippet below contains a common C# error. Try to identify what’s wrong and how to fix it before checking the solutions.
Error #1⌗
int health = 100
Debug.Log(health);
What’s wrong here?
Click for solution
Problem: Missing semicolon after the first statement. Fix: Add a semicolon after each statement.
int health = 100;
Debug.Log(health);
Error #2⌗
float speed = 5.5;
What’s wrong here?
Click for solution
Problem: Missing ‘f’ suffix on float literal. Fix: Add ‘f’ suffix to float literals to avoid type conversion issues.
float speed = 5.5f;
Error #3⌗
Script file is named “Player.cs” but contains:
public class PlayerController : MonoBehaviour
{
// class content
}
What’s wrong here?
Click for solution
Problem: Class name doesn’t match filename. Fix: Make sure the class name matches the filename exactly.
public class Player : MonoBehaviour
{
// class content
}
Error #4⌗
int score;
Debug.Log("Score: " + score + 10);
What’s wrong here?
Click for solution
Problem: Using uninitialized variable and incorrect string concatenation. Fix: Initialize variables before use and use parentheses for math operations.
int score = 0;
Debug.Log("Score: " + (score + 10));
Error #5⌗
public class Player
{
void Start()
{
Debug.Log("Game started!");
}
}
What’s wrong here?
Click for solution
Problem: Missing MonoBehaviour inheritance. Fix: Inherit from MonoBehaviour to access Unity’s lifecycle methods.
public class Player : MonoBehaviour
{
void Start()
{
Debug.Log("Game started!");
}
}