Objectpool (物件池) 帶例項
之前發了快取池的用法,那麼索性把物件池也寫一個把。
首先是Unity佈置:
程式碼直接給“Main Camera”
預製體新增剛體:也就是要發射的子彈。
Poolable程式碼:
public class Poolable : MonoBehaviour
{
public string key;
public bool isPooled;
}
POOL程式碼:
public class POOLc : MonoBehaviour
{
const string PoolKey = "";
[SerializeField]//序列化域,可以序列化非公有非靜態域用[SerializeField]屬性標記。不可以序列化靜態域/不可以序列化屬性 序列化的型別有:
//- All classed inheriting from UnityEngine.Object, for example Gameobject, Commponent, MonoBehaviour, Texture2D, AnimationClip.. - All basic data types like int, string, float, bool. - Some built in types like Vector2, Vector3, Vector4, Quaternion, Matrix4x4, Color, Rect, Layermask.. - Arrays of a serializable type
//- 所有繼承自UnityEngine.Object的類,例如GameObject,Component,MonoBehaviour,Texture2D,AnimationClip..- 所有基本型別像int,string,float,bool.- 一些內建型別像Vector2,Vector3,Vector4,Quaternion,Matrix4x4,Color,Rect,Layermask..- 一個序列化型別的Array(陣列)
GameObject prefab;
List<Poolable> instances = new List<Poolable>();
public Transform Mytrans;
bool isFire = false;
Poolable obj;
void Start()
{
if (GameObjectPoolController.AddEntry(PoolKey, prefab, 5, 10))
Debug.Log("預填充池");
else
Debug.Log("池已配置");
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
obj = GameObjectPoolController.Dequeue(PoolKey);
obj.gameObject.SetActive(true);
instances.Add(obj);
isFire = true;
}
if (instances.Count > 1)
{
Poolable obj = instances[0];
instances.RemoveAt(0);
GameObjectPoolController.Enqueue(obj);
}
if (isFire)
{
obj.GetComponent<Rigidbody>().velocity = new Vector3(0,0,-100);
obj.transform.position = Mytrans.position;
obj.transform.forward = Mytrans.forward;
isFire = false;
}
}
}
PoolData程式碼:
public class PoolData
{
public GameObject prefab;//預設
public int maxCount;//變數最大個數
public Queue<Poolable> pool;//預填充列
}
public class GameObjectPoolController : MonoBehaviour
{
//單例
static GameObjectPoolController Instance
{
get
{
if (instance == null)
CreateSharedInstance();
return instance;
}
}
static GameObjectPoolController instance;
static Dictionary<string, PoolData> pools = new Dictionary<string, PoolData>();
void Awake()
{
if (instance != null && instance != this)
Destroy(this);
else
instance = this;
}
//設定儲存最大值
public static void SetMaxCount(string key, int maxCount)
{
if (!pools.ContainsKey(key))
return;
PoolData data = pools[key];
data.maxCount = maxCount;
}
//入倉
public static bool AddEntry(string key, GameObject prefab, int prepopulate, int maxCount)
{
if (pools.ContainsKey(key))
return false;
PoolData data = new PoolData();
data.prefab = prefab;
data.maxCount = maxCount;
data.pool = new Queue<Poolable>(prepopulate);
pools.Add(key, data);
for (int i = 0; i < prepopulate; ++i)
Enqueue(CreateInstance(key, prefab));
return true;
}
//清倉
public static void ClearEntry(string key)
{
if (!pools.ContainsKey(key))
return;
PoolData data = pools[key];
while (data.pool.Count > 0)
{
Poolable obj = data.pool.Dequeue();
GameObject.Destroy(obj.gameObject);
}
pools.Remove(key);
}
internal static void Enqueue(List<Poolable> instances)
{
throw new NotImplementedException();
}
//入隊
public static void Enqueue(Poolable sender)
{
if (sender == null || sender.isPooled || !pools.ContainsKey(sender.key))
return;
PoolData data = pools[sender.key];
if (data.pool.Count >= data.maxCount)
{
GameObject.Destroy(sender.gameObject);
return;
}
data.pool.Enqueue(sender);
sender.isPooled = true;
sender.transform.SetParent(Instance.transform);
sender.gameObject.SetActive(false);
}
//出隊
public static Poolable Dequeue(string key)
{
if (!pools.ContainsKey(key))
return null;
PoolData data = pools[key];
if (data.pool.Count == 0)
return CreateInstance(key, data.prefab);
Poolable obj = data.pool.Dequeue();
obj.isPooled = false;
return obj;
}
// 建立共享例項 主要是建立一個不銷燬的父物體
static void CreateSharedInstance()
{
GameObject obj = new GameObject("GameObject Pool Controller");
DontDestroyOnLoad(obj);
instance = obj.AddComponent<GameObjectPoolController>();
}
static Poolable CreateInstance(string key, GameObject prefab)
{
GameObject instance = Instantiate(prefab) as GameObject;
Poolable p = instance.AddComponent<Poolable>();
p.key = key;
return p;
}
}
效果圖:
Demo連結:https://pan.baidu.com/s/1_P2S-Jr4eaBymJK3UsyUYw 密碼:tp49