Unity游戲對象池和單例模式的配合使用

? ? ? ?本次介紹兩個腳本GameObjectPool游戲對象池類和MonoSingLeton單例模式類利虫。

? ? ? ?在Unity中不論是在游戲中或者是別的應用場景,我們有時候會需要重復產生相同的物體并銷毀掉冈爹,例如子彈就得不斷生成不斷銷毀倾鲫。但這樣是很消耗性能的崖堤。所以有的大佬就設計了游戲對象池這個概念毅糟。

? ? ? ?游戲對象池腳本掛在一個空物體上,玩家在Unity中不需要使用 Instantiate() 方法進行創(chuàng)建物體弛饭。而是用我GameObjectPool腳本中的CreateObject(string key,GameObject go,Vector3 pos,Quaternion rat)進行創(chuàng)建冕末。依次是預制件名稱、預制件對象侣颂、三維坐標數據档桃、旋轉數據。當使用這個方法創(chuàng)建時物體時憔晒,該物體會成為對象池的子物體藻肄,而當需要到銷毀時對象池會將該物體隱藏,若再次需要用到拒担,則重新設置物體的坐標和旋轉并啟用嘹屯。若對象池內的物體不夠用了才會重新生成一個對象。

? ? ? ?游戲對象池在游戲中只能有一個从撼,所以需要將他設計為單例模式州弟。只需要讓游戲對象池繼承他便可。然后調用他的instance方法就可以了低零。

————————————————————————————————————————

MonoSingLeton腳本

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

/// <summary>

/// 單例模式掛載腳本

/// </summary>

public abstract class MonoSingLeton<T> : MonoBehaviour where T : MonoSingLeton<T>

{

? ? private static T m_Instance = null;

? ? //3.

? ? //設計階段婆翔,寫腳本沒有掛在物體上,希望腳本單例模式

? ? //運行時掏婶,需要這個腳本唯一實例啃奴,第1次,調用instance

? ? public static T instance

? ? {

? ? ? ? get

? ? ? ? {

? ? ? ? ? ? if(m_Instance == null)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? m_Instance = FindObjectOfType(typeof(T)) as T;

? ? ? ? ? ? ? ? if (m_Instance == null)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? m_Instance = new GameObject("Singleton of" + typeof(T).ToString(), typeof(T)).GetComponent<T>();

? ? ? ? ? ? ? ? ? ? m_Instance.Init();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }


? ? ? ? ? ? return m_Instance;

? ? ? ? }

? ? }

? ? private void Awake()

? ? {

? ? ? ? if (m_Instance == null)

? ? ? ? {

? ? ? ? ? ? m_Instance = this as T;

? ? ? ? }

? ? }

? ? //提供初始化一種選擇

? ? public virtual void Init() { }

? ? //當程序退出時做清理工作雄妥,單例模式對象=null

? ? private void OnApplicationQuit()

? ? {

? ? ? ? m_Instance = null;

? ? }

}

——————————————————————————————————————

游戲對象池腳本

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

/// <summary>

/// 游戲對象池

/// </summary>

public class GameObjectPool : MonoSingLeton<GameObjectPool>

{

? ? //1.創(chuàng)建池

? ? private GameObjectPool()

? ? {

? ? }

? ? //static private GameObjectPool obj = new GameObjectPool();

? ? ////提供得到對象的唯一通道

? ? //static public GameObjectPool GetObject()

? ? //{

? ? //? ? return obj;

? ? //}

? ? private Dictionary<string, List<GameObject>> cache = new Dictionary<string, List<GameObject>>();

? ? //2.創(chuàng)建一個對象并使用對象

? ? public GameObject CreateObject(string key,GameObject go,Vector3 pos,Quaternion rat)

? ? {

? ? ? ? //1.查找池中有無可用的游戲對象

? ? ? ? GameObject tempGo = FindUsable(key);

? ? ? ? //2.池中有從池中返回

? ? ? ? if (tempGo != null)

? ? ? ? {

? ? ? ? ? ? tempGo.transform.position = pos;

? ? ? ? ? ? tempGo.transform.rotation = rat;

? ? ? ? ? ? tempGo.SetActive(true);? //表示當前正在使用

? ? ? ? }

? ? ? ? else//3.池中沒有加載最蕾,放入池中再返回

? ? ? ? {

? ? ? ? ? ? tempGo = Instantiate(go, pos, rat) as GameObject;

? ? ? ? ? ? //放入池中

? ? ? ? ? ? Add(key, tempGo);

? ? ? ? }

? ? ? ? tempGo.transform.parent = transform;

? ? ? ? return tempGo;

? ? }

? ? private GameObject FindUsable(string key)

? ? {

? ? ? ? if (cache.ContainsKey(key))

? ? ? ? {

? ? ? ? ? ? //從列表中找出未激活的游戲物體

? ? ? ? ? ? return cache[key].Find((p) => !p.activeSelf);

? ? ? ? }

? ? ? ? return null;

? ? }

? ? private void Add(string key,GameObject go)

? ? {

? ? ? ? //檢查池中有沒有需要的key,沒有的話則創(chuàng)建對應列表

? ? ? ? if (!cache.ContainsKey(key))

? ? ? ? {

? ? ? ? ? ? cache.Add(key,new List<GameObject>());

? ? ? ? }

? ? ? ? cache[key].Add(go);

? ? }

? ? //3.? 釋放資源:從池中刪除對象

? ? //3.1 釋放部分:按key釋放

? ? public void Clear(string key)

? ? {

? ? ? ? if (cache.ContainsKey(key))

? ? ? ? {

? ? ? ? ? ? //銷毀場景中游戲物體

? ? ? ? ? ? for (int i = 0; i < cache[key].Count; i++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? Destroy(cache[key][i]);

? ? ? ? ? ? }

? ? ? ? ? ? //緊緊移除了字典中對象地址

? ? ? ? ? ? cache.Remove(key);

? ? ? ? }

? ? }

? ? //3.2 釋放全部

? ? public void ClearAll()

? ? {

? ? ? ? List<string> list = new List<string>(cache.Keys);

? ? ? ? for (int i = 0; i < list.Count; i++)

? ? ? ? {

? ? ? ? ? ? Clear(list[i]);

? ? ? ? }

? ? }

? ? //4.? 回收對象【從畫面中消失】

? ? //4.1 即使回收對象

? ? public void CollectObject(GameObject go)

? ? {

? ? ? ? go.SetActive(false);

? ? }

? ? //4.2 延時回收對象? 協程

? ? public void CollectObject(GameObject go,float delay)

? ? {

? ? ? ? StartCoroutine(CollectDelay(go,delay));

? ? }

? ? private IEnumerator CollectDelay(GameObject go,float delay)

? ? {

? ? ? ? yield return new WaitForSeconds(delay);

? ? ? ? CollectObject(go);

? ? }

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末茎芭,一起剝皮案震驚了整個濱河市揖膜,隨后出現的幾起案子誓沸,更是在濱河造成了極大的恐慌梅桩,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拜隧,死亡現場離奇詭異宿百,居然都是意外死亡趁仙,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門垦页,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雀费,“玉大人,你說我怎么就攤上這事痊焊≌蛋溃” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵薄啥,是天一觀的道長辕羽。 經常有香客問我,道長垄惧,這世上最難降的妖魔是什么刁愿? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮到逊,結果婚禮上铣口,老公的妹妹穿的比我還像新娘。我一直安慰自己觉壶,他們只是感情好脑题,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著铜靶,像睡著了一般旭蠕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旷坦,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天掏熬,我揣著相機與錄音,去河邊找鬼秒梅。 笑死旗芬,一個胖子當著我的面吹牛,可吹牛的內容都是我干的捆蜀。 我是一名探鬼主播疮丛,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼辆它!你這毒婦竟也來了誊薄?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤锰茉,失蹤者是張志新(化名)和其女友劉穎呢蔫,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體飒筑,經...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡片吊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年绽昏,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俏脊。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡全谤,死狀恐怖,靈堂內的尸體忽然破棺而出爷贫,到底是詐尸還是另有隱情认然,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布漫萄,位于F島的核電站季眷,受9級特大地震影響,放射性物質發(fā)生泄漏卷胯。R本人自食惡果不足惜子刮,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窑睁。 院中可真熱鬧挺峡,春花似錦、人聲如沸担钮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽箫津。三九已至狭姨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間苏遥,已是汗流浹背饼拍。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留田炭,地道東北人师抄。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像教硫,于是被迫代替她去往敵國和親叨吮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348