Un pool avec une file
Fait partie de la section Architecture de jeu dans Unity du Journey Unity de Coddy. Leçon 47 sur 64.
Un pool a besoin d’un endroit où garder ses objets de réserve, et C# dispose de la collection qu’il lui faut, Queue<T> : Enqueue ajoute un élément à la fin, Dequeue prend celui du début, et Count indique combien attendent. Cet aquarium fait monter une bulle toutes les 0.3 secondes, et chaque bulle retourne dans le pool à la surface :
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, sur le prefab de la bulle
public BubblePool pool;
void Update()
{
transform.Translate(0f, 2f * Time.deltaTime, 0f);
if (transform.position.y > 5f) pool.Return(gameObject);
}Get vérifie d’abord Count, car Dequeue sur une file vide déclenche une InvalidOperationException. Ce n’est qu’ensuite qu’il fait appel à Instantiate, et seule une nouvelle bulle a besoin que son champ pool soit défini : une bulle réutilisée le possède déjà. La file fournit d’abord la bulle qui a attendu le plus longtemps : premier entré, premier sorti. Une bulle à la surface appelle Return au lieu de Destroy et reste dans la scène, inactive, jusqu’au prochain appel à Get.
Get place la bulle avant SetActive(true), car son activation exécute immédiatement OnEnable, et tout ce qui s’y trouve doit voir la nouvelle position, et non l’endroit où elle avait disparu la dernière fois. C’est aussi ainsi qu’un objet réutilisé repart à zéro : Awake et Start ne se sont exécutées qu’une fois, lors de la création de la bulle, tandis que OnEnable s’exécute à chaque appel à Get.
Défi
MoyenMettez les empreintes en pool au lieu de les détruire.
- Dans
Trail, gardez les empreintes de réserve dans uneQueue<GameObject>.Return(footprint)la désactive et l’ajoute à la file d’attente ;Startcréeprewarmempreintes et les renvoie. Get(position)retire une empreinte de réserve de la file d’attente (ou en crée une), la place et l’active.- Dans
Footprint, remplacez l’appel àDestroy: réinitialisez l’âge dansOnEnable; aprèslifesecondes, appeleztrail.Return(gameObject).
Appuyez sur « Jouer » et déplacez-vous : les empreintes s’estompent après 1.5 seconde. Puis appuyez sur « Vérifier ».
Essayez vous-même
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;
// Remplir le pool avec des empreintes précréées
}
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)
{
// Les empreintes de rechange attendent dans le pool
}
}
Toutes les leçons de Architecture de jeu dans Unity
1Des composants, pas des hiérarchies
De petits composantsUn script de base pour les ennemisComposants abstraitsDes composants qui fonctionnent ensembleRécapitulatif : tourelle modulaireRécapitulatif : canon double4Données sérialisées
Classes sérialisablesListes dans l’InspecteurÉnumérations dans l’InspecteurRécapitulatif : table de butinRécapitulatif : tirer le butin2Les interfaces dans Unity
IDamageableInterfaces et TryGetComponentGetComponentsRécapitulatif : touche d’interactionLe plus proche à portée5ScriptableObjects
Ressources de donnéesStatistiques des armesParamètres partagésSauver le ventLes vagues comme donnéesRécapitulatif : base de données des objetsRécapitulatif : acheter dans la boutique3Événements
Les événements C# dans UnityS’abonner dans OnEnableChamps UnityEventLes événements pilotent l’interfaceRécapitulatif : fenêtre de succèsRécapitulatif : minuteur de la fenêtre6Sauvegarder avec JSON
JsonUtilitySauvegarder la partieCharger et valeurs par défautRécapitulatif : emplacements de sauvegardeChoisir et supprimer un emplacement9Réutilisation des objets
Pourquoi mettre les objets en poolUn pool avec une fileObjectPool de UnityRécapitulatif : pool de projectilesEntraînez-vous par vous-même : Playground Unity