因为自己一直都有在做射击游戏,难免就会发射子弹,生成敌人等等的功能,然后unity自带的克隆(Instantiale)虽然可以实现这个功能但是,在子弹的管理和消失,敌人的生成和管理上都有一定的困难,比较不方便,于是我去大佬哪里学习对象池功能,
对象池我的理解就是,我们在一个空间里放置了我们需要的物品,然后要使用时就拿出来,然后不用的放回去就可以了,如果我们需要的比较多,也可以直接生成新的物体,但是到最后只会有我们最开始放置的那么多,
下面我们就来一起写一写这个对象池,
我们打开unity创建一个项目,我们这里使用的是2018.4.12的版本
我们这次就点击鼠标左键生成一个个球来写这个对象池
我们创建一个代码,然后写出鼠标左键生成小球的代码,然后给小球添加一个刚体组件
然后我们运行程序就可以看到我们一直点着鼠标左键间隔五秒就会生成一个球体
但是这个时候我们发现生成了以后,如果我们不使用代码消失的话就会一直存在, 如果我们生成太多的话就会对游戏游玩和运行产生问题,这个时候对象池的作用也可以体现出来了
我们首先把这个小球拉成预制体然后在场景里把小球删掉。然后我们创建代码,来片编写对象池
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class duixiangchi : MonoBehaviour
{
public GameObject Sphere;
Queue<GameObject> Spere_;//Queue为队列,在这里我们用来存储我们的小球对象
public int Spere_Num=10;
public static duixiangchi Chi;
// Start is called before the first frame update
void Start()
{
Chi = this;
DXC();
}
public void DXC()
{
Spere_ = new Queue<GameObject>(); //初始化队列
GameObject Spere_a = null;//声明一个空的游戏物体;
for (int i = 0; i < Spere_Num; i++)
{
Spere_a = Instantiate(Sphere);//我们新建的物体就是我们的小球
Spere_a.SetActive(false);//让我们的新生成的小球隐藏起来;
Spere_.Enqueue(Spere_a);//将我们新生成的小球放入到我们的队列里
}
}
public GameObject GetSpere()//创建一个方法来获取我们需要的游戏物体
{
if(Spere_!=null&&Spere_.Count>0)
{
GameObject Spere_a = Spere_.Dequeue();//从对象池里拿出来一个小球
Spere_a.SetActive(true);//把小球显示出来
return Spere_a;//返回小球这个游戏物体
}
else
{
return Instantiate(Sphere);//如果我们的对象池里没有对象,就克隆一个返回出来
}
}
public void DesSphere(GameObject Spere_a)//把我们拿出去使用过的对象再拿回来
{
Spere_a.SetActive(false);//将对象隐藏
Spere_a.Enqueue(Spere_a);//将对象重新放回我们的对象池
}
// Update is called once per frame
void Update()
{
}
}
这里我们就已经写出了对象池的基本结构,然后我们再编写一个代码来使用实现对象池的使用,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class shiyong : MonoBehaviour
{
public float Spere_Time;
public GameObject Game;
private void OnEnable()//当对象激活时,我们可以在这里给我们刚刚生成的物体加自己想要的状态等等
{//在这里我们已经提前添加了该有的刚体组件就不再展示了
}
private void OnDisable()//当我们的对象处于隐藏的状态的时候,这个基本就是我们要让物体的一些自带的属性还原
{
}
private void OnDestroy()//当我们的物体消失的时候,这种可以用来实现,指弹的计数,得分等等
{
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{ Spere_Time += Time.deltaTime;
if(Spere_Time>=2F)
{
Spere_Time = 0;
duixiangchi.Chi.DesSphere(Game);//每过两秒就自动回收到对象池
}
}
}
然后我们在我们第一个生成的代码里对我们的小球的生成,进行一点改造,
我们将第二个代码放在我们的预制体小球上面,再将小球拉入代码里,让其自我回收,其他的两个代码放在我们的外部都可以,然后运行可以看到一开始场景里就多了一部分小球,然后我们点击鼠标的左键,可以看到我们的小球出现在了场景里,我们不动过了几秒以后小球就会自己不显示的回到对象池里
这就是最基本的对象池的一个使用,当然能修改的地方还有很多,如有错误请大佬指出