需求
- 需要一个不可销毁的对象池容器节点,作为对象池里的GameObject的父节点。
- 对象池对象需要挂载自定义的MonoBehaviour,目的是增加对象池的生命周期,从对象池取出与被对象池回收的生命周期。
- 从对象池取出一个对象,如果没有,直接创建它。
- 将一个对象放入对象池。
代码
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class GameObjectManager :MonoBehaviour
{
static Vector3 s_OutOfRange = new Vector3(9000, 9000, 9000);
private static Transform s_poolParent;
public static Transform PoolParent
{
get
{
if (s_poolParent == null)
{
GameObject instancePool = new GameObject("ObjectPool");
s_poolParent = instancePool.transform;
if(Application.isPlaying)
DontDestroyOnLoad(s_poolParent);
}
return s_poolParent;
}
}
#region 新版本对象池
static Dictionary<string, List<PoolObject>> s_objectPool_new = new Dictionary<string, List<PoolObject>>();
static PoolObject CreatePoolObject(string gameObjectName, GameObject parent = null)
{
GameObject go = ResourceManager.Load<GameObject>(gameObjectName);
if (go == null)
{
throw new Exception("CreatPoolObject error dont find : ->" + gameObjectName + "<-");
}
GameObject instanceTmp = Instantiate(go);
instanceTmp.name = go.name;
PoolObject po = instanceTmp.GetComponent<PoolObject>();
if (po == null)
{
throw new Exception("CreatPoolObject error : ->" + gameObjectName + "<- not is PoolObject !");
}
po.OnCreate();
if (parent != null)
{
instanceTmp.transform.SetParent(parent.transform);
}
instanceTmp.SetActive(true);
return po;
}
public static void PutPoolObject(string gameObjectName)
{
DestroyPoolObject(CreatePoolObject(gameObjectName));
}
public static void PutPoolGameOject(string name)
{
DestroyGameObjectByPool(CreateGameObjectByPool(name));
}
public static bool IsExist_New(string objectName)
{
if (objectName == null)
{
Debug.LogError("IsExist_New error : objectName is null!");
return false;
}
if (s_objectPool_new.ContainsKey(objectName) && s_objectPool_new[objectName].Count > 0)
{
return true;
}
return false;
}
public static PoolObject GetPoolObject(string name, GameObject parent = null)
{
PoolObject po;
if (IsExist_New(name))
{
po = s_objectPool_new[name][0];
s_objectPool_new[name].RemoveAt(0);
if (po && po.SetActive)
po.gameObject.SetActive(true);
if (parent == null)
{
po.transform.SetParent(null);
}
else
{
po.transform.SetParent(parent.transform);
}
}
else
{
po = CreatePoolObject(name, parent);
}
po.OnFetch();
return po;
}
public static void DestroyPoolObject(PoolObject obj)
{
string key = obj.name.Replace("(Clone)", "");
if (s_objectPool_new.ContainsKey(key) == false)
{
s_objectPool_new.Add(key, new List<PoolObject>());
}
if (s_objectPool_new[key].Contains(obj))
{
throw new Exception("DestroyPoolObject:-> Repeat Destroy GameObject !" + obj);
}
s_objectPool_new[key].Add(obj);
if (obj.SetActive)
obj.gameObject.SetActive(false);
else
obj.transform.position = s_OutOfRange;
obj.OnRecycle();
obj.name = key;
obj.transform.SetParent(PoolParent);
}
public static void DestroyPoolObject(PoolObject go, float time)
{
Timer.DelayCallBack(time, (object[] obj) =>
{
DestroyPoolObject(go);
});
}
public static void CleanPool_New()
{
foreach (string name in s_objectPool_new.Keys)
{
if (s_objectPool_new.ContainsKey(name))
{
List<PoolObject> objList = s_objectPool_new[name];
for (int i = 0; i < objList.Count; i++)
{
try
{
objList[i].OnObjectDestroy();
}
catch (Exception e)
{
Debug.Log(e.ToString());
}
Destroy(objList[i].gameObject);
}
objList.Clear();
}
}
s_objectPool_new.Clear();
}
public static void CleanPoolByName_New(string name)
{
if (s_objectPool_new.ContainsKey(name))
{
List<PoolObject> objList = s_objectPool_new[name];
for (int i = 0; i < objList.Count; i++)
{
try
{
objList[i].OnObjectDestroy();
}
catch(Exception e)
{
Debug.Log(e.ToString());
}
Destroy(objList[i].gameObject);
}
objList.Clear();
s_objectPool_new.Remove(name);
}
}
#endregion
#region 新版本对象池 异步方法
public static void CreatePoolObjectAsync(string name, CallBack<PoolObject> callback, GameObject parent = null)
{
ResourceManager.LoadAsync(name, (status,res) =>
{
try
{
callback(CreatePoolObject(name, parent));
}
catch(Exception e)
{
Debug.LogError("CreatePoolObjectAsync Exception: " + e.ToString());
}
});
}
#endregion
}