对象池简介:
对象池优化的主要思想是重复利用已经创建的对象,避免频繁的创建和销毁。具体来说,对象池会在游戏启动时预先创建一定数量的对象,并将其存储在一个池中。当需要使用该类型的对象时,从对象池中取出一个空闲对象,而不是每次都创建一个新对象。当该对象不再使用时,将其重新放回到对象池中,以便下次继续使用。
为什么要使用对象池 O.o?
在咱们游戏开发当中,会出现很多的内存利用产生的问题,对象池就可以很好的提高性能和内存的利用率,所以对象池也是一种常见的优化手段。
对象池优点:
Unity对象池优化主要有以下几个方面的优化:
-
减少内存分配:对象池可以减少不必要的资源分配,从而降低了内存使用率。
-
减少CPU消耗:频繁的对象创建和销毁对象会导致额外的CPU消耗 使用对象池技术可以避免频繁的对象创建和销毁操作 从而减少CPU的消耗
-
提高代码易读性:使用对象池技术可以使我们写的代码更加清晰明了,便于后期维护和扩展。
代码实现(代码内有详细简介):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjTools : MonoBehaviour
{
// 单例
public static ObjTools poolInstance;
// 池子要存储的物体
public GameObject Object;
// 内存区(队列)
public Queue<GameObject> objectPool = new Queue<GameObject>();
// 池子的初始容量
public int defaultCount = 16;
// 池子的最大容量
public int maxCount = 25;
private void Awake()
{
poolInstance = this;
//Init();
}
// 对池子进行初始化(创建初始容量个数的物体)
public void Init()
{
GameObject obj;
for (int i = 0; i < defaultCount; i++)
{
obj = Instantiate(Object, this.transform);
// 将生成的对象入队
objectPool.Enqueue(obj);
obj.SetActive(false);
}
}
// 从池子中取出物体
public GameObject Get()
{
GameObject tmp;
// 如果池子内有物体,从池子取出一个物体
if (objectPool.Count > 0)
{
// 将对象出队
tmp = objectPool.Dequeue();
tmp.SetActive(true);
}
// 如果池子中没有物体,直接新建一个物体
else
{
tmp = Instantiate(Object, this.transform);
}
return tmp;
}
// 将物体回收进池子
public void Remove(GameObject obj)
{
// 池子中的物体数目不超过最大容量
if (objectPool.Count < maxCount)
{
// 该对象没有在队列中
if (!objectPool.Contains(obj))
{
// 将对象入队
objectPool.Enqueue(obj);
obj.SetActive(false);
}
}
// 超过最大容量就销毁
else
{
Destroy(obj);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Game : MonoBehaviour
{
ObjTools obj;
public GameObject game, dr;
Queue<GameObject> queue = new Queue<GameObject>();
private void Awake()
{
obj = this.GetComponent<ObjTools>();
}
void Start()
{
obj.Init();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0))
{
game = obj.Get();
game.transform.position = transform.position + transform.forward * 2;
game.transform.rotation = new Quaternion(0, 0, 0, 0);
queue.Enqueue(game);
game.transform.position = Vector3.MoveTowards(transform.position, dr.transform.position, 0.5f);
Invoke("Del", 2);
}
}
public void Del()
{
if (game != null)
{
obj.Remove(queue.Dequeue());
}
}
}
总结:
我上方使用的队列实现的对象池,除此之外,游戏开发中还可以使用其他数据结构来实现对象池,例如:
-
栈:栈是一种后进先出(LIFO)的数据结构,适用于对象池的实现。通过将对象推入栈顶和从栈顶弹出对象,可以实现对象的回收和重用。
-
集合:列表是一种动态数组,可以在任意位置插入、删除和访问元素。可以使用列表来保存对象,并通过标记或其他方式来跟踪哪些对象是可用的。当需要获取一个对象时,可以遍历列表找到一个可用的对象进行重用。
-
字典:字典是一种键值对存储的数据结构,可以使用字典来管理对象池中的对象。可以将对象的唯一ID作为键,将对象本身作为值,通过键值对来获取和回收对象。
-
对象池管理器:可以创建一个自定义的对象池管理器类,其中可以使用各种数据结构来实现对象池。这个管理器可以负责对象的创建、获取、回收和管理,提供接口供其他脚本调用。
需要根据具体需求来进行选择合适的数据结构来实现对象池,以满足项目的需求和性能要求。不同的实现方式可能在性能和灵活性上有所差异。
后期补充(重中之重(非技术)):
其他的工具研究的不多了 就先提供两个比较常用的调试工具叭
后期还会有其他更改与补充 十分欢迎大家来分享自己de见解
希望能和大家相互学习 一起提升自己的芝士!!!