对象池:子弹的发射和子弹撞击后的回收
作用:使游戏不卡顿,提高游戏性能
先声明一个接口:写进出池子的方法,通过继承达到进出的效果
publicinterfaceIPoolObject
{
void EnterPool();
void ExitPool();
}
创建基础实例对象 用来继承接口
达到进出池子的初始化
publicclassBasePoolObject : MonoBehaviour, IPoolObject
{
publicvoid EnterPool() // 进仓进行存储
{
Debug.Log("进入池子的初始化");
}
publicvoid ExitPool() // 出仓
{
Debug.Log("退出池子的初始化 -- 获取使用");
}
//做碰撞器的物体点一下进行回收
void OnMouseDown()
{
Pool.instance.Recycle(this.gameObject);
}
//发生碰撞回收物体
void OnTriggerEnter(Collider other)
{
Pool.instance.Recycle(this.gameObject);
}
}
实现物体的产生,存储,出仓和回收
publicclassPool : MonoBehaviour
{
//Unity中实现单例的方法 方便访问池子
publicstaticPool instance;
//有多少子弹
publicint initCount;
//进哪种子弹
publicGameObject objPrefab;
//存放在哪
publicQueue<GameObject> queue = newQueue<GameObject>();
void Awake()
{
instance = this;
Init();
}
//存放子弹
publicvoid Init()
{
IPoolObject ipoolObject = objPrefab.GetComponent<IPoolObject>();
if (ipoolObject != null)
{
for (int i = 0; i < initCount; i++)
{
//存储子弹到弹夹中
GameObject obj = GameObject.Instantiate(objPrefab);
//obj.transform.position = new Vector3(10000,10000, 10000);
obj.SetActive(false);
queue.Enqueue(obj);
}
}
else
{
Debug.Log("不是我想要的子弹,初始化失败");
return;
}
}
//打出子弹
publicGameObject GetObject()
{
GameObject result = null;
//判断是否有货
if (queue.Count >=1)
{
result = queue.Dequeue();
result.SetActive(true);
result.GetComponent<IPoolObject>().ExitPool();
}
//没货
else
{
result = GameObject.Instantiate(objPrefab);
result.GetComponent<IPoolObject>().ExitPool();
}
return result;
}
//回收子弹
publicvoid Recycle(GameObject obj)
{
IPoolObject ipoolObject = obj.GetComponent<IPoolObject>();
if (ipoolObject != null)
{
//禁止使用
obj.SetActive(false);
//初始化
ipoolObject.EnterPool();
//存入队列
queue.Enqueue(obj);
}
}
}
对武器的操作也是鼠标进行点击发出子弹
publicclassWeapon : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
GameObject bullet = Pool.instance.GetObject();
bullet.transform.position =ray.origin;
bullet.GetComponent<Rigidbody>().AddForce(ray.direction * 20);
}
}
}
子弹的移动
publicclassShellRemove : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
transform.Translate(newVector3(0, 0, 1) * Time.deltaTime * 10, Space.World);
}
}
程序测试
publicclassTest : MonoBehaviour {
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown(1))
{
Pool.instance.GetObject();
}
}
}
挂脚本:
子弹预制体挂上移动脚本ShellRemove和测试脚本Test 和对象池脚本BasePoolObject
空物体上挂上操作脚本Pool 和武器脚本Weapon
还有需要注意的碰撞刚体
子弹预制体作为主动方需要挂Rigidbody刚体和Box Collider
物体墙上BoxCollider中Is Trigger不勾选