Menu
CoddyTech

Sebuah Mesin Keadaan

Termasuk bagian Arsitektur Game di Unity dalam perjalanan Unity di Coddy. Pelajaran 29 dari 50.

SetState milik Beacon akan sama pada setiap object yang memiliki state: turret, enemy, dan door. Kode itu bisa berada di class tersendiri, yaitu state machine, yang menyimpan state saat ini dan mengubahnya. Setiap object membuat satu mesin dan memanggilnya, alih-alih mengulang kode:

public class StateMachine
{
    public IState Current { get; private set; }

    public void ChangeState(IState next)
    {
        Current?.Exit();
        Current = next;
        Current.Enter();
    }

    public void Tick()
    {
        Current?.Tick();
    }
}

public class Beacon : MonoBehaviour
{
    public Renderer lamp;
    private StateMachine machine = new StateMachine();
    private IState blink;
    private IState steady;

    void Start()
    {
        blink = new BlinkState(lamp);
        steady = new SteadyState();
        machine.ChangeState(steady);
    }

    void Update()
    {
        if (Keyboard.current.spaceKey.wasPressedThisFrame) machine.ChangeState(machine.Current == steady ? blink : steady);
        machine.Tick();
    }
}

Pemanggilan ChangeState pertama tidak memiliki state yang perlu ditinggalkan: Current bernilai null, dan ?. melewati pemanggilan Exit. Bagian 1 memperingatkan bahwa ?. tidak mendeteksi null palsu milik Unity. Hal itu berlaku untuk Unity Object yang telah dihancurkan, sedangkan state adalah object C# biasa, jadi ?. aman digunakan di sini. Current memiliki private set, jadi tidak ada script yang bisa mengganti state tanpa melalui ChangeState beserta Exit dan Enter-nya.

Urutan di dalam ChangeState penting setiap kali dua state menyentuh hal yang sama. Exit membatalkan perubahan yang dibuat state lama, lalu Enter menyiapkan state baru, sehingga state baru menjadi penentu terakhir. Jika Enter milik DarkState mematikan lampu dan dijalankan sebelum Exit milik BlinkState, Exit itu akan menyalakan lampu lagi dalam state gelap. StateMachine juga merupakan class biasa: beacon, turret, dan enemy masing-masing membuat mesin sendiri dengan new dan memanggil Tick-nya dari Update.

challenge icon

Tantangan

Sedang

Tahan Space untuk menyelinap. WalkState dan SneakState sudah siap di PlayerStates.cs: Enter dan Exit-nya mencatat apa yang terjadi (Walk: enter, Sneak: exit...), dan Tick-nya memanggil Move() milik pemain. Tulis machine yang menjalankannya.

  • Di StateMachine.cs, tulis class biasa StateMachine dengan property publik Current yang hanya dapat diatur oleh machine, method ChangeState(IState next) yang menjalankan Exit state lama, lalu Enter state baru, dan method Tick() yang menjalankan Tick state saat ini.
  • Pemain meminta state-nya setiap frame, jadi ChangeState tidak melakukan apa pun jika dipanggil dengan state yang sudah aktif: tidak ada Exit dan tidak ada Enter.
  • Di Player.cs, tambahkan field StateMachine bernama machine. Di Start, buat machine dan kedua state (masing-masing menerima pemain), lalu mulai dengan berjalan. Di Update, beralih ke menyelinap selama Space ditahan dan ke berjalan jika tidak, lalu jalankan Tick pada machine.

Tekan Play, berjalanlah, tahan Space dan terus berjalan, lalu tekan Check.

Coba sendiri

// StateMachine: Current, ChangeState, dan Tick
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Arsitektur Game di Unity