137 lines
4.7 KiB
C#
137 lines
4.7 KiB
C#
|
|
using System.Collections;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using UnityEngine;
|
||
|
|
/*******************************************************************************
|
||
|
|
*Create By CG
|
||
|
|
*Function 对象池管理_大池子
|
||
|
|
*******************************************************************************/
|
||
|
|
namespace ZXK.Framework
|
||
|
|
{
|
||
|
|
public class ObjectPoolsManager : ClassSingleton<ObjectPoolsManager>
|
||
|
|
{
|
||
|
|
//所有对象池的父物体
|
||
|
|
private GameObject _poolsParent;
|
||
|
|
//所有对象池的共同父物体在Hierarchy窗口的名字
|
||
|
|
private const string _poolsParentName = "ObjectPools";
|
||
|
|
|
||
|
|
//当前所有对象池的列表
|
||
|
|
private List<ObjectPool> _objectPoolsList = new List<ObjectPool>();
|
||
|
|
|
||
|
|
//用来表示游戏对象所属的对象池
|
||
|
|
private Dictionary<GameObject, ObjectPool> _objectsDictionary = new Dictionary<GameObject, ObjectPool>();
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 从对象池生成游戏对象。
|
||
|
|
/// 如果对象池有,从对象池中取出来用。
|
||
|
|
/// 如果对象池没有,实例化该对象。
|
||
|
|
/// </summary>
|
||
|
|
public GameObject Spawn(GameObject prefab, Vector3 position, Quaternion rotation, Transform parent = null)
|
||
|
|
{
|
||
|
|
if (prefab == null) return null;
|
||
|
|
|
||
|
|
//如果场景中没有对象池的父物体,则生成一个空物体,作为所有对象池的父物体
|
||
|
|
CreatePoolsParentIfNull();
|
||
|
|
|
||
|
|
//先通过预制体来查找它所属的小对象池,如果找到了,则返回这个小对象池。
|
||
|
|
//如果找不到,则创建一个小对象池,用来存放这种预制体。
|
||
|
|
ObjectPool objectPool = FindPoolByPrefabOrCreatePool(prefab);
|
||
|
|
|
||
|
|
GameObject go = objectPool.Spawn(position, rotation, parent);
|
||
|
|
|
||
|
|
_objectsDictionary.Add(go, objectPool);
|
||
|
|
|
||
|
|
return go;
|
||
|
|
}
|
||
|
|
|
||
|
|
public void Despawn(GameObject go, float delayTime = 0)
|
||
|
|
{
|
||
|
|
if (go == null) return;
|
||
|
|
MonoManager.Instance.StartCoroutine(DespawnCoroutine(go, delayTime));
|
||
|
|
}
|
||
|
|
IEnumerator DespawnCoroutine(GameObject go, float delayTime = 0)
|
||
|
|
{
|
||
|
|
//等待指定秒数
|
||
|
|
if (delayTime > 0)
|
||
|
|
yield return new WaitForSeconds(delayTime);
|
||
|
|
|
||
|
|
if (_objectsDictionary.TryGetValue(go, out ObjectPool pool))
|
||
|
|
{
|
||
|
|
_objectsDictionary.Remove(go);
|
||
|
|
|
||
|
|
pool.Despawn(go);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
//获取这个游戏对象所属的对象池
|
||
|
|
pool = FindPoolByUsedGameObject(go);
|
||
|
|
|
||
|
|
if (pool != null)
|
||
|
|
{
|
||
|
|
pool.Despawn(go);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
ObjectPool FindPoolByUsedGameObject(GameObject go)
|
||
|
|
{
|
||
|
|
if (go == null) return null;
|
||
|
|
|
||
|
|
for (int i = 0; i < _objectPoolsList.Count; i++)
|
||
|
|
{
|
||
|
|
ObjectPool pool = _objectPoolsList[i];
|
||
|
|
|
||
|
|
for (int j = 0; j < pool._UsedGameObjectList.Count; j++)
|
||
|
|
{
|
||
|
|
if (pool._UsedGameObjectList[j] == go)
|
||
|
|
return pool;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
//先通过预制体来查找它所属的小对象池,如果找到了,则返回这个小对象池。
|
||
|
|
//如果找不到,则创建一个小对象池,用来存放这种预制体。
|
||
|
|
private ObjectPool FindPoolByPrefabOrCreatePool(GameObject prefab)
|
||
|
|
{
|
||
|
|
//确保大对象池是存在的
|
||
|
|
CreatePoolsParentIfNull();
|
||
|
|
|
||
|
|
//查找并返回该预制体对数的对象池
|
||
|
|
ObjectPool objectPool = null;
|
||
|
|
if (prefab != null)
|
||
|
|
{
|
||
|
|
for (int i = 0; i < _objectPoolsList.Count; i++)
|
||
|
|
{
|
||
|
|
if (_objectPoolsList[i]._Prefab == prefab)
|
||
|
|
objectPool = _objectPoolsList[i];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (objectPool == null)
|
||
|
|
{
|
||
|
|
objectPool = new GameObject($"ObjectPool_{prefab.name}").AddComponent<ObjectPool>();
|
||
|
|
|
||
|
|
objectPool._Prefab = prefab;
|
||
|
|
|
||
|
|
objectPool.transform.SetParent(_poolsParent.transform);
|
||
|
|
|
||
|
|
_objectPoolsList.Add(objectPool);
|
||
|
|
}
|
||
|
|
|
||
|
|
return objectPool;
|
||
|
|
}
|
||
|
|
|
||
|
|
//如果场景中没有对象池的父物体,则生成一个空物体,作为所有对象池的父物体。
|
||
|
|
private void CreatePoolsParentIfNull()
|
||
|
|
{
|
||
|
|
if (_poolsParent == null)
|
||
|
|
{
|
||
|
|
_objectPoolsList.Clear();
|
||
|
|
_objectsDictionary.Clear();
|
||
|
|
|
||
|
|
_poolsParent = new GameObject(_poolsParentName);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|