這周VR做飛機的項目,子彈太多,用到對象池,用的是一個插件,但是發現一個問題,子彈數特別多的情況下,池裏放了400個子彈,特效也特別多,結果發現一個問題,從池中取對象和對象回池用時太長,多的時候能達到2ms。最後查看了底層,發現一個問題,池中對象是用list存放的,每次移除的時候耗時太多,應該是這個原因造成的。爲了驗證這個問題,我自己寫了一個對象池,思路大致是對的,沒有寫那麼嚴謹,可以做個參考。最後發現消時減少不少。主要是將list換成了LinkedList。
<pre name="code" class="csharp">using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Patent
{
public class ObjectPool
{
public LinkedList<GameObject> UsingLinkedList;
public LinkedList<GameObject> UnusingLinkedList;
private GameObject prefab;
public ObjectPool(GameObject prefab)
{
this.prefab = prefab;
UsingLinkedList =new LinkedList<GameObject>();
UnusingLinkedList = new LinkedList<GameObject>();
for (int i = 0; i < 10; i++)
{
GameObject go = GameObject.Instantiate(prefab);
go.SetActive(false);
UnusingLinkedList.AddFirst(go);
}
}
public ObjectPool(GameObject prefab, int preloadNum)
{
this.prefab = prefab;
UsingLinkedList = new LinkedList<GameObject>();
UnusingLinkedList = new LinkedList<GameObject>();
for (int i = 0; i < preloadNum; i++)
{
GameObject go = GameObject.Instantiate(prefab);
go.SetActive(false);
UnusingLinkedList.AddFirst(go);
}
}
public GameObject PullObjcetFromPool(Quaternion q,Vector3 pos)
{
GameObject go = null;
if (UnusingLinkedList.Count > 0)
{
go = UnusingLinkedList.First.Value;
go.SetActive(true);
go.transform.rotation = q;
go.transform.position = pos;
UnusingLinkedList.RemoveFirst();
UsingLinkedList.AddLast(go);
}
else
{
go = GameObject.Instantiate(prefab);
go.transform.rotation = q;
go.transform.position = pos;
UsingLinkedList.AddLast(go);
}
return go;
}
public void PushObjcetToPool(GameObject handleObjcet)
{
if (handleObjcet.activeSelf)
{
handleObjcet.SetActive(false);
UnusingLinkedList.AddFirst(handleObjcet);
UsingLinkedList.Remove(handleObjcet);
}
}
public void Dispose()
{
UsingLinkedList.Clear();
UnusingLinkedList.Clear();
UsingLinkedList = null;
UnusingLinkedList = null;
}
}
}
namespace Patent
{
public class PoolManager : MonoBehaviour
{
public static PoolManager Instance;
public List<GameObject> prefabList;
//存放預製體對應的id,ObjcetPool
public Dictionary<int ,ObjectPool> poolManagerDic;
void Awake()
{
Instance = this;
//初始化所有成員
poolManagerDic =new Dictionary<int, ObjectPool>();
if (prefabList!=null&&prefabList.Count>0)
{
int leng = prefabList.Count;
GameObject prefabUnit = null;
for (int i = 0; i < leng; i++)
{
prefabUnit = prefabList[i];
poolManagerDic.Add(prefabUnit.GetInstanceID(),new ObjectPool(prefabUnit));
}
}
}
void Start()
{
}
void Update()
{
}
/// <summary>
/// 獲取對應的對象池
/// </summary>
/// <param name="instanceID"></param>
/// <returns></returns>
public ObjectPool GetMyObjcetPool(int instanceID)
{
ObjectPool objcetPool = null;
if (poolManagerDic.ContainsKey(instanceID))
{
objcetPool = poolManagerDic[instanceID];
}
else
{
Debug.Log("cant find poolOjbects");
}
return objcetPool;
}
/// <summary>
/// 獲取對應的對象池
/// </summary>
/// <param name="prefab"></param>
/// <returns></returns>
public ObjectPool GetMyObjcetPool(GameObject prefab)
{
ObjectPool objcetPool = null;
int instanceID = prefab.GetInstanceID();
if (poolManagerDic.ContainsKey(instanceID))
{
objcetPool = poolManagerDic[instanceID];
}
return objcetPool;
}
public void PushObjectPool(GameObject handleObjcet,ObjectPool objcetPool)
{
objcetPool.PushObjcetToPool(handleObjcet);
}
public void PushObjectPool(GameObject handleObject, ObjectPool objcetPool, float delayTime)
{
StartCoroutine(DelayPushToObjcetPool(handleObject,objcetPool,delayTime));
}
IEnumerator DelayPushToObjcetPool(GameObject handleObject, ObjectPool objcetPool, float delayTime)
{
yield return new WaitForSeconds(delayTime);
objcetPool.PushObjcetToPool(handleObject);
}
}
}
有時間將它完成,做成工具類,方便使用