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);
}
}