Menu
CoddyTech

Un pool con una cola

Parte de la sección Arquitectura de juegos en Unity del Journey de Unity de Coddy. Lección 47 de 64.

A un grupo de objetos le hace falta un lugar donde guardar los objetos sobrantes, y C# tiene la colección adecuada: Queue<T>: Enqueue agrega un elemento al final, Dequeue toma el que está al principio y Count indica cuántos esperan. Este acuario hace subir una burbuja cada 0.3 segundos, y cada burbuja vuelve al grupo al llegar a 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, en el prefab de la burbuja
public BubblePool pool;

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

Get comprueba primero Count, porque Dequeue en una cola vacía lanza una InvalidOperationException. Solo entonces llama a Instantiate, y solo hace falta asignar el campo pool a una burbuja nueva: una reutilizada ya lo tiene. La cola entrega primero la burbuja que lleva más tiempo esperando; es un sistema primero en entrar, primero en salir. Una burbuja que llega a la superficie llama a Return en lugar de Destroy, y permanece en la escena, inactiva, hasta la siguiente llamada a Get.

Get coloca la burbuja antes de SetActive(true), porque activarla ejecuta OnEnable de inmediato, y cualquier cosa que ocurra allí debería ver la nueva posición, no el lugar donde desapareció la última vez. Es también allí donde un objeto reutilizado vuelve a empezar: Awake y Start se ejecutaron una sola vez, cuando se creó la burbuja, y OnEnable se ejecuta en cada llamada a Get.

challenge icon

Desafío

Intermedio

Reutiliza las huellas en lugar de destruirlas.

  1. En Trail, guarda las que sobren en una Queue<GameObject>. Return(footprint) la desactiva y la agrega a la cola; Start crea prewarm huellas y las devuelve.
  2. Get(position) saca una huella de la cola (o crea una), la coloca y la activa.
  3. En Footprint, reemplaza Destroy: reinicia la edad en OnEnable; después de life segundos, ejecuta trail.Return(gameObject).

Presiona «Jugar» y camina: las huellas se desvanecen después de 1.5 segundos. Luego, presiona «Comprobar».

Pruébalo tú mismo

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;
        // Llena la reserva con huellas preparadas de antemano
    }

    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)
    {
        // Las huellas de repuesto esperan en la reserva
    }
}

Todas las lecciones de Arquitectura de juegos en Unity

Practica por tu cuenta: Playground de Unity