首先,我们要创建一个对象池类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool
{
Dictionary<string, List<GameObject>> pool;
private static ObjectPool _instance = null;
private ObjectPool()
{
pool = new Dictionary<string, List<GameObject>>();
}
public static ObjectPool Instance
{
get
{
if(_instance == null)
{
_instance = new ObjectPool();
}
return _instance;
}
}
//存入
public void PutInPool(GameObject obj)
{
if (pool.ContainsKey(obj.name))
{
pool[obj.name].Add(obj);
}
else
{
List<GameObject> newList = new List<GameObject>();
newList.Add(obj);
pool[obj.name] = newList;
}
obj.SetActive(false);
}
//取出
public GameObject GetFromPool(string key)
{
if (pool.ContainsKey(key))
{
if (pool[key].Count>0)
{
GameObject obj = pool[key][0];
pool[key].Remove(obj);
obj.SetActive(true);
return obj;
}
}
return null;
}
//清空
public void ClearPool()
{
pool.Clear();
}
//索引器
public GameObject this[string key]
{
get
{
return GetFromPool(key);
}
set
{
PutInPool(value);
}
}
}
为了方便起见,再来个资源管理类,用于动态加载资源
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class ResourcesManager
{
private static Dictionary<string, GameObject> resDic = new Dictionary<string, GameObject>();
/// <summary>
/// 用于加载resources文件夹中的资源
/// </summary>
/// <param name="path">预制体在resources文件夹中的路径</param>
/// <returns>加载出来的预制体</returns>
public static GameObject Load(string path)
{
//1、判断容器中是否存在该路径
if (resDic.ContainsKey(path))
{
//2、如果存在,直接从容器中获取
return resDic[path];
}
//3、如果没有,使用load方法读取,并存入容器
GameObject go = Resources.Load(path) as GameObject;
resDic[path] = go;
return go;
}
//非泛型容器, == Dictionary<object,object>
private static Hashtable resTable = new Hashtable();
//泛型函数
public static T Load<T>(string path) where T : Object
{
//1、判断容器中是否存在该路径
if (resTable.ContainsKey(path))
{
//2、如果存在,直接从容器中获取
return resTable[path] as T;
}
//3、如果没有,使用load方法读取,并存入容器
T t = Resources.Load<T>(path);
resTable[path] = t;
return t;
}
}
为对象使用对象池
//先声明一个对象池
ObjectPool pool;
void Start()
{
pool = ObjectPool.Instance;
}
void CreatEffect(string effectName, Vector3 hitPos)
{
GameObject obj = pool.GetFromPool(effectName + "(Clone)");
if (obj == null)
{
//如果对象池中没有,则动态加载预制体
obj = ResourcesManager.Load("Prefabs/" + effectName);
Instantiate(obj, hitPos, UnityEngine.Random.rotation);
}
else if (obj != null)
{
obj.transform.position = hitPos;
obj.transform.rotation = UnityEngine.Random.rotation;
}
}
//销毁时清空对象池
private void OnDestroy()
{
pool.ClearPool();
}