对象池的实现:
一、先定义个List集合用来存储对象,起初先在池子里放置一定数量的对象,并且把他设置为false;然后写一个方法查找没有激活的对象,并且返回一个激活的对象;如果池子中对象数量不够,重新再向池子里添加对象。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 脚本挂在到空物体上
/// </summary>
public class ObjectPool : MonoBehaviour {
public static ObjectPool current;
void Awake()
{
current = this;
}
//将被放入对象池中的预制体
GameObject objectPrb;
//池子大小
public int poolCapacity = 20;
//定义对象集合
public List<GameObject> pool;
//池子容量不够时,是否自动扩展池子
public bool willgrow = true;
void Start(){
//加载预设体
objectPrb= Resources.Load("Sphere")as GameObject;
for(int i = 0 ; i<poolCapacity ; i++)
{
GameObject obj = Instantiate(objectPrb);
pool.Add(obj);
obj.SetActive(false);
}
}
public GameObject GetPooledObject(){
for( int i = 0 ; i<pool.Count ; i++) //遍历对象池,将未激活的对象传递出去
{
if ( ! pool[i].activeInHierarchy )
return pool[i];
}
if ( willgrow ) //当池子中所有对象都激活了,但是还想激活显示对象时,扩展池子
{
GameObject obj = Instantiate(objectPrb);
pool.Add(obj);
obj.SetActive(false);
return obj;
}
return null;
}
}
二、创建控制脚本,调用对象池的函数
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 脚本挂在到空物体上
/// </summary>
public class Control : MonoBehaviour {
void Update () {
if (Input.GetMouseButtonDown(0))
{
Fire();
}
}
void Fire()
{
GameObject obj = ObjectPool.current.GetPooledObject();
if (obj == null)
{
return;
}
obj.transform.position = Vector3.one;
obj.transform.rotation = transform.rotation;
obj.SetActive(true);
}
}
三、预设体消失的时候只需要取消激活
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour {
void OnEnable()
{
Invoke("Destroy",2);
}
void Destroy() {
gameObject.SetActive(false);
}
void OnDisable(){
CancelInvoke();
}
void Update()
{
transform.Translate(transform.forward * 5f * Time.deltaTime);
}
}
网友评论