Menu
CoddyTech

Keadaan sebagai class

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

Switch pada enum di bagian 3 menempatkan pekerjaan setiap state dalam satu Update. Cara ini tidak lagi cocok saat state memiliki datanya sendiri: timer yang hanya digunakan satu state akhirnya menjadi field di MonoBehaviour, berdampingan dengan field milik setiap state lainnya, dan setiap case harus ingat untuk mereset nilai yang digunakannya. Pola state dari C# memberi setiap state class tersendiri, dan setiap class mengimplementasikan satu antarmuka. Suar jalan ini berkedip atau tetap menyala, dan Space beralih di antara keduanya:

public interface IState
{
    void Enter();
    void Tick();
    void Exit();
}

public class BlinkState : IState
{
    private Renderer lamp;
    private float timer;

    public BlinkState(Renderer lamp)
    {
        this.lamp = lamp;
    }

    public void Enter() { timer = 0f; }

    public void Tick()
    {
        timer += Time.deltaTime;
        if (timer >= 0.5f)
        {
            timer = 0f;
            lamp.enabled = !lamp.enabled;
        }
    }

    public void Exit() { lamp.enabled = true; }
}

public class SteadyState : IState
{
    public void Enter() { }
    public void Tick() { }
    public void Exit() { }
}

public class Beacon : MonoBehaviour
{
    public Renderer lamp;
    private IState blink;
    private IState steady;
    private IState current;

    void Start()
    {
        blink = new BlinkState(lamp);
        steady = new SteadyState();
        SetState(steady);
    }

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

    void SetState(IState next)
    {
        if (current != null) current.Exit();
        current = next;
        current.Enter();
    }
}

State tersebut adalah class C# biasa, bukan MonoBehaviour. Kamu membuatnya dengan new dan memberikan kebutuhan mereka melalui constructor, dalam contoh ini Renderer lampu, karena mereka bukan komponen dan tidak dapat memanggil GetComponent atau menampilkan field di Inspector. Unity juga tidak pernah memanggil method mereka: Beacon adalah MonoBehaviour, jadi Update miliknya memanggil current.Tick() setiap frame.

timer hanya dimiliki BlinkState, dan Enter miliknya mengatur nilainya menjadi 0 setiap kali suar mulai berkedip. Exit merapikan keadaan saat state berakhir: Space bisa ditekan saat lampu sedang mati, dan Exit menyalakannya kembali, sehingga SteadyState tidak pernah dimulai dengan lampu mati. SetState menjalankan Exit milik state lama, lalu Enter milik state baru. State ketiga, seperti denyut lambat, bisa dibuat sebagai satu class lagi, dan Update milik Beacon tidak perlu diubah.

challenge icon

Tantangan

Sedang

Sebuah turret penjaga melindungi halaman. Panah menggerakkan Player (siap). Beri turret dua state yang ditulis sebagai class:

  • Di IState.cs, deklarasikan public interface IState dengan void Enter(), void Tick(), dan void Exit().
  • Di TurretStates.cs, tulis dua class biasa yang mengimplementasikannya. ScanState menerima kepala turret di konstruktornya. Class ini mengayunkan kepala dari sisi ke sisi: sudut y lokal kepala bergerak dengan kecepatan 90 derajat per detik antara -45 dan 45, dimulai dari 0 dan berbalik ke atas setiap kali pemindaian dimulai. Enter-nya juga mewarnai kepala dengan Color.green.
  • AlertState menerima kepala dan player. Enter-nya mewarnai kepala dengan Color.red dan mencatat Intruder!; Tick-nya memutar kepala agar menghadap player hanya pada sumbu y, tanpa kemiringan; Exit-nya mencatat All clear.
  • Di Turret.cs, buat kedua state di Start dan mulai pemindaian. Setiap frame, beralih ke mode waspada saat player berada lebih dekat dari range (4) ke turret, dan kembali memindai saat player tidak berada di dekatnya, lalu jalankan Tick dari state saat ini. Perubahan state menjalankan Exit dari state lama, lalu Enter dari state baru.

Tekan Play, berjalanlah mendekati turret lalu menjauh lagi, kemudian tekan Check.

Coba sendiri

using UnityEngine;

// ScanState dan AlertState
quiz iconUji dirimu

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

Semua pelajaran di Arsitektur Game di Unity