2025-02-12 08:43:33 +08:00

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