Unity3D – Object Pooling – Bullets – CSharp
Object Pooling è una tecnica per ridurre i calcoli della CPU.
Questo sistema di programmazione consiste nel creare un gruppo di oggetti, storarli inattivi all’interno di una lista, per poi attivarli e posizionarli direttamente nell’area di gioco.
La generazione di tutti gli oggetti comporta un consumo di RAM iniziale elevato, che comunque è molto meno costoso in termini di prestazioni del dover ogni volta istanziare e distruggere i singoli eggetti.
Applicare questa tecnica ha senso se utilizziamo a video nello stesso tempo almeno diverse centinaia di oggetti o stiamo sviluppando su piattaforma mobile dove la potenza di calcolo della CPU non è elevata.
Creiamo una scena con:
(parent) Spaceship
– (child) Bullet
All’oggetto ‘Bullet’ applichiamo:
BulletScript.cs
using UnityEngine; using System.Collections; public class BulletScript : MonoBehaviour { public float speed = 5; // Use this for initialization void Start () { } // Update is called once per frame void Update () { // simple move the object transform.Translate (0, speed * Time.deltaTime, 0); } }// END MonoBehaviour
Questo script semplicemente muove l’oggetto
BulletDestroyScript.cs
using UnityEngine; using System.Collections; public class BulletDestroyScript : MonoBehaviour { // This function is called when the object becomes enabled and active. // It is a part of MonoBehaviour.OnEnable() void OnEnable() { Invoke ("Destroy", 2f); // call the function after 2 second } void Destroy() { gameObject.SetActive (false); // deactivate the object } // This function is called when the behaviour becomes disabled () or inactive. // It is a part of MonoBehaviour.OnDisable() void OnDisable() { CancelInvoke(); } }// END MonoBehaviour
Questo script disattiva l’oggetto dopo 2 secondi per ottimizzare il rendering
All’oggetto ‘Spaceship’ applichiamo:
BulletFireScript.cs
using UnityEngine; using System.Collections; using System.Collections.Generic; // to add Lists public class BulletFireScript : MonoBehaviour { public float fireTime = .1f; // attiva un oggetto bullet ogni xxx secondi public GameObject bullet; // Assign in Inspector public int pooledAmount = 20; // numero di oggetto instanziati, se insufficienti aumentarli public List<GameObject> bullets; // Use this for initialization void Start () { // crea una lista di oggetti inattivi bullets = new List<GameObject> (); for (int i = 0; i < pooledAmount; i++) { GameObject obj = (GameObject)Instantiate(bullet); obj.SetActive (false); // inattivi, verranno attivati dalla funzione Fire() bullets.Add (obj); // aggiungi l'oggetto alla lista Debug.Log(bullets.Count); } InvokeRepeating ("Fire", fireTime, fireTime); // richiama la funzione Fire() }// END Start void Fire() { // posiziona e attiva tutti gli aoggetti della lista bullets for (int i=0; i < bullets.Count; i++)// scorre tutti gli oggetti della scena { if (!bullets[i].activeInHierarchy)// se un oggetto nella scena non è attivo { bullets[i].transform.position = transform.position;// posiziona bullets[i].transform.rotation = transform.rotation;// rotazione bullets[i].SetActive(true);// attiva break; }// END if } }// END Fire }// END MonoBehaviour
Assegniamo in Inspector l’oggetto ‘Bullet’ alla variabile ‘bullet’
Questo script:
1. Crea una lista
2. Start () -> Instanzia 20 oggetti, li disattiva e li inserisce nella lista
3. Fire() -> posiziona gli oggetti e li attiva
Avviate il gioco, osservate Hierarchy e Inspector per BulletFireScript.cs per comprenderne il funzionamento
Si può notare dal codice di tutti gli script che – Destroy (gameObject) – NON è mai stata utilizzata, perchè i 20 oggetti bullet vengono continuamente riciclati attivandoli e disattivandoli di continuo.