Menu
CoddyTech

Pool dengan Queue

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

Sebuah pool membutuhkan tempat untuk menyimpan object cadangannya, dan C# menyediakan collection untuk itu, Queue<T>: Enqueue menambahkan item di bagian belakang, Dequeue mengambil item di bagian depan, dan Count menunjukkan jumlah item yang menunggu. Akuarium ini mengeluarkan satu gelembung setiap 0.3 detik, dan setiap gelembung kembali ke pool saat mencapai permukaan:

using System.Collections.Generic;
using UnityEngine;

public class BubblePool : MonoBehaviour
{
    public GameObject bubblePrefab;
    private Queue<GameObject> pool = new Queue<GameObject>();
    private float timer;

    void Update()
    {
        timer += Time.deltaTime;
        if (timer >= 0.3f)
        {
            timer = 0f;
            Get(new Vector3(Random.Range(-2f, 2f), 0f, 0f));
        }
    }

    public GameObject Get(Vector3 position)
    {
        GameObject bubble;
        if (pool.Count > 0)
        {
            bubble = pool.Dequeue();
        }
        else
        {
            bubble = Instantiate(bubblePrefab);
            bubble.GetComponent<Bubble>().pool = this;
        }
        bubble.transform.position = position;
        bubble.SetActive(true);
        return bubble;
    }

    public void Return(GameObject bubble)
    {
        bubble.SetActive(false);
        pool.Enqueue(bubble);
    }
}
// Bubble.cs, pada prefab gelembung
public BubblePool pool;

void Update()
{
    transform.Translate(0f, 2f * Time.deltaTime, 0f);
    if (transform.position.y > 5f) pool.Return(gameObject);
}

Get memeriksa Count terlebih dahulu, karena Dequeue pada queue kosong akan memunculkan InvalidOperationException. Setelah itu barulah Instantiate dipanggil, dan hanya gelembung baru yang perlu diatur field pool-nya: gelembung yang digunakan kembali masih memilikinya. Queue memberikan gelembung yang paling lama menunggu terlebih dahulu, yang masuk pertama keluar pertama. Gelembung di permukaan memanggil Return, bukan Destroy, lalu tetap berada di scene dalam keadaan tidak aktif sampai Get berikutnya.

Get menempatkan gelembung sebelum SetActive(true), karena mengaktifkannya langsung menjalankan OnEnable, dan apa pun yang ada di sana seharusnya melihat posisi baru, bukan posisi tempat gelembung itu terakhir kali menghilang. Di sini juga object yang digunakan kembali memulai ulang: Awake dan Start berjalan satu kali, saat gelembung dibuat, sedangkan OnEnable berjalan setiap kali Get dipanggil.

challenge icon

Tantangan

Sedang

Jejak kaki di pasir. Panah menggerakkan Player (siap). Trail.cs, yang dipasang pada Player, membuat jejak kaki setiap kali berjalan sejauh 1 unit dengan memanggil Get(position), dan setiap Footprint bertahan selama life (1.5) detik. Saat ini Get membuat jejak kaki baru setiap kali, lalu setiap jejak kaki menghancurkan dirinya sendiri. Gunakan pool:

  • Di Trail.cs, simpan jejak kaki cadangan dalam Queue<GameObject>. Field trail setiap jejak kaki yang dibuat Trail harus diatur ke Trail ini.
  • Di Start, isi pool dengan prewarm (6) jejak kaki, yang dibuat lalu dinonaktifkan, sehingga langkah pertama tidak membuat jejak kaki baru.
  • Get(position) mengambil jejak kaki dari antrean jika ada, dan hanya membuat yang baru jika antrean kosong. Lalu, fungsi ini menempatkan jejak kaki dan mengaktifkannya.
  • Return(footprint) menonaktifkan jejak kaki dan memasukkannya ke antrean.
  • Di Footprint.cs, jejak kaki menghitung usianya dan, setelah life detik, kembali dengan trail.Return(gameObject), bukan dihancurkan. Jejak kaki yang digunakan kembali akan bertahan selama 1.5 detik penuh lagi.

Tekan Play, berjalan-jalan sebentar, lalu tekan Check.

Coba sendiri

using System.Collections.Generic;
using UnityEngine;

public class Trail : MonoBehaviour
{
    public GameObject footprintPrefab;
    public float step = 1f;
    public int prewarm = 6;
    private Vector3 lastDrop;

    void Start()
    {
        lastDrop = transform.position;
        // Isi pool dengan jejak kaki awal sebanyak prewarm
    }

    void Update()
    {
        if (Vector3.Distance(transform.position, lastDrop) >= step)
        {
            lastDrop = transform.position;
            Get(new Vector3(transform.position.x, 0.02f, transform.position.z));
        }
    }

    public GameObject Get(Vector3 position)
    {
        GameObject footprint = Instantiate(footprintPrefab, position, Quaternion.identity);
        footprint.GetComponent<Footprint>().trail = this;
        return footprint;
    }

    public void Return(GameObject footprint)
    {
        // Jejak kaki cadangan menunggu di pool
    }
}
quiz iconUji dirimu

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

Semua pelajaran di Arsitektur Game di Unity