1,Unity知识点之对象池

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class Pool 
{
    [SerializeField] GameObject prefab;
    public GameObject Prefab => prefab;
    public int Size => size;
    public int RuntimeSize => queue.Count;

    [SerializeField] int size = 1;

    Queue<GameObject> queue;

    Transform parent;

    /// <summary>
    /// 初始化
    /// </summary>
    public void Initialize(Transform parent)
    {
        queue = new Queue<GameObject>();

        this.parent = parent;

        for (int i = 0; i < size; i++)
        {
            //入列,队列的最末尾添加一个元素
            queue.Enqueue(Create());
        }
    }

    /// <summary>
    /// 生成对象
    /// </summary>
    /// <returns></returns>
    private GameObject Create()
    {
        var create = GameObject.Instantiate(prefab,parent);

        create.SetActive(false);

        return create;
    }

    /// <summary>
    /// 可用对象
    /// </summary>
    /// <returns></returns>
    private GameObject AvailableObject()
    {
        GameObject availableObject = null;

        //Peek(),返回队列中的第一个元素
        if (queue.Count > 0 && !queue.Peek().activeSelf)
        {
            //返回队列中的第一个元素,并从队列中移除
            availableObject = queue.Dequeue();
        }
        else
        {
            availableObject = Create();
        }

        //再返回一个可用对象前,将其入列;
        queue.Enqueue(availableObject);

        return availableObject;
    }

    /// <summary>
    /// 预备好的对象
    /// </summary>
    /// <returns></returns>
    public GameObject PreparedObject()
    {
        var preparedObject = AvailableObject();

        preparedObject.SetActive(true);

        return preparedObject;
    }

    /// <summary>
    ///预备好的对象
    /// </summary>
    /// <param name="position"></param>
    /// <returns></returns>
    public GameObject PreparedObject(Vector3 position)
    {
        var preparedObject = AvailableObject();

        preparedObject.SetActive(true);

        preparedObject.transform.position = position;

        return preparedObject;
    }

    /// <summary>
    /// 预备好的对象
    /// </summary>
    /// <param name="position"></param>
    /// <param name="rotation"></param>
    /// <returns></returns>
    public GameObject PreparedObject(Vector3 position,Quaternion rotation)
    {
        var preparedObject = AvailableObject();

        preparedObject.SetActive(true);

        preparedObject.transform.position = position;
        preparedObject.transform.rotation = rotation;

        return preparedObject;
    }


    /// <summary>
    /// 预备好的对象
    /// </summary>
    /// <param name="position"></param>
    /// <param name="rotation"></param>
    /// <param name="localScale"></param>
    /// <returns></returns>
    public GameObject PreparedObject(Vector3 position, Quaternion rotation,Vector3 localScale)
    {
        var preparedObject = AvailableObject();

        preparedObject.SetActive(true);

        preparedObject.transform.position = position;
        preparedObject.transform.rotation = rotation;
        preparedObject.transform.localScale = localScale;

        return preparedObject;
    }

}
 


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PoolManager : MonoBehaviour
{
    [SerializeField] Pool[] playerProjectilePools;

    static Dictionary<GameObject, Pool> dictionary;

    private void Start()
    {
        dictionary = new Dictionary<GameObject, Pool>();

        Initialize(playerProjectilePools);
    }

    private void OnDisable()
    {
        CheckPoolSize(playerProjectilePools);
    }
    /// <summary>
    /// 检测对象池的大小
    /// </summary>
    /// <param name="pools"></param>
    void CheckPoolSize(Pool[] pools)
    {
        foreach (var pool in pools)
        {
            if (pool.RuntimeSize > pool.Size)
            {
                Debug.LogWarning(string.Format( "Pool: {0} has a runtime size {1} bigger than its initialize size {2}!",
                    pool.Prefab.name,
                    pool.RuntimeSize,
                    pool.Size));
            }
        }
    }
    void Initialize(Pool[] pools)
    {
        foreach (var pool in pools)
        {
            #if UNITY_EDITOR
            if (dictionary.ContainsKey(pool.Prefab))
            {
                Debug.LogError("在多个对象池中,发现了相同的预制体:" + pool.Prefab.name);
                continue;                //跳过本次循环
            }
            #endif

            dictionary.Add(pool.Prefab, pool);

            Transform poolParent = new GameObject("Pool:" + pool.Prefab.name).transform;
            poolParent.parent = transform;

            pool.Initialize(poolParent);
        }
    }

    /// <summary>
    /// <para>根据出入的<paramref name="prefab"/></paramref>参数,返回对象池中预备好的游戏对象。</para>
    /// </summary>
    /// <param name="prefab">指定游戏对象的预制体</param>
    /// <returns></returns>
    public static GameObject Release(GameObject prefab)
    {
        #if UNITY_EDITOR
        if (!dictionary.ContainsKey(prefab))
        {
            Debug.LogError("PoolManager 找不到prefab:" + prefab.name);
            return null;
        }
        #endif

        return dictionary[prefab].PreparedObject();
    }

    /// <summary>
    /// <para>根据出入的<paramref name="prefab"/></paramref>参数,返回对象池中预备好的游戏对象。</para>
    /// </summary>
    /// <param name="prefab">指定游戏对象的预制体</param>
    /// <param name="position">指定的释放位置</param>
    /// <returns></returns>
    public static GameObject Release(GameObject prefab,Vector3 position)
    {
        #if UNITY_EDITOR
        if (!dictionary.ContainsKey(prefab))
        {
            Debug.LogError("PoolManager 找不到prefab:" + prefab.name);
            return null;
        }
        #endif

        return dictionary[prefab].PreparedObject(position);
    }

    /// <summary>
    /// 根据输入的<paramref name="prefab"/></paramref>参数,返回对象池中预备好的游戏对象。
    /// </summary>
    /// <param name="prefab">指定游戏对象的预制体</param>
    /// <param name="position">指定的释放位置</param>
    /// <param name="rotation">指定的旋转值</param>
    /// <returns></returns>
    public static GameObject Release(GameObject prefab, Vector3 position, Quaternion rotation)
    {
        #if UNITY_EDITOR
        if (!dictionary.ContainsKey(prefab))
        {
            Debug.LogError("PoolManager 找不到prefab:" + prefab.name);
            return null;
        }
        #endif

        return dictionary[prefab].PreparedObject(position, rotation);
    }

    /// <summary>
    /// 根据出入的<paramref name="prefab"/></paramref>参数,返回对象池中预备好的游戏对象。
    /// </summary>
    /// <param name="prefab">指定游戏对象的预制体</param>
    /// <param name="position">指定的释放位置</param>
    /// <param name="rotation">指定的旋转值</param>
    /// <param name="localScale">指定的缩放值</param>
    /// <returns></returns>
    public static GameObject Release(GameObject prefab, Vector3 position, Quaternion rotation,Vector3 localScale)
    {
        #if UNITY_EDITOR
        if (!dictionary.ContainsKey(prefab))
        {
            Debug.LogError("PoolManager 找不到prefab:" + prefab.name);
            return null;
        }
        #endif

        return dictionary[prefab].PreparedObject(position, rotation, localScale);
    }
}
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值