设计一个对象池管理器,用来控制不同的对象池,通过参数向不同的池子获取对象,对应的池子再根据自身情况返回所需对象。
脚本如下:
1.池子的设计 。包含新建/删除/回收等方法。
public class Pool
{
private GameObject ori;
public Pool(GameObject ori)
{
this.ori = ori;
}
public List<GameObject> store = new List<GameObject>();
public List<GameObject> uesd = new List<GameObject>();
public GameObject GetObj()
{
GameObject temp;
if (store.Count > 0)
{
temp = store[0];
store.RemoveAt(0);
}
else
{
temp = GameObject.Instantiate(ori);
var key = temp.AddComponent<PoolKey>();
key.key = ori.name;
}
uesd.Add(temp);
return temp;
}
public void RestoreObj(GameObject temp)
{
if (uesd.Contains(temp))
{
uesd.Remove(temp);
}
store.Add(temp);
}
public void DestoryObj(GameObject obj)
{
if (Application.isPlaying)
{
UnityEngine.GameObject.Destroy(obj);
}
else
{
UnityEngine.Object.DestroyImmediate(obj);
}
}
public void Clear()
{
int length = store.Count;
for (int i = length - 1; i >= 0; i--)
{
DestoryObj(store[i]);
}
length = uesd.Count;
for (int i = length - 1; i >= 0; i--)
{
DestoryObj(uesd[i]);
}
store.Clear();
uesd.Clear();
}
}
2.控制器的设计。
/// <summary>
/// 万能对象池控制器 ,用来控制不同的池子从不同的池子中去对应的对象
/// </summary>
public class ObjController : MonoBehaviour
{
[ShowInInspector]
public static Dictionary<string, Pool> poolManager = new Dictionary<string, Pool>();
//生成一个游戏物体
public static GameObject CreateObj(GameObject ori)
{
GameObject temp;
if (poolManager.ContainsKey(ori.name) == false)
{
poolManager[ori.name] = new Pool(ori);
}
temp = poolManager[ori.name].GetObj();
return temp;
}
//回收一个游戏物体
public static void Restore(GameObject obj)
{
var poolKey = obj.GetComponent<PoolKey>();
if (poolKey && poolManager.ContainsKey(poolKey.key))
{
poolManager[poolKey.key].RestoreObj(obj);
}
else
{
Debug.Log($"<color=red>{obj.name} 这个物体无法被回收,推测1:poolKey==null({poolKey == null}),2:没有这个池子</color>");
}
}
//清空某个游戏物体的对象池,顺便删除所有该池子里的对象
public static void ClearObjPool(GameObject obj)
{
if (poolManager.ContainsKey(obj.name))
{
poolManager[obj.name].Clear();
poolManager.Remove(obj.name);
}
else
{
Debug.Log("<color=red>清除失败</color>");
}
}
public static void ClearAll()
{
foreach (var item in poolManager)
{
item.Value.Clear();
}
poolManager.Clear();
}
}
3.为了方便寻找,每一个对象身上挂了一个key.
public class PoolKey : MonoBehaviour
{
public string key;
[ShowInInspector]
public int id { get => GetInstanceID(); }
}
还有优化空间。暂时先用。