Come funziona il pooling in Unity

Immagine di copertina

In Unity, esistono funzioni come Instantiate e Destroy per creare e distruggere gli oggetti nel gioco. Tuttavia, queste operazioni possono essere costose, specialmente se vengono eseguite molto spesso durante il gameplay. Immagina di star giocando a uno sparatutto, dove continuamente tutti i giocatori sparano contro altri nemici infiniti proiettili… sarebbe un continuo “Instantiate’n’Destroy”!

In situazioni del genere, dove bisogna creare e distruggere frequentemente oggetti, soprattutto quando si tratta dello sviluppo di videogiochi e la gestione delle risorse è fondamentale, si usa l’algoritmo di pooling.

Il pooling (da pool, “piscina di oggetti”) viene utilizzato quando vi è la necessità di gestire diversi oggetti che sono sempre gli stessi. In fase di inizializzazione dell’applicazione, l’algoritmo genera un certo numero di oggetti, che vengono attivati e disattivati quando necessario, utilizzando sempre le stesse risorse.

Implementazione del pooling

Creiamo la classe ObjectPoolingManager per gestire il pool di oggetti. Dapprima, viene istanziato un numero predefinito di oggetti e riutilizzati quando necessario. Il metodo GetPooledObject restituisce un oggetto disattivato nel pool quando richiesto.

public class ObjectPoolingManager : MonoBehaviour
{
    // Dichiarazione di variabili pubbliche
    public static ObjectPoolingManager instance; // Riferimento statico a se stesso per l'accesso globale
    public GameObject pooledObject; // Il tipo di oggetto da poolare
    public int pooledAmount = 10; // Il numero iniziale di oggetti da poolare

    // Lista di oggetti poolati
    private List<GameObject> pooledObjects;

    // Metodo chiamato quando l'oggetto viene inizializzato
    private void Awake()
    {
        // Verifica se c'è già un'istanza di ObjectPoolingManager
        if (instance == null)
            instance = this; // Se non c'è, imposta questa istanza come l'istanza singleton
        else
            Destroy(gameObject); // Se c'è già un'istanza, distruggi questo oggetto per evitare duplicati
    }

    // Metodo chiamato all'avvio
    void Start()
    {
        pooledObjects = new List<GameObject>(); // Inizializza la lista di oggetti poolati
        // Loop per creare e inizializzare gli oggetti poolati
        for (int i = 0; i < pooledAmount; i++)
        {
            GameObject obj = Instantiate(pooledObject); // Crea un nuovo oggetto dal prefab specificato
            obj.SetActive(false); // Disattiva l'oggetto appena creato
            pooledObjects.Add(obj); // Aggiunge l'oggetto alla lista di oggetti poolati
        }
    }

    // Metodo per ottenere un oggetto poolato disponibile
    public GameObject GetPooledObject()
    {
        // Loop attraverso gli oggetti poolati
        for (int i = 0; i < pooledObjects.Count; i++)
        {
            // Verifica se l'oggetto non è attivo nell'attuale gerarchia
            if (!pooledObjects[i].activeInHierarchy)
            {
                return pooledObjects[i]; // Se trovato, restituisci l'oggetto
            }
        }
        return null; // Se non ci sono oggetti disponibili, restituisci null
    }
}

Utilizzo del pooling

Vediamo ora come sfruttare il pooling manager per “spawnare1 oggetti ogni volta che vogliamo:

public class ObjectSpawner : MonoBehaviour
{
    public float spawnRate = 1f; // Frequenza di spawn degli oggetti
    public float despawnTime = 5f; // Tempo prima che gli oggetti spawnati vengano disattivati

    void Start()
    {
        StartCoroutine(SpawnObjects()); // Avvia la coroutine per lo spawn degli oggetti
    }

    // Coroutine per lo spawn degli oggetti
    IEnumerator SpawnObjects()
    {
        while (true) // Loop infinito per continuare lo spawn degli oggetti
        {
            yield return new WaitForSeconds(spawnRate); // Attendere per la durata della frequenza di spawn
            GameObject obj = ObjectPoolingManager.instance.GetPooledObject(); // Ottiene il primo oggetto disponibile (non ancora attivato) dal pooling

            if (obj != null) // Se è stato ottenuto un oggetto valido
            {
                obj.transform.position = transform.position; // Imposta la posizione dell'oggetto sulla posizione dello spawn
                obj.SetActive(true); // Attiva l'oggetto
                StartCoroutine(DeactivateObject(obj)); // Avvia la coroutine per disattivare l'oggetto dopo un certo periodo di tempo
            }
        }
    }

    // Coroutine per disattivare un oggetto dopo un certo periodo di tempo
    IEnumerator DeactivateObject(GameObject obj)
    {
        yield return new WaitForSeconds(despawnTime); // Attendere per il tempo di disattivazione
        obj.SetActive(false); // Disattiva l'oggetto
    }
}

In sintesi, l’algoritmo di pooling permette di:

  1. ridurre l’utilizzo della memoria: evita il “Instantiate’n’Destroy” continuo di oggetti in gioco, risparmiando risorse di memoria;
  2. migliorare le prestazioni e la stabilitĂ : elimina il ritardo causato dalla creazione dinamica degli oggetti durante il gioco.

Pooling Esempio di Pooling in Unity


đź”— Leggi anche:


  1. Quando si parla di “spawnare” un oggetto in un gioco, si intende il processo di istanziazione di quell’oggetto all’interno del mondo virtuale del gioco. ↩︎

Conosci meglio chi ha scritto questo articolo

Bamboo Innovation Studio

Bamboo Innovation Studio S.r.l. è una startup innovativa con sedi a Napoli e Roma, fondata da Giuliana Muto e Davide Deodati, due giovani imprenditori under 30 riconosciuti per il loro talento e inseriti nella lista Forbes.

Specializzati nello sviluppo di soluzioni immersive basate su Extended Reality (XR) e videogiochi, collaboriamo con aziende, musei e professionisti per creare esperienze digitali su misura, rivoluzionando l’interazione tra uomo e tecnologia. Il nostro obiettivo è guidare la trasformazione digitale nell’Industria 5.0, unendo creatività, innovazione e tecnologia per dare vita a nuovi modi di comunicare, apprendere e sperimentare.

Foto di Bamboo Innovation Studio

Partners

Community, aziende e persone che supportano attivamente il blog

Vuoi diventare partner?

Collaboriamo con community, aziende e strumenti del mondo tech che vogliono raggiungere la nostra community di dev ed engineer italiani. Scrivici per proporre una collaborazione.

✉️ Scrivici

Vuoi diventare tech content creator? 🖊️

Se ti va di raccontare la tua esperienza nel mondo tech, questo è il posto giusto.

Cerchiamo voci autentiche, esempi pratici e punti di vista utili per chi legge.

Scrivici a collaborazioni[at]theredcode.it con una proposta: idea, taglio del contenuto e una breve presentazione. Non vediamo l'ora di leggere la tua esperienza!

Invia la tua idea