ObjectPool di Unity
Termasuk bagian Arsitektur Game di Unity dalam perjalanan Unity di Coddy. Pelajaran 48 dari 64.
Unity menyediakan pool, ObjectPool<T> di UnityEngine.Pool. Kamu memberi tahu pool apa yang harus dilakukan pada setiap langkah dengan empat lambda, lalu pool menyimpan objek cadangan dan jumlahnya. Cerobong ini mengepulkan asap setiap 0.2 detik, dan setiap kepulan dikembalikan setelah satu detik:
using UnityEngine;
using UnityEngine.Pool;
public class Chimney : MonoBehaviour
{
public Puff puffPrefab;
private ObjectPool<Puff> pool;
private float timer;
void Awake()
{
pool = new ObjectPool<Puff>(
createFunc: () => Instantiate(puffPrefab),
actionOnGet: puff => puff.gameObject.SetActive(true),
actionOnRelease: puff => puff.gameObject.SetActive(false),
actionOnDestroy: puff => Destroy(puff.gameObject),
collectionCheck: true,
defaultCapacity: 10,
maxSize: 20);
}
void Update()
{
timer += Time.deltaTime;
if (timer >= 0.2f)
{
timer = 0f;
Puff puff = pool.Get();
puff.transform.position = transform.position + Vector3.up;
puff.Launch(pool);
}
}
}// Puff.cs
private IObjectPool<Puff> pool;
private float age;
public void Launch(IObjectPool<Puff> owner)
{
pool = owner;
age = 0f;
}
void Update()
{
transform.Translate(0f, Time.deltaTime, 0f);
age += Time.deltaTime;
if (age >= 1f) pool.Release(this);
}createFunc dijalankan saat Get mendapati pool kosong; actionOnGet dijalankan setiap kali Get dipanggil dan actionOnRelease setiap kali Release dipanggil. Saat sebuah kepulan dikembalikan ketika sudah ada objek cadangan sebanyak maxSize, pool tidak menyimpannya: actionOnDestroy akan menghancurkannya. defaultCapacity hanya menentukan kapasitas awal list milik pool, jadi tidak ada objek yang dibuat sejak awal. CountAll menghitung kepulan yang telah dibuat dan masih dimiliki pool, CountActive menghitung yang sedang ada di dalam game, dan CountInactive menghitung objek cadangan. Get mengaktifkan kepulan sebelum cerobong menempatkannya, dan ini tidak masalah di sini karena Puff tidak memiliki OnEnable yang membaca posisinya. Kepulan menyimpan pool sebagai IObjectPool<Puff>, yaitu interface yang diimplementasikan oleh setiap pool Unity, dan Launch mengatur ulang usianya setiap kali digunakan.
Jika collectionCheck aktif, mengembalikan kepulan yang sudah ada di dalam pool akan memunculkan InvalidOperationException: Trying to release an object that has already been released to the pool. Pemeriksaan ini hanya berjalan di Editor karena pemeriksaan mencari objek cadangan pada setiap Release; dalam build, kepulan akan tersimpan dua kali di dalam pool dan dua pemanggilan Get akan memberikan object yang sama. Penyebab umumnya adalah object yang terus berjalan setelah dikembalikan lalu mengembalikan dirinya lagi. Karena itu, actionOnRelease menonaktifkannya.
Tantangan
SedangLuncurkan kembang api dari pool Unity.
- Di
AwakemilikLauncher, buatObjectPool<Spark>: buat denganInstantiate(sparkPrefab), aktifkan saat diambil, nonaktifkan saat dilepas, hancurkan object saat dilepas,maxSize: 5. - Di
Update, ambil setiap spark denganpool.Get()alih-alihInstantiate. - Di
Return, panggilpool.Release(spark)alih-alihDestroy.
Tekan tombol “Main” dan luncurkan beberapa rentetan kembang api. Lalu tekan tombol “Periksa”.
Coba sendiri
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Pool;
public class Launcher : MonoBehaviour
{
public Spark sparkPrefab;
public int sparks = 8;
void Awake()
{
// Buat pool: ciptakan, ambil, lepaskan, dan hancurkan, dengan maksimal 5 percikan cadangan
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
for (int i = 0; i < sparks; i++)
{
Spark spark = Instantiate(sparkPrefab);
spark.transform.position = transform.position + Vector3.up;
spark.Launch(Direction(i), this);
}
}
}
// Percikan yang masa hidupnya telah berakhir
public void Return(Spark spark)
{
Destroy(spark.gameObject);
}
// Ke luar dan ke atas, tersebar merata di sekeliling peluncur
Vector3 Direction(int i)
{
return Quaternion.Euler(0f, i * 360f / sparks, 0f) * new Vector3(0f, 1f, 3f);
}
}
Semua pelajaran di Arsitektur Game di Unity
1Komponen, Bukan Hierarki
Komponen KecilSkrip Dasar MusuhKomponen AbstrakKomponen yang Bekerja BersamaRangkuman: Turret ModularRangkuman: Meriam Kembar4Data yang Diserialisasi
Class yang Dapat DiserialisasiList di InspectorEnum di InspectorRangkuman: Tabel LootRangkuman: Acak Loot2Antarmuka di Unity
IDamageableAntarmuka dan TryGetComponentGetComponentsRingkasan: Tombol InteractRingkasan: Terdekat dalam Jangkauan5ScriptableObjects
Aset DataStatistik SenjataPengaturan BersamaSelamatkan AnginGelombang sebagai DataRekap: database ItemBeli dari Toko8Kode yang Dapat Digunakan Kembali
Extension methodSingleton GenerikHelper GenerikUlasan: FindNearest3Event
Event C# di UnityBerlangganan di OnEnableField UnityEventEvent Menggerakkan UIRangkuman: Popup PencapaianRangkuman: Timer Popup6Menyimpan dengan JSON
JsonUtilitySimpan GameMuat dan Nilai DefaultRingkasan: Slot SimpananPilih dan Hapus Slot9Object Pooling
Mengapa Menggunakan Object PoolPool dengan QueueObjectPool di UnityRingkasan: Pool PeluruLatihan sendiri: Playground Unity