在網(wǎng)上看見了對象池的一些應(yīng)用遏暴,一直很好奇,所以來研究一下
對象池主要的用途就是在那些需要重復(fù)被創(chuàng)建和銷毀的物體上可以不進(jìn)行重復(fù)的創(chuàng)建和銷毀,例如子彈宗收,在射擊時(shí)被創(chuàng)建,一般在打到物體或者飛行一段距離(時(shí)間)后被銷毀亚兄,然后再射擊一次混稽,再重復(fù)此操作,但要知道审胚,多次的創(chuàng)建和銷毀很耗性能匈勋,而對象池可以這樣去處理子彈——在射擊時(shí)先查詢對象池里有沒有沒被激活的子彈,沒有就創(chuàng)建一個(gè)新的膳叨,并把新的子彈加入到對象池洽洁,再把它射擊出去;有就激活舊子彈菲嘴,然后重置其參數(shù)饿自,再把它射擊出去,打到物體或者飛行一段距離(時(shí)間)后不進(jìn)行銷毀而是直接隱藏龄坪,這樣就可以做到重復(fù)利用已創(chuàng)建出來的子彈昭雌,只進(jìn)行激活和隱藏操作,大大節(jié)省了性能
那么具體就見代碼吧悉默,就以子彈為例
現(xiàn)在寫了三個(gè)腳本城豁,一個(gè)是子彈的,主要有子彈的速度抄课,飛行距離唱星,初始位置,移動跟磨,銷毀间聊,碰撞
一個(gè)是武器的,主要有子彈抵拘,子彈射擊出的位置哎榴,創(chuàng)建對應(yīng)類型的子彈的克隆體并加入到對象池中
一個(gè)是對象池的,有一個(gè)存放所有克隆體的字典,以Tag為key尚蝌,有加入字典的方法迎变,又找到某種類型的克隆體的方法,還有一個(gè)重置物體的方法
這樣構(gòu)成了一個(gè)最簡單的子彈對象池
首先是子彈代碼:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace tomo
{
public class bullet : MonoBehaviour
{
// Use this for initialization
public float speed;
public float distance;
private Vector3 start_pos;
void Awake()
{
start_pos = transform.position;
}
void Start()
{
}
// Update is called once per frame
void Update()
{
Move();
}
private void Move()
{
transform.GetComponent<Rigidbody>().velocity = Vector3.forward * speed * Time.deltaTime;
destroy(distance);
}
private void destroy(float dis)
{
float D = Vector3.Distance(start_pos, transform.position);
if (D >= dis)
{
transform.gameObject.SetActive(false);
}
}
void OnTriggerEnter(Collider collider)
{
if (collider.transform.name == "Cylinder")
{
transform.gameObject.SetActive(false);
}
}
}
}
武器代碼:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace tomo
{
public class weapon : MonoBehaviour
{
public GameObject Bullet;
public Transform shootPostion;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Create_Bullet(shootPostion.position);
}
}
public void Create_Bullet(Vector3 sp)
{
List<GameObject> list = pool.getObj(Bullet);
if (list.Count > 0)
{
pool.reset(list[0], sp, transform.rotation);
list[0].SetActive(true);
//return list[0];
}
else
{
GameObject obj = GameObject.Instantiate(Bullet, sp, transform.rotation) as GameObject;
pool.inputObj(obj);
//return obj;
}
}
}
}
對象池代碼:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace tomo {
public class pool : MonoBehaviour {
// Use this for initialization
//public static List<GameObject> pooledObj = new List<GameObject>();
public static Dictionary<string, List<GameObject>> dictionary = new Dictionary<string, List<GameObject>>();
void Start() {
}
// Update is called once per frame
void Update() {
}
//將新建子彈加入對象池列表
public static void inputObj(GameObject obj)
{
//Debug.Log("......"+obj);
//pooledObj.Add(obj);
var tagString = obj.tag;
if (dictionary.ContainsKey(tagString))
{
dictionary[tagString].Add(obj);
}
else
{
List<GameObject> list = new List<GameObject>();
list.Add(obj);
dictionary.Add(tagString, list);
}
}
public void OnClickShowDictionary()
{
foreach (var item in dictionary.Keys)
{
var list = dictionary[item];
foreach (var it in list)
{
Debug.LogError("tag " + it.tag + " name " + it.name);
}
}
}
//在對象池列表中找到隱藏的對象
public static List<GameObject> getObj(GameObject obj)
{
List<GameObject> list = new List<GameObject>();
foreach (var tag in dictionary.Keys)
{
if (tag == obj.tag)
{
List<GameObject> dic_list = dictionary[tag];
for (int i = 0; i < dic_list.Count; i++)
{
if (dic_list[i].activeSelf == false)
{
list.Add(dic_list[i]);
}
}
}
}
return list;
}
public static void reset(GameObject obj, Vector3 position, Quaternion rotation)
{
obj.transform.position = position;
obj.transform.rotation = rotation;
}
}
}