Unity Game Development with C#: Complete Beginner's Guide
Unity combines a visual editor with C# scripting to let you build 2D, 3D, VR, and AR games for 25+ platforms. C# is the language that brings your GameObjects to life — without it, you have a static scene.
In this tutorial, you’ll learn Unity’s C# scripting model: MonoBehaviour lifecycle, physics with Rigidbody and Collider, input handling, prefabs, scenes, and build settings. By the end, you’ll have a working player controller and understand how to structure a Unity project.
What You’ll Learn
- Unity interface: Scene, Game, Hierarchy, Project, Inspector panels
- GameObjects and components architecture
- MonoBehaviour lifecycle: Awake, Start, Update, FixedUpdate, LateUpdate
- Physics: Rigidbody, Collider, triggers, raycasts
- Input handling with InputManager and InputSystem
- Prefabs, scenes, and build settings
Why Unity C# Matters
Unity powers games like Hollow Knight, Cities: Skylines, and Among Us. Beyond games, it’s used in architecture visualization, film production, and training simulations. C# in Unity is approachable for beginners and powerful enough for AAA studios. At DodaTech, we use Unity for interactive product demos in Doda Browser that showcase hardware acceleration across devices.
Learning Path
flowchart LR
A[Game Dev Overview] --> B[Unity Guide]
B --> C[Unity C# Scripting<br/>You are here]
C --> D[Unreal Blueprints]
C --> E[2D Animation]
style C fill:#f90,color:#fff
The Unity Interface
Unity’s editor has five key panels:
| Panel | Purpose |
|---|---|
| Scene | Visual viewport for editing your game world |
| Game | Renders what the camera sees — your play view |
| Hierarchy | Lists every GameObject in the current scene |
| Project | File browser for assets, scripts, and scenes |
| Inspector | Shows properties of the selected GameObject or asset |
A GameObject is every object in your scene — a character, camera, light, or empty marker. It’s an invisible container that holds components (scripts, renderers, colliders, audio sources). Components give GameObjects their behavior and appearance.
MonoBehaviour and the Lifecycle
Every C# script that needs to run in a scene extends MonoBehaviour. This base class gives you lifecycle methods that Unity calls automatically:
using UnityEngine;
public class PlayerController : MonoBehaviour
{
void Awake()
{
// Called when the script instance is loaded (before Start)
Debug.Log("Player is waking up");
}
void Start()
{
// Called before the first frame update (after Awake)
Debug.Log("Player is starting");
}
void Update()
{
// Called once per frame (frame-rate dependent)
// Use for input reading, non-physics movement, timers
}
void FixedUpdate()
{
// Called at a fixed timestep (default 0.02s)
// Use for physics calculations (Rigidbody forces, movement)
}
void LateUpdate()
{
// Called after all Update methods
// Use for camera follow, IK adjustments
}
}Expected output: The console prints “Player is waking up”, then “Player is starting” on scene load.
Physics: Rigidbody and Collider
Physics in Unity requires two components:
- Rigidbody — enables physics simulation (gravity, forces, velocity)
- Collider — defines the shape used for collision detection (Box, Sphere, Capsule, Mesh)
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float speed = 5f;
public float jumpForce = 7f;
private Rigidbody rb;
private bool isGrounded;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
// Read input in Update (frame-rate independent input read)
float moveX = Input.GetAxis("Horizontal");
float moveZ = Input.GetAxis("Vertical");
Vector3 move = transform.right * moveX + transform.forward * moveZ;
// Apply physics movement in FixedUpdate
if (Input.GetButtonDown("Jump") && isGrounded)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
isGrounded = false;
}
// Use MovePosition for smooth physics-based movement
rb.MovePosition(transform.position + move * speed * Time.deltaTime);
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Ground"))
isGrounded = true;
}
void OnCollisionExit(Collision collision)
{
if (collision.gameObject.CompareTag("Ground"))
isGrounded = false;
}
}Expected behavior: Press WASD to move, Space to jump. The player can only jump when touching the ground. Time.deltaTime makes movement frame-rate independent.
Working with Prefabs
A prefab is a reusable GameObject template. Create an enemy once, save it as a prefab, and instantiate it at runtime:
public class BulletSpawner : MonoBehaviour
{
public GameObject bulletPrefab;
public Transform firePoint;
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
GameObject bullet = Instantiate(
bulletPrefab,
firePoint.position,
firePoint.rotation
);
// Destroy bullet after 2 seconds to avoid memory leaks
Destroy(bullet, 2f);
}
}
}Expected behavior: Clicking the mouse (or pressing Ctrl) spawns a bullet prefab at the fire point. The bullet self-destructs after 2 seconds.
Changes to the prefab asset update every instance — the same approach used in DodaZIP for template-based file generation.
Scenes and Build Settings
A scene is a container for your game world. Games typically have multiple scenes:
MenuScene → GameScene → GameOverSceneSwitch scenes programmatically:
using UnityEngine.SceneManagement;
public class SceneSwitcher : MonoBehaviour
{
public void LoadGameScene()
{
SceneManager.LoadScene("GameScene");
}
public void ReloadCurrentScene()
{
Scene currentScene = SceneManager.GetActiveScene();
SceneManager.LoadScene(currentScene.name);
}
}Build Settings (File > Build Settings) let you:
- Add all scenes to the build list
- Set the platform target (Windows, Mac, Linux, Android, iOS, WebGL)
- Configure player settings (resolution, icon, company name)
Common Mistakes Beginners Make
1. Modifying transform.position on a Rigidbody
Use rb.MovePosition() or rb.AddForce() instead. Direct position changes bypass physics and cause jittery, unrealistic movement.
2. Forgetting Time.deltaTime
Movement without Time.deltaTime runs at different speeds on different frame rates. Always multiply movement by Time.deltaTime for consistency.
3. Checking Input in FixedUpdate
Input.GetAxis() reads correctly in Update(). In FixedUpdate(), input values may be stale. Read input in Update() and apply physics in FixedUpdate().
4. Scaling the Parent Instead of Children
Non-uniform scaling on a parent object distorts child colliders. Keep root objects at (1,1,1) scale.
5. Not Using CompareTag
gameObject.tag == "Enemy" allocates memory. Use gameObject.CompareTag("Enemy") — it’s faster and zero-alloc.
6. Attaching Scripts to Wrong Objects
A movement script on the camera won’t move the player. Attach scripts to the GameObject they control.
7. Forgetting Layer Collision Matrix
Configure Edit > Project Settings > Physics > Layer Collision Matrix to prevent, say, player bullets hitting the player who fired them.
Practice Questions
1. What’s the difference between Update() and FixedUpdate()?
Update() runs every frame (variable rate). FixedUpdate() runs at a fixed timestep (default 0.02s) and is used for physics calculations.
2. Why use Instantiate() with prefabs?
Prefabs allow you to spawn objects at runtime without having copies sitting in the scene. Changes to the prefab propagate to all instances.
3. What does Time.deltaTime do?
It returns the time in seconds since the last frame. Multiplying movement by it makes speed independent of frame rate.
4. How do you detect a collision in Unity?
Add OnCollisionEnter(Collision collision) to a script on a GameObject that has both a Collider and a Rigidbody.
5. Challenge: Add a sprint mechanic with stamina.
Track isSprinting bool. When LeftShift is held, multiply speed by 2. Add a stamina float that depletes while sprinting and recovers at rest. Clamp it between 0 and maxStamina.
Mini Project: Ball Collector
Create a new 3D project:
- Add a Sphere with Rigidbody and SphereCollider
- Write a script that applies force based on arrow keys
- Create Cube pickups with BoxCollider (isTrigger = true)
- Add OnTriggerEnter to detect pickups, destroy them, increment score
- Display score with TextMeshPro
FAQ
What’s Next
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro