Пул на основе очереди
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 47 из 64.
Пулу нужно место для хранения запасных объектов, и в C# для этого есть коллекция Queue<T>: Enqueue добавляет элемент в конец, Dequeue забирает элемент из начала, а Count показывает, сколько элементов ждут. В этом аквариуме пузырьки поднимаются каждые 0.3 секунды, и каждый пузырёк возвращается в пул у поверхности:
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, на префабе пузырька
public BubblePool pool;
void Update()
{
transform.Translate(0f, 2f * Time.deltaTime, 0f);
if (transform.position.y > 5f) pool.Return(gameObject);
}Сначала Get проверяет Count, потому что вызов Dequeue для пустой очереди вызывает исключение InvalidOperationException. Только после этого выполняется Instantiate, и устанавливать поле pool нужно только новому пузырьку: у повторно используемого оно уже задано. Очередь выдаёт первым пузырёк, который дольше всех ждал: первым пришёл — первым вышел. Пузырёк у поверхности вызывает Return вместо Destroy и остаётся в сцене неактивным до следующего вызова Get.
Get размещает пузырёк до вызова SetActive(true), потому что его включение сразу запускает OnEnable, и всё, что выполняется там, должно видеть новую позицию, а не ту, где пузырёк исчез в прошлый раз. Именно здесь повторно используемый объект начинает работу заново: Awake и Start выполняются один раз, когда пузырёк создаётся, а OnEnable запускается при каждом вызове Get.
Задание
СреднеИспользуй пул следов вместо их уничтожения.
- В
Trailхрани запасные объекты вQueue<GameObject>.Return(footprint)деактивирует объект и добавляет его в очередь;Startсоздаётprewarmследов и возвращает их. Get(position)извлекает запасной объект из очереди (или создаёт новый), размещает его и активирует.- В
Footprintзамени Destroy: сбрасывай возраст вOnEnable; по истеченииlifeсекунд вызывайtrail.Return(gameObject).
Нажми «Играть» и пройдись: следы исчезнут через 1.5 секунды. Затем нажми «Проверить».
Попробуйте сами
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;
// Заполните пул заранее созданными отпечатками следов
}
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)
{
// Запасные отпечатки следов ожидают в пуле
}
}
Все уроки раздела Архитектура игр в Unity
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыКомпоненты работают вместеПовторение: модульная турельПовторение: спаренная пушка4Сериализованные данные
Сериализуемые классыСписки в инспектореПеречисления в инспектореПовторение: таблица добычиПовторение: определяем добычу2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействияПовторение: ближайший в пределах досягаемости5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиСохраняем ветерВолны как данныеПовторение: база предметовПовторение: покупка в магазинеПотренируйтесь самостоятельно: Песочница Unity