|
Chinar 堅持將簡單的生活方式,帶給世人! (擁有更好的閱讀體驗 —— 高分辨率用戶請根據需求調整網頁縮放比例) |
|
助力快速完成 Unity 對象池的創建與使用 為新手節省寶貴的時間,避免采坑! |
Chinar 教程效果:
1
MonoSingleton —— 單例基類
任何繼承自 MonoSingleton 泛型基類的腳本/類 都是單例類

using UnityEngine;
/// <summary>
/// 泛型單例基類 —— 任何繼承自該類的類,都是單例類
/// </summary>
/// <typeparam name="T">泛型</typeparam>
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
instance = FindObjectOfType(typeof(T)) as T;
if (instance == null) instance = new GameObject("Chinar Single of " + typeof(T).ToString(), typeof(T)).GetComponent<T>();
}
return instance;
}
}
private void Awake()
{
if (instance == null) instance = this as T;
}
private void OnApplicationQuit()
{
instance = null;
}
}
2
ObjectPool —— 對象池
新建一個腳本 ObjectPool 繼承自泛型基類 MonoSingleton《ObjectPool》
是以 ObjectPool 就會是一個單例類

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 對象池(重復調用/使用的游戲物體) 子彈,技能,導彈,敵人
/// </summary>
public class ObjectPool : MonoSingleton<ObjectPool>
{
//字段 池 技能預設物(因為一個技能可能有多個預制件) 技能的復用性
private Dictionary<string, List<GameObject>> cache = new Dictionary<string, List<GameObject>>();
int i = 0; //標記 0
/// <summary>
/// 創建顯示對象
/// </summary>
/// <returns>The object.</returns>
/// <param name="key">對象名稱</param>
/// <param name="go">對象的預制件</param>
/// <param name="position">對象的新位置</param>
/// <param name="quaternion">對象的角度</param>
public GameObject CreateObject(string key, GameObject go, Vector3 position, Quaternion quaternion)
{
GameObject tempgo = cache.ContainsKey(key) ? cache[key].Find(p => !p.activeSelf) : null; //返回池中未激活的對象,所有都被激活就返回空,賦值給臨時對象
if (tempgo != null) //如果臨時對象不為空
{
tempgo.transform.position = position; //設置位置
tempgo.transform.rotation = quaternion; //旋轉信息
}
else //否則,就是空了。(也就是沒能從池子里取出對象)
{
tempgo = Instantiate(go, position, quaternion); //那就根據傳入的預設物,生成一個新物體
print("實例化物體數量:" + i++);
if (!cache.ContainsKey(key)) //池中沒有鍵
{
cache.Add(key, new List<GameObject>()); //新建一個 列表
}
cache[key].Add(tempgo); //給字典中的列表加入/add 臨時物體,如果有鍵就直接添加了
}
tempgo.SetActive(true); //並啟用臨時物體
return tempgo; //返回
}
/// <summary>
/// 直接回收
/// </summary>
/// <param name="go">Go.</param>
public void CollectObject(GameObject go)
{
go.SetActive(false);
}
/// <summary>
/// 延遲回收
/// </summary>
/// <param name="go">Go.</param>
/// <param name="delay">Delay.</param>
public void CollectObject(GameObject go, float delay)
{
StartCoroutine(Collect(go, delay));
}
private IEnumerator Collect(GameObject go, float delay)
{
yield return new WaitForSeconds(delay);
CollectObject(go);
}
/// <summary>
/// 釋放資源
/// </summary>
/// <returns>The clear.</returns>
/// <param name="key">Key.</param>
public void Clear(string key)
{
if (cache.ContainsKey(key))
{
//Destroy當中所有的對象
for (int i = 0; i < cache[key].Count; i++)
{
Destroy(cache[key][i]);
}
//清除鍵當中的所有值
//cache[key].Clear();
//清除這個鍵(鍵值一起清除)
cache.Remove(key);
}
}
/// <summary>
/// 釋放所有對象池
/// </summary>
public void ClearAll()
{
var list = new List<string>(cache.Keys);
for (int i = 0; i < list.Count; i++)
{
Clear(list[i]);
}
}
}
3
PoolTest —— 測試對象池的使用
新建一個腳本 PoolTest 用來測試對象池的使用

using UnityEngine;
/// <summary>
/// 測試對象池的調用
/// </summary>
public class PoolTest : MonoBehaviour
{
GameObject go; //臨時對象
GameObject item; //臨時對象池對象
void Start()
{
go = Resources.Load<GameObject>("Cube"); //在Resources文件目錄下做一個Cube預設物
}
void Update()
{
if (Input.GetKey(KeyCode.Space)) //按下空格創建一個Cube
{
item = ObjectPool.Instance.CreateObject("Object1", go, Vector3.zero, new Quaternion(0, 0, 0, 0));
item.transform.position += new Vector3(0, 0, 1);
}
if (Input.GetMouseButtonDown(0)) //按下左鍵執行回收對象
{
if (item != null)
{
ObjectPool.Instance.CollectObject(item, 0.2f);
}
}
if (Input.GetMouseButtonDown(1)) //按下右鍵執行清除已經生成的對象
{
ObjectPool.Instance.Clear("Object1");
}
}
}
支持
May Be —— 搞開發,總有一天要做的事!
|
Chinar 提供一站式教程,閉眼式創建! 為新手節省寶貴時間,避免采坑! |
先點擊領取 —— 阿里全產品優惠券 (享受最低優惠)
1 —— 雲服務器超全購買流程 (新手必備!)
2 —— 阿里ECS雲服務器自定義配置 - 購買教程(新手必備!)
3—— Windows 服務器配置、運行、建站一條龍 !
4 —— Linux 服務器配置、運行、建站一條龍 !
Chinar
本博客為非營利性個人原創,除部分有明確署名的作品外,所刊登的所有作品的著作權均為本人所擁有,本人保留所有法定權利。違者必究
對於需要復制、轉載、鏈接和傳播博客文章或內容的,請及時和本博主進行聯系,留言,Email: ichinar@icloud.com
對於經本博主明確授權和許可使用文章及內容的,使用時請注明文章或內容出處並注明網址
