Mengenal fondasi Unity: Scene, GameObject, Transform, script MonoBehaviour, dan physics (Rigidbody, Collider, Physics Material), lalu membangun game Unity pertama dengan studi kasus Rimba Runner yang bisa langsung dimainkan

Setelah di episode 2 kita memahami game loop dan arsitektur game, sekarang saatnya masuk ke engine nyata. Kita mulai dari Unity — engine paling populer di industri untuk game 2D maupun 3D, dengan dokumentasi paling melimpah dan ekosistem komunitas terbesar. Di episode ini kalian akan membangun game Unity pertama: versi awal Rimba Runner yang bisa langsung dimainkan.
Mengapa mulai dari Unity? Karena model komponennya yang sangat visual membuat perpindahan dari konsep game loop ke praktik nyata terasa mulus: kalian menempelkan komponen ke GameObject, engine menjalankan lifecycle-nya, dan kalian tinggal mengisi logika di fungsi yang disediakan.
Scene adalah container satu level/lingkungan game — di Unity, satu scene adalah satu file (.unity) yang berisi seluruh objek di level tersebut. GameObject adalah objek paling dasar di Unity: setiap karakter, kamera, lampu, atau dinding adalah GameObject. Sendiri ia hanya sebuah identitas kosong; kemampuan muncul dari komponen yang ditempelkan padanya.
Satu komponen yang selalu ada di setiap GameObject adalah Transform — menyimpan posisi, rotasi, dan skala. Inilah kunci sistem hierarki ala Unity: jika parent bergerak, semua child ikut bergerak relatif terhadapnya.
Struktur level pertama Rimba Runner di Hierarchy panel kira-kira begini:
Scene: Level 1
├── Player (GameObject + SpriteRenderer + Rigidbody2D + PlayerController)
├── Ground (GameObject + SpriteRenderer + BoxCollider2D)
├── Obstacles
│ └── Box (GameObject + SpriteRenderer + BoxCollider2D)
└── Main CameraScript Unity adalah kelas C# yang menurunkan MonoBehaviour. Menurunkan kelas ini memberi kalian akses ke lifecycle engine: Start() dipanggil sekali saat objek hidup, Update() dipanggil setiap frame (ini game loop dari episode 2), dan FixedUpdate() pada interval tetap untuk physics. Contoh paling sederhana — menggerakkan player:
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 5f;
void Update()
{
float move = Input.GetAxis("Horizontal");
Vector2 position = transform.position;
position.x += move * speed * Time.deltaTime;
transform.position = position;
}
}Perhatikan Time.deltaTime — persis delta time dari episode 2. Tanpa itu, kecepatan gerak akan berbeda di setiap frame rate. Konsep yang sama akan muncul berulang kali di Godot (_process(delta)) dan Unreal (Tick(deltaSeconds)).
Untuk mendapatkan gerakan yang lebih halus — misalnya menghormati physics dan collision — gunakan Rigidbody2D alih-alih mengubah transform langsung:
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 5f;
private Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
float move = Input.GetAxis("Horizontal");
rb.velocity = new Vector2(move * speed, rb.velocity.y);
}
}Aturan praktis yang penting: physics selalu dikerjakan lewat FixedUpdate + Rigidbody, bukan Update. Ini memastikan hasilnya deterministik dan konsisten dengan simulated physics — prinsip yang kita bahas sebagai fixed timestep di episode 2.
Physics di Unity bekerja lewat pasangan Rigidbody (mengikuti hukum fisika: gravitasi, tumbukan) dan Collider (bentuk tabrakan). Untuk Rimba Runner versi 2D:
Ketika collider bersentuhan, Unity mengirim event collision. Deteksi tabrakan bisa dilakukan lewat callback:
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Obstacle"))
{
Debug.Log("Kena rintangan!");
}
}Satu properti Physics Material yang wajib dipahami sejak awal: friction dan bounciness. Tanpa friction material, karakter bisa "meluncur" di lantai; terlalu bouncy, karakter memantul tak terkendali. Untuk platformer klasik, set friction tinggi di material lantai.
Waktunya praktik. Ikuti langkah-langkah ini di Unity Hub (versi 2022 LTS atau lebih baru, template 2D (Built-in Render Pipeline)):
RimbaRunner.BoxCollider2D.Rigidbody2D (freeze rotation Z) dan BoxCollider2D.Scripts, buat PlayerController.cs, tempelkan ke Player.[x] Project 2D dibuat (RimbaRunner)
[x] Ground dengan BoxCollider2D
[x] Player dengan Rigidbody2D + BoxCollider2D
[x] PlayerController.cs menempel & bergerak
[x] Player tidak tembus ground saat PlayWarning
Saat membuat GameObject dari script, gunakan Instantiate() dan jangan pernah meletakkan GameObject baru sebagai anak dari GameObject yang sedang dihancurkan (Destroy) — ini penyebab error klasik "trying to access a destroyed object". Pola Instantiate akan kita pakai untuk peluru dan musuh di episode 6.
Tip
Setiap script yang menurunkan MonoBehaviour boleh punya banyak public field (seperti public float speed). Field itu otomatis muncul di Inspector Unity, sehingga designer bisa menyesuaikan nilai tanpa menyentuh kode — ini kolaborasi programmer-designer yang kita bahas di episode 1 dan 17.
Kalian sekarang sudah menapakkan kaki di engine paling populer di industri.
Inti yang harus dibawa pulang:
MonoBehaviour: Start() sekali, Update() tiap frame, FixedUpdate() untuk physics.Time.deltaTime untuk gerakan agar konsisten di semua frame rate.OnCollision*.Di episode 4 selanjutnya kita akan membandingkan dengan Godot fundamentals — node, scene, GDScript/C#, dan signals, plus membangun game Godot pertama. Kalian akan melihat betapa banyak konsep yang ternyata sama, hanya dengan nama dan alur kerja yang berbeda. Sampai jumpa di episode 4!