引言
何为对象池:对于游戏中经常使用而且需要及时销毁的对象,比如子弹,特效,捕鱼游戏中的鱼,甚至音效,这些对象如果使用平常的instantiate方法,是在不停的申请内存,而这些对象基本有没有区别,这样无疑会消耗我们大量性能。所以对象池为此而生。对象池就是在我们不需要的时候隐藏起来而不是直接销毁.。
对象池的大概结构:因为我们的对象池应该是可以存储大量不同种类的池子(object),所以用一个key为池子的名字,value为对应的池子的字典(Dictionary)来存储更为合适。也就是说主代码应该是一个对象池的控制器类,一个每个池子的itemPool类。
类中的主要方法:控制器里主方法应该有出池和入池两个方法,具体到另一个也应该有出池和入池两个方法
准备
Unity开发工具,Visual Studio。
正文
- 创建一个新的Project(TestPool)和一个新的Scene(Pool),新建两个类ObjectPool和SubPool,目录结构如下
2.编写代码(主代码如下)
public class ObjectPool : MonoBehaviour
{
public static ObjectPool instance;
Dictionary<string, SubPool> m_pools = new Dictionary<string, SubPool>();
public string ResourcesDic;
private void Start()
{
instance = this;
}
public GameObject Spawn(string name)
{
if (!m_pools.ContainsKey(name))
{
Register(name);
}
return m_pools[name].Spawn();
}
public void UnSpawn(GameObject go)
{
foreach (var item in m_pools.Values)
{
if (item.Contains(go))
{
item.Unspawn(go);
break;
}
}
}
private void Register(string name)
{
string path = null;
if (string.IsNullOrEmpty(ResourcesDic.Trim()))
{
path = name;
}
else
{
path = ResourcesDic + "/" + name;
}
GameObject go = Resources.Load<GameObject>(path);
SubPool subPool = new SubPool(go);
m_pools.Add(name, subPool);
}
}
public class SubPool
{
GameObject prefab;
List<GameObject> poolList;
public SubPool(GameObject go)
{
poolList = new List<GameObject>();
prefab = go;
}
public GameObject Spawn()
{
GameObject go = null;
for (int i = 0; i < poolList.Count; i++)
{
if (!poolList[i].activeSelf)
{
go = poolList[i];
break;
}
}
if (go==null)
{
go = GameObject.Instantiate(prefab);
go.SendMessage("Spwan", SendMessageOptions.DontRequireReceiver);
poolList.Add(go);
}
return go;
}
public void Unspawn(GameObject go)
{
if (poolList.Contains(go))
{
go.SetActive(false);
go.SendMessage("UnSpawn", SendMessageOptions.DontRequireReceiver);
}
}
public bool Contains(GameObject go)
{
return poolList.Contains(go);
}
}
3.使用方法
将脚本ObjectPool挂在场景中,出池调用ObjectPool.instance.Spawn(name),入池调用ObjectPool.instance.UnSpawn(gameobject)即可
总结
可能各个版本的对象池有些地方细节不一样,但思路都是一样的,都是为了解决大量实例化对象引发的性能问题而产生,在以后的项目中如果有遇到这种情况的,可以考虑加入对象池使我们的游戏优化的更好。