Unity在2021.1版本新增了内置的对象池系统,众所周知对象池对于优化游戏,特别是当需要不断生成物体非常有用。对于一个懒人,看到可以自己不用苦哈哈的去敲一个对象池,那是相当的高兴,于是就到B站上找了一些视频,大概的学习了一下。
练手项目我就随便新建了一个普通的3D core,放好地板、生成点,做好预制体。
创建对象池脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;//引用对象池命名空间
public class Pool : MonoBehaviour
{
public GameObject cube;//预制体
public float time;//间隔时长
private ObjectPool<GameObject> pool;//对象池
我们在Unity手册里可以看到
(链接:https://docs.unity3d.com/cn/current/ScriptReference/Pool.ObjectPool_1.html)
ObjectPool是如何用的
ObjectPool<GameObject>
(池子内没有可调用的预制体时调用的创建预制体的方法,
取得池子内的预制体,
释放预制体到池子,
销毁预制体,
官方的检测最好设置true(开启),
默认池子大小,
最大池子大小)
所以在Awake创建对象池
void Awake()
{
pool = new ObjectPool<GameObject>(objOnCreate, objOnGet, objOnRelease, objOnDestroy, true, 10, 50);
}
之后分别写对象池内的那些方法
GameObject objOnCreate()
{
var obj= Instantiate(cube, transform.position, transform.rotation);
//obj.GetComponent<Cube>().cubepool = pool;
return obj;
}
void objOnGet(GameObject obj)
{
obj.gameObject.SetActive(true);
}
void objOnRelease(GameObject obj)
{
obj.gameObject.SetActive(false);
obj.transform.position = transform.position;
}
void objOnDestroy(GameObject obj)
{
Destroy(obj);
}
之后就是使用对象池方法,用Pool.Get()和Pool.Release()来实现
间隔生成物体:
void Start()
{
StartCoroutine("Spawn");//使用协程
}
IEnumerator Spawn()
{
while (true)
{
yield return new WaitForSeconds(time);
var cubs = pool.Get();
Debug.Log("生成");
}
}
当物体碰撞地面时释放物体(挂载在预制体上)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;
public class Cube : MonoBehaviour
{
public ObjectPool<GameObject> cubepool;//用来获取对象池
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.layer == LayerMask.NameToLayer("Ground"))
{
//Debug.Log("销毁");
cubepool.Release(gameObject);
}
}
}
同时,在对象池的Creat(生成预制体)的方法中添加代码
GameObject objOnCreate()
{
var obj= Instantiate(cube, transform.position, transform.rotation);
obj.GetComponent<Cube>().cubepool = pool;//预制体脚本中的池子和对象池脚本的池子保持一致
return obj;
}
就得到了一个自带对象池的自动生成方块的项目了。