Unity中的場景管理

一、簡述

? ? ? ? 在我們實際的項目開發(fā)中,項目中通常有一個以上的場景Scene,尤以MOBA和RGP有大量的Scene。場景的加載為何用異步加載,最為主要的是用戶體驗。當Scene較大時,使用同步加載時,直接在內(nèi)存中映射加載,會造成許久的卡頓后才正常顯示,且用戶體驗很差,所以選擇異步加載且用一個過渡的UI界面來顯示場景的加載進步。


二、基本思路

????????在當前場景中開啟一個協(xié)程Coroutines,并使用UnityEngine.SceneManagement.SceneManager中的異步加載方法LoadSceneAsync(string sceneName)。詳細代碼請見下方。

private string strNextSceneName = null;//下一需要加載的場景

private void LoadScene(string sceneName)

{

strNextSceneName = sceneName;

StartCoroutine(StartLoadScene());//開啟協(xié)程

}

private IEnumerator StartLoadScene() {

AsyncOperation async = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(strNextSceneName);//使用異步加載

if (null == async)

{

yield break;//關(guān)閉協(xié)程

}

}

三、項目開發(fā)思路

? ? ? ? 在實際項目中,我們可能會返回上一個場景,用一個UI界面來顯示場景加載的進度,且在加載完成后回調(diào)。那么新建場景管理類來統(tǒng)一調(diào)度場景。

using System;

using System.Collections;

using UnityEngine;

/// /// 場景管理類///

public class SceneManager : MonoBehaviour{

private static SceneManager _mInstance;//私有單例

?private Action onSceneLoaded = null;//場景加載完成回調(diào)

private string strNextSceneName = null;//將要加載的場景名

private string strCurSceneName = null;//當前場景名,如若沒有場景,則默認返回Login

private string strPreSceneName = null;//上一個場景名

private bool bLoading = false; //是否正在加載中

private bool bDestroyAuto = true;//自動刪除loading背景

private const string _strLoadSceneName = "LoadingScene"; //加載場景名字

/// /// 獲取當前場景名 ///

public static string strLoadedSceneName => _mInstance.strCurSceneName;

public static void CreateInstance(GameObject go) {

if (null != _mInstance) return;

{

_mInstance = go.AddComponent();

DontDestroyOnLoad(_mInstance);

_mInstance.strCurSceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; }

}

/// /// 加載前一個場景 ///

public static void LoadPreScene() {

if (string.IsNullOrEmpty(_mInstance.strPreSceneName)) return;

{

LoadScene(_mInstance.strPreSceneName); }

}

public static void LoadScene(string strLevelName) {

_mInstance.LoadLevel(strLevelName,null);

}

public static void LoadScene(string strLevelName, Action onSecenLoaded) {

_mInstance.LoadLevel(strLevelName, onSecenLoaded);

}

//加載場景 bDestroyAuto 自動刪除loading背景

void LoadLevel(string strLevelName, Action onSecenLoaded, bool isDestroyAuto = true) {

//是否可加載

if (bLoading) { return; }

if (strCurSceneName == strLevelName) {

//return;

}

bLoading = true; //鎖屏

//開始加載 onSceneLoaded = onSecenLoaded;

strNextSceneName = strLevelName;

strPreSceneName = strCurSceneName;

strCurSceneName = _strLoadSceneName;

bDestroyAuto = isDestroyAuto;

//加載進度UI界面

InitLoadingUI();

StartCoroutine(StartLoadSceneOnEditor(_strLoadSceneName, OnLoadingSceneLoaded, null)); //StartCoroutine(StartLoadSceneOnEditor(strNextSceneName, OnNextSceneLoaded, OnNextSceneProgress));

}

//加載顯示進度的UI界面

private void InitLoadingUI() {

UILoadingView.Show();//UI加載進度界面

}

//當加載過度場景加載完成

void OnLoadingSceneLoaded() {

StartCoroutine(StartLoadSceneOnEditor(strNextSceneName, OnNextSceneLoaded, OnNextSceneProgress));

}

//場景加載進度變化

void OnNextSceneProgress(float fProgress) {

UILoadingView.Instance.UpdateProgress(fProgress);

}

//加載下一場景王城回調(diào)

void OnNextSceneLoaded() {

bLoading = false;

OnNextSceneProgress(1);

strCurSceneName = strNextSceneName;

strNextSceneName = null;

onSceneLoaded?.Invoke();

}

//開始加載

private IEnumerator StartLoadSceneOnEditor(string strLevelName, Action OnSecenLoaded, Action OnSceneProgress) {

AsyncOperation async = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(strLevelName);

if (null == async) {

yield break;

}

while (!async.isDone) {//是否加載完成

//若未加載完成,則回調(diào)進度Action

OnSceneProgress?.Invoke(async.progress);

yield return null;

}

OnSecenLoaded?.Invoke();

}

}


注:

? ? ? ? 如果考慮到代碼性能的話,進度回調(diào)和加載完成回調(diào)使用delegate委托,去除System.dll的引用;

????????協(xié)程的yield return 0應(yīng)該使用yield return null,減少GC,因為0=>nul中有個裝箱過程,會產(chǎn)生不必要的GC;

? ? ? ? 協(xié)程的開啟需要在MonoBehaviour中實現(xiàn),則需要SceneManager的實例,且掛在場景中,保證場景在加載中不被摧毀;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,829評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,737評論 18 399
  • 這是公司老板親自站在大門發(fā)的開工禮品 開門迎旺旺 今年一定旺 紅包里面裝的是一注彩票 萬一中獎了呢 三月新規(guī)一出 ...
    慕星讀者OR獨者閱讀 353評論 0 1
  • 愿有歲月可回首,且以深情共白頭!
    芊宇閱讀 120評論 0 0
  • 新的一年開始了,想要進步的朋友又紛紛做起健身計劃學(xué)習(xí)計劃。我也想要進步也想要身材更好,但我不會一上來就去辦一張健身...
    神奇安妮閱讀 5,962評論 29 206