Pool z kolejką
Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 47 z 64.
Basen potrzebuje miejsca do przechowywania zapasowych obiektów, a C# ma do tego kolekcję Queue<T>: Enqueue dodaje element na końcu, Dequeue pobiera element z początku, a Count podaje, ile elementów czeka. W tym akwarium co 0.3 sekundy wypływa bańka, a każda z nich wraca do puli przy powierzchni:
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, na prefabie bąbelka
public BubblePool pool;
void Update()
{
transform.Translate(0f, 2f * Time.deltaTime, 0f);
if (transform.position.y > 5f) pool.Return(gameObject);
}Get najpierw sprawdza Count, ponieważ wywołanie Dequeue na pustej kolejce powoduje wyjątek InvalidOperationException. Dopiero potem wywołuje Instantiate, a pole pool trzeba ustawić tylko nowej bańce: używana ponownie nadal je ma. Kolejka wydaje bańkę, która czekała najdłużej — pierwsza weszła, pierwsza wychodzi. Bańka przy powierzchni wywołuje Return zamiast Destroy i pozostaje w scenie, nieaktywna, aż do następnego wywołania Get.
Get ustawia pozycję bańki przed wywołaniem SetActive(true), ponieważ jej włączenie natychmiast uruchamia OnEnable, a wszystko, co się tam dzieje, powinno widzieć nową pozycję, a nie tę, w której bańka ostatnio zniknęła. Właśnie wtedy używany ponownie obiekt zaczyna od początku: Awake i Start uruchomiły się raz, gdy utworzono bańkę, a OnEnable uruchamia się przy każdym wywołaniu Get.
Wyzwanie
ŚredniUmieszczaj odciski w puli zamiast ich niszczyć.
- W
Trailprzechowuj zapasowe obiekty wQueue<GameObject>.Return(footprint)wyłącza obiekt i dodaje go do kolejki;Starttworzyprewarmodcisków i zwraca je. Get(position)pobiera zapasowy obiekt z kolejki (lub tworzy nowy), umieszcza go i włącza.- W
Footprintzastąp wywołanie Destroy: zresetuj wiek wOnEnable; polifesekundach wywołajtrail.Return(gameObject).
Naciśnij „Graj” i idź: odciski znikną po 1.5 sekundy. Następnie naciśnij „Sprawdź”.
Spróbuj swoich sił
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;
// Wypełnij pulę śladami stóp przygotowanymi z wyprzedzeniem
}
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)
{
// Zapasowe ślady stóp czekają w puli
}
}
Wszystkie lekcje w sekcji Architektura gier w Unity
1Komponenty, nie hierarchie
Małe komponentyBazowy skrypt przeciwnikaKomponenty abstrakcyjneWspółpracujące komponentyPowtórka: modułowa wieżyczkaPowtórka: podwójne działo4Dane serializowane
Klasy serializowalneListy w InspectorzeEnumy w InspectorzePodsumowanie: tabela łupówPodsumowanie: losowanie łupów2Interfejsy w Unity
IDamageableInterfejsy i TryGetComponentGetComponentsPowtórka: klawisz interakcjiPowtórka: najbliższy w zasięgu5ScriptableObjects
Zasoby danychStatystyki broniWspółdzielone ustawieniaOcal wiatrFale jako danePowtórka: Baza przedmiotówPowtórka: Kupowanie w sklepie8Kod wielokrotnego użytku
Metody rozszerzająceGeneryczny singletonGeneryczne metody pomocniczePodsumowanie: FindNearest3Zdarzenia
Zdarzenia C# w UnitySubskrybuj w OnEnablePola UnityEventZdarzenia sterują UIPodsumowanie: popup osiągnięciaPodsumowanie: timer popupu6Zapisywanie za pomocą JSON
JsonUtilityZapisz gręWczytywanie i wartości domyślnePodsumowanie: sloty zapisuWybierz i usuń slot9Pooling obiektów
Dlaczego używać poolingu obiektówPool z kolejkąObjectPool w UnityPodsumowanie: pula pociskówPoćwicz samodzielnie: Edytor online Unity