[Unity] Construcción de grupos de objetos tradicionales y el uso del grupo de objetos oficial de Unity ObjectPool

Fuente de materiales de aprendizaje: [Reproducción en vivo del maestro SiKi] Cómo usar la tecnología de grupo de objetos de Unity ObjectPool_哔哩哔哩_bilibili

Objetivo: Generar una gran cantidad de Cubos en la pantalla

 1. Estructura de grupo de objetos tradicional

1. Objeto: necesita un prefabricado para copiar

2. Conjunto de objetos (ObjectPool)

(1) crear

        ① Use una cola para almacenar objetos: public Queue<GameObject> cube = new Queue<GameObject>;

        ②Adoptar el modo singleton: instancia de objeto estático público;

        ③Determinar el número de objetos almacenados en el grupo de objetos: for loop→Instantiate→poner en la cola

(2) Definir los métodos requeridos por el grupo de objetos

        ① Obtener el objeto

        Determine si hay un objeto en el conjunto de objetos:

                Allí → obtener objeto → sacar ( Dequeue() ), activar ( SetActive(true) )

                Ninguno → Crear objeto → Instanciar

        ② Reciclaje: invalidación ( SetActive(false) ), puesta en cola ( Enqueue() )

3. Usa la rutina en el objeto para lograr el efecto de desaparición (usado en Onable)

2. Uso del grupo de objetos oficial de Unity ObjectPool

Código de ejemplo oficial:

using System.Text;
using UnityEngine;
using UnityEngine.Pool;

// This component returns the particle system to the pool when the OnParticleSystemStopped event is received.
[RequireComponent(typeof(ParticleSystem))]
public class ReturnToPool : MonoBehaviour
{
    public ParticleSystem system;
    public IObjectPool<ParticleSystem> pool;

    void Start()
    {
        system = GetComponent<ParticleSystem>();
        var main = system.main;
        main.stopAction = ParticleSystemStopAction.Callback;
    }

    void OnParticleSystemStopped()
    {
        // Return to the pool
        pool.Release(system);
    }
}

// This example spans a random number of ParticleSystems using a pool so that old systems can be reused.
public class PoolExample : MonoBehaviour
{
    public enum PoolType
    {
        Stack,
        LinkedList
    }

    public PoolType poolType;

    // Collection checks will throw errors if we try to release an item that is already in the pool.
    public bool collectionChecks = true;
    public int maxPoolSize = 10;

    IObjectPool<ParticleSystem> m_Pool;

    public IObjectPool<ParticleSystem> Pool
    {
        get
        {
            if (m_Pool == null)
            {
                if (poolType == PoolType.Stack)
                    m_Pool = new ObjectPool<ParticleSystem>(CreatePooledItem, OnTakeFromPool, OnReturnedToPool, OnDestroyPoolObject, collectionChecks, 10, maxPoolSize);
                else
                    m_Pool = new LinkedPool<ParticleSystem>(CreatePooledItem, OnTakeFromPool, OnReturnedToPool, OnDestroyPoolObject, collectionChecks, maxPoolSize);
            }
            return m_Pool;
        }
    }

    ParticleSystem CreatePooledItem()
    {
        var go = new GameObject("Pooled Particle System");
        var ps = go.AddComponent<ParticleSystem>();
        ps.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);

        var main = ps.main;
        main.duration = 1;
        main.startLifetime = 1;
        main.loop = false;

        // This is used to return ParticleSystems to the pool when they have stopped.
        var returnToPool = go.AddComponent<ReturnToPool>();
        returnToPool.pool = Pool;

        return ps;
    }

    // Called when an item is returned to the pool using Release
    void OnReturnedToPool(ParticleSystem system)
    {
        system.gameObject.SetActive(false);
    }

    // Called when an item is taken from the pool using Get
    void OnTakeFromPool(ParticleSystem system)
    {
        system.gameObject.SetActive(true);
    }

    // If the pool capacity is reached then any items returned will be destroyed.
    // We can control what the destroy behavior does, here we destroy the GameObject.
    void OnDestroyPoolObject(ParticleSystem system)
    {
        Destroy(system.gameObject);
    }

    void OnGUI()
    {
        GUILayout.Label("Pool size: " + Pool.CountInactive);
        if (GUILayout.Button("Create Particles"))
        {
            var amount = Random.Range(1, 10);
            for (int i = 0; i < amount; ++i)
            {
                var ps = Pool.Get();
                ps.transform.position = Random.insideUnitSphere * 10;
                ps.Play();
            }
        }
    }
}

1. Cree un grupo de objetos (se requiere el uso de UnityEngine.Pool)

pool privado de IObjectPool<Cube>;

// CreatePooledItem - 创建对象
// OnTakeFromPool - 取出对象
// OnReturnedToPool - 回收对象
// OnDestroyPoolObject -销毁对象
// collectionChecks - true / false
// 10 - 默认对象池容量
//maxPoolSize - 对象池最大容量
Pool = new ObjectPool<Cube>(CreatePooledItem, OnTakeFromPool, 
OnReturnedToPool, OnDestroyPoolObject, collectionChecks, 10, maxPoolSize);

2. Método de objeto

(1) CreatePooledItem:Instanciar、SetActive(false)→return

        cube.pool = pool; → el objeto creado contiene una referencia al grupo de objetos

(2) OnTakeFromPool: Activar al sacar - SetActive(true)

(3) OnReturnedToPool: Falló cuando se puso - SetActive (falso)

(4) OnDestroyPoolObject: destruye objetos redundantes después de alcanzar la capacidad máxima

3. Uso

(1) Sacar: pool.Get();

(2) Retorno: pool.Release(esto);

Supongo que te gusta

Origin blog.csdn.net/simplenthpower/article/details/129300985
Recomendado
Clasificación