Un pool con una coda
Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 47 di 64.
A una piscina serve un posto dove conservare gli oggetti di riserva, e C# ha la raccolta adatta: Queue<T>: Enqueue aggiunge un elemento in fondo, Dequeue prende quello in testa e Count indica quanti sono in attesa. Questo acquario fa salire una bolla ogni 0.3 secondi, e ogni bolla torna nella piscina quando raggiunge la superficie:
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, sul prefab della bolla
public BubblePool pool;
void Update()
{
transform.Translate(0f, 2f * Time.deltaTime, 0f);
if (transform.position.y > 5f) pool.Return(gameObject);
}Get controlla prima Count, perché Dequeue su una coda vuota genera un'eccezione InvalidOperationException. Solo allora esegue Instantiate, e solo a una bolla nuova serve impostare il campo pool: una riutilizzata lo conserva. La coda restituisce per prima la bolla che ha atteso più a lungo, secondo il principio «primo entrato, primo uscito». Una bolla in superficie chiama Return invece di Destroy e rimane nella scena, inattiva, fino al successivo Get.
Get posiziona la bolla prima di SetActive(true), perché attivarla esegue subito il suo OnEnable, e tutto ciò che si trova lì dovrebbe vedere la nuova posizione, non quella in cui era scomparsa l'ultima volta. È anche lì che un oggetto riutilizzato ricomincia: Awake e Start sono stati eseguiti una volta, quando la bolla è stata creata, mentre OnEnable viene eseguito a ogni Get.
Sfida
MedioMetti in pool le impronte invece di distruggerle.
- In
Trail, tieni le impronte di scorta in unaQueue<GameObject>.Return(footprint)la disattiva e la inserisce nella coda;Startcreaprewarmimpronte e le restituisce. Get(position)estrae un’impronta di scorta dalla coda (oppure ne crea una), la posiziona e la attiva.- In
Footprint, sostituisci Destroy: azzera l’età inOnEnable; dopolifesecondi,trail.Return(gameObject).
Premi «Gioca» e cammina: le impronte svaniscono dopo 1.5 secondi. Poi premi «Verifica».
Provalo tu
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;
// Riempi il pool con impronte preparate in anticipo
}
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)
{
// Le impronte di riserva attendono nel pool
}
}
Tutte le lezioni di Architettura dei giochi in Unity
1Componenti, non gerarchie
Componenti piccoliUno script base per i nemiciComponenti astrattiComponenti che collaboranoRipasso: torretta modulareRipasso: cannone doppio4Dati serializzati
Classi serializzabiliElenchi nell'InspectorEnum nell'InspectorRiepilogo: tabella del bottinoRiepilogo: tira il bottino2Interfacce in Unity
IDamageableInterfacce e TryGetComponentGetComponentsRiepilogo: tasto InteragisciRiepilogo: il più vicino a portata5ScriptableObjects
Asset di datiStatistiche delle armiImpostazioni condiviseSalva il ventoOnde come datiRiepilogo: database degli oggettiRiepilogo: comprare dal negozio3Eventi
Eventi C# in UnityIscrizione in OnEnableCampi UnityEventGli eventi guidano l'interfaccia utenteRiepilogo: popup dei risultatiRiepilogo: timer del popup6Salvare con JSON
JsonUtilitySalva la partitaCaricamento e valori predefinitiRiepilogo: slot di salvataggioScegli ed elimina uno slot9Pooling degli oggetti
Perché usare un pool di oggettiUn pool con una codaObjectPool di UnityRiepilogo: pool di proiettiliEsercitati da solo: Playground Unity