Transisi
Termasuk bagian Arsitektur Game di Unity dalam perjalanan Unity di Coddy. Pelajaran 30 dari 50.
Siapa yang menentukan kapan state berubah? Jika pemiliknya yang menentukan, semua aturan kembali berada dalam satu Update, seperti pada switch. Biasanya, setiap state mengetahui cara keluarnya sendiri: di Tick, state memeriksa kondisinya dan meminta state berikutnya kepada machine. Bom ini menunggu sampai player mendekat, lalu membakar sumbunya, dan kembali menunggu jika player berlari:
public class Bomb : MonoBehaviour
{
public Transform player;
public StateMachine machine = new StateMachine();
public IState idle;
public IState fuse;
void Start()
{
idle = new IdleState(this);
fuse = new FuseState(this);
machine.ChangeState(idle);
}
void Update() { machine.Tick(); }
public bool PlayerNear()
{
return Vector3.Distance(transform.position, player.position) < 3f;
}
}
public class IdleState : IState
{
private Bomb bomb;
public IdleState(Bomb bomb) { this.bomb = bomb; }
public void Enter() { }
public void Exit() { }
public void Tick()
{
if (bomb.PlayerNear()) bomb.machine.ChangeState(bomb.fuse);
}
}
public class FuseState : IState
{
private Bomb bomb;
private float timer;
public FuseState(Bomb bomb) { this.bomb = bomb; }
public void Enter() { timer = 2f; }
public void Exit() { }
public void Tick()
{
if (!bomb.PlayerNear())
{
bomb.machine.ChangeState(bomb.idle);
return;
}
timer -= Time.deltaTime;
if (timer <= 0f)
{
Debug.Log("Boom!");
Object.Destroy(bomb.gameObject);
}
}
}Setiap state menerima bomb di konstruktornya, lalu mengakses machine, pemeriksaan player, dan state lainnya melalui bomb. Bomb membuat setiap state satu kali, di Start, jadi sebuah state tidak pernah membuat state lain dengan new: dua state yang saling membuat di konstruktornya akan terus berulang sampai stack overflow. Update milik bomb hanya menjalankan Tick pada machine, sementara aturannya berada di state yang sesuai: sumbu dengan durasi 2 detik hanya menjadi urusan FuseState.
ChangeState langsung menjalankan Exit milik FuseState dan Enter milik IdleState, tetapi bagian Tick milik FuseState yang tersisa tetap akan berjalan setelah pemanggilan itu. return menghentikannya, jika tidak, sumbu akan terbakar satu frame lagi untuk state yang sudah berakhir. Destroy ditulis sebagai Object.Destroy: MonoBehaviour mewarisinya dari class Object milik Unity, sedangkan class biasa harus menyebutkan nama class tersebut.
Tantangan
SedangPerangkap lalat menjepret siapa pun yang mendekatinya. Flytrap.cs sudah siap: file ini membuat mesin dan ketiga state (field publik open, snap, dan chew), memulai dengan Open dan menjalankan tick pada mesin setiap frame, serta PlayerInReach() menyatakan apakah pemain berjarak kurang dari 2 di atas tanah. Di FlytrapStates.cs, semua Enter sudah ditulis (warna, timer, log Chomp!). Tulis transisinya di Tick setiap state:
- Open: saat pemain berada dalam jangkauan, perangkap menjepret.
- Snap berlangsung selama 0.5 detik. Setelah itu, perangkap mengunyah jika pemain masih dalam jangkauan, dan terbuka lagi jika pemain berhasil menjauh.
- Chew berlangsung selama 3 detik, siapa pun yang berada di sekitarnya, lalu perangkap terbuka lagi.
Gunakan tombol panah untuk menggerakkan Player. Tekan Play, berjalanlah mendekati perangkap, lalu coba hindari jepretannya, kemudian tekan Check.
Coba sendiri
using UnityEngine;
public class OpenState : IState
{
private Flytrap trap;
public OpenState(Flytrap trap)
{
this.trap = trap;
}
public void Enter()
{
trap.Paint(new Color(0.3f, 0.8f, 0.2f));
}
public void Tick()
{
// Tutup dengan cepat saat pemain berada dalam jangkauan
}
public void Exit()
{
}
}
public class SnapState : IState
{
private Flytrap trap;
private float timer;
public SnapState(Flytrap trap)
{
this.trap = trap;
}
public void Enter()
{
timer = 0f;
trap.Paint(new Color(1f, 0.55f, 0.1f));
}
public void Tick()
{
// Setelah 0.5 detik: kunyah jika pemain masih dalam jangkauan, buka kembali jika tidak
}
public void Exit()
{
}
}
public class ChewState : IState
{
private Flytrap trap;
private float timer;
public ChewState(Flytrap trap)
{
this.trap = trap;
}
public void Enter()
{
timer = 3f;
trap.Paint(new Color(0.5f, 0.05f, 0.1f));
Debug.Log("Chomp!");
}
public void Tick()
{
// Setelah 3 detik: buka kembali
}
public void Exit()
{
}
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Arsitektur Game di Unity
1Komponen, Bukan Hierarki
Komponen KecilSkrip Dasar MusuhKomponen AbstrakKomponen yang Bekerja SamaRingkasan: Turret Modular5ScriptableObjects
Aset DataStatistik SenjataPengaturan BersamaGelombang sebagai DataUlasan: database Item8Kode yang Dapat Digunakan Kembali
Extension methodSingleton GenerikHelper GenerikUlasan: FindNearest