序
一個游戲往往都是由很多場景組成的,例如會有主界面場景、戰(zhàn)斗場景…等,不同的場景也是由若干的資源組合而成,在游戲的制作過程中,場景和資源的加載是不可或缺的。不管是場景還是資源都會涉及到加載的問題,在什么時候進(jìn)行場景或資源的加載?場景的加載和資源的加載如何區(qū)分?加載時是使用同步的方式還是異步的方式?…
場景加載
在需要切換到新場景時,就會涉及到場景加載。Unity場景加載分為同步加載和異步加載。
提到場景的跳轉(zhuǎn),在Unity中想要實現(xiàn)場景轉(zhuǎn)換的前置工作就是將涉及到加載的場景添加到Scenes In Build中。
操作流程:
1、選中File中的Build Settings
2、在Scenes In Build中添加場景
Unity中常用的場景加載相關(guān)方法
1、加載場景(同步、異步)
同步加載場景 SceneManager.LoadScene();
此方法的第一個參數(shù)可以使用場景的名稱(輸入名稱時要使用字符串)或者在Scenes In Build中對應(yīng)的數(shù)字編號。
此方法的第二個參數(shù)是枚舉變量,對應(yīng)的枚舉類型是LoadSceneMode,這個枚舉類型只有兩個值
(1)當(dāng)給第二個參數(shù)賦值LoadSceneMode.Single時,這個加載場景方法就會使得當(dāng)前游戲中有且僅有我們給定的場景(第一個參數(shù)傳入的場景)會被加載。
(1)當(dāng)給第二個參數(shù)賦值LoadSceneMode.Additive時,會讓我們給定的場景加載,并讓這個場景與當(dāng)前已經(jīng)加載的場景同時顯示。
這種同步的場景加載方式存在一個問題,就是當(dāng)加載的場景很大很復(fù)雜時,加載速度就會變慢,而且加載時會出現(xiàn)卡頓,為了解決這個問題,Unity提供了一個新的方法。
異步加載場景 SceneManager.LoadSceneAsync();
此方法有返回值i,返回值的類型時AsyncOperation,我們可以通過接收這個返回值來跟蹤場景的加載進(jìn)度。
AsyncOperation.isDone
// 這個是用來判斷加載是否完成。這個屬性是加載完并且跳轉(zhuǎn)成功后才會變成完成。
AsyncOperation.allowSceneActivation
// 這個是加載完后,是否允許跳轉(zhuǎn),當(dāng)為false時,即使場景加載完了,也不會跳轉(zhuǎn)。
AsyncOperation.progress
// 這個時表示加載場景的進(jìn)度。實際上的值時 0 - 0.9, 當(dāng)值為0.9的時候,場景就已經(jīng)加載完成了。
需要注意的是,SceneManager.LoadSceneAsync() 方法也可以在普通的方法中調(diào)用,但這樣做會導(dǎo)致阻塞主線程,從而導(dǎo)致應(yīng)用程序在加載期間出現(xiàn)卡頓或無響應(yīng)的情況。所以異步加載場景更推薦卸載協(xié)程中使用。
2、獲取當(dāng)前場景 SceneManager.GetActiveScene();
通常使用這個方法是為了進(jìn)行后續(xù)獲取信息的一些操作,例如
// 獲取當(dāng)前場景
Scene scene = SceneManager.GetActiveScene();
// 場景名稱
Debug.log(scene.name);
// 場景是否已經(jīng)加載
Debug.log(scene.isLoaded);
// 場景路徑
Debug.log(scene.path);
// 場景索引
Debug.log(scene.buildIndex);
3、獲取調(diào)用場景對象所指向的場景中的所有游戲物體
Scene scene = SceneManager.GetActiveScene();
GameObject[] gos = scene.GetRootGameObjects();
以上都是針對場景的方法,下面介紹一些針對場景管理類而言的方法
4、獲得當(dāng)前加載的場景數(shù)量
Debug.log(SceneManager.sceneCount);
這個變量可以獲取到當(dāng)前加載的場景的數(shù)量,場景并非在同一時間只能存在一個,它是可以多個疊加起來的。
5、創(chuàng)建一個新的場景
// 方法中的參數(shù)是新場景的名稱
Scenee scene = SceneManager.CreateScene("newScene");
6、卸載場景
// 參數(shù)是要卸載的場景的場景名
SceneManager.UnloadSceneAsync(newScene);
卸載這個場景后,場景及其對應(yīng)的場景文件都會被刪除。
分析LoadSceneAsync相關(guān)問題
這里之所以將LoadSceneAsync單獨(dú)拿出來分析,是因為Unity異步加載場景的這個方法確實存在一些小坑,不便于使用者使用。
1、SceneManager.LoadSceneAsync()并不是真正上的后臺加載,它是在每一幀加載一些資源;
2、將allowSceneActivation設(shè)置為false后,Unity中就只會加載到90%,剩下的要等到allowSceneActivation設(shè)置為true才加載。加載到90%時,我們?nèi)藶榭刂谱屍溥M(jìn)度條的值為100%,實際并沒有加載完成,所以會卡頓;
3、floa類型轉(zhuǎn)int類型的轉(zhuǎn)換規(guī)則:值會向零舍入,1.99會返回1,0.9會返回0,所以我這的進(jìn)度條直接從0到100,就是這個原因,一直返回的是0。
類型轉(zhuǎn)換的規(guī)則:
當(dāng)在int(假設(shè)int是32位的)、float和double格式之間進(jìn)行強(qiáng)制類型轉(zhuǎn)換時,原則如下:
1.從 int 轉(zhuǎn)換成 float,數(shù)字不會溢出,但是可能被舍入。
2.從 int、float 轉(zhuǎn)換成 double,能夠保留精確的數(shù)值。因為 double 有更大的范圍和更高的精度(有效位數(shù))。
3.從 double 轉(zhuǎn)換成 float,因為 float 范圍要小一些,所以值可能溢出成 +∞ 或 -∞。另外由于float精度較小,還可能被舍入。
4.從 float、double 轉(zhuǎn)換成 int,值將會向零舍入。如1.999會被轉(zhuǎn)成1,-1.999會被轉(zhuǎn)成-1。同時值可能會溢出。
資源加載
資源加載和場景加載類似,也存在同步加載和異步加載。使用Unity開發(fā)游戲的過程中,資源的加載一直都是需要重點(diǎn)關(guān)注的。
Unity提供的資源加載方式
Unity一共提供了5種資源加載的方式,分別是
1、Resources(只能加載Resources目錄中的資源)
2、AssetBundle(只能加載AB資源,當(dāng)前設(shè)備允許訪問的路徑都可以)
3、WWW(可以加載任意處資源,包括項目外資源(如遠(yuǎn)程服務(wù)器))
4、AssetDatabase(只能加載Assets目錄下的資源,但只能用于Editor)
5、UnityWebRequest(可以加載任意處資源,是WWW的升級版本)
同步加載和異步加載的意義和優(yōu)缺點(diǎn)
既然資源加載有同步和異步兩種方式,那必然是因為兩者各有優(yōu)劣,那么了解兩者的差異,我們才可以在開發(fā)中靈活使用。
1、同步:并不是按字面意思的同時或一起,而是指協(xié)同步調(diào),協(xié)助、相互配合。是按先后順序執(zhí)行在發(fā)出一個功能調(diào)用時,在沒有得到返回結(jié)果之前一直在等待,不會繼續(xù)往下執(zhí)行。
同步的優(yōu)點(diǎn):管理方便,資源準(zhǔn)備好可以及時返回。缺點(diǎn):沒有異步快。
2、異步:剛好和同步相反,也就是在發(fā)出一個功能調(diào)用時,不管沒有沒得到結(jié)果,都繼續(xù)往下執(zhí)行,異步加載至少有一幀的延遲。
異步的優(yōu)點(diǎn):速度快與主線程無關(guān)。缺點(diǎn):調(diào)用比較麻煩,最好的做法是使用回調(diào)。
Unity中Resource常用的資源加載相關(guān)方法
1、同步加載資源 Resources.Load();
(1)讀取文件時的根目錄是 Assets/Resources,所有資源文件都放在該文件夾下,命令中的路徑從 Resources 文件夾里開始寫。
(2)用 / 表示子文件夾。
(3)讀取的文件不要加文件的后綴。
(4)Load 后 <> 中寫入讀取的類型。
2、異步加載資源 Resources.LoadAsync<>();
Resources 異步加載就是內(nèi)部新開一個線程進(jìn)行資源加載,不會造成主線程卡頓。
?注意:異步加載不能馬上得到加載的資源,至少要等一幀。
比較常用的異步加載資源的方式,一個是事件監(jiān)聽實現(xiàn)異步加載,另一個是協(xié)程實現(xiàn)異步加載。兩種方式各有優(yōu)劣,事件監(jiān)聽的方式實現(xiàn)異步加載,優(yōu)勢是寫法簡單,但是有一定局限性,只能在資源加載結(jié)束后進(jìn)行處理,這實際上屬于“線性加載”。協(xié)程的方式實現(xiàn)異步加載,優(yōu)勢是可以在協(xié)程中處理復(fù)雜邏輯(比如,同時加載多個資源、進(jìn)度條更新等),但相應(yīng)的編寫邏輯會更為復(fù)雜,這實際上是類似于“并行加載”。
加載的過渡(加載界面)
不論是場景還是資源,在異步加載的時候,都會存在一個問題,當(dāng)資源在異步加載的過程中,會存在可能資源未加載完成就切換場景的情況,這樣一來就會導(dǎo)致表現(xiàn)效果不好。
Q:資源異步加載的時候怎么解決表現(xiàn)問題?
A:一般來說,最簡單的處理方式就是使用UI遮擋一下(加載界面),再有比較常用的方式,就是其他主頁點(diǎn)擊按鈕后先跳轉(zhuǎn)到加載頁面場景, 同時異步加載要跳轉(zhuǎn)到的場景。
具體實現(xiàn)加載界面的方法很多,網(wǎng)上的文檔也很多,這里就不過多贅述,下面提供幾個相關(guān)鏈接以供參考:
1、http://t.csdn.cn/VTTvA
2、http://t.csdn.cn/wlmwq
3、http://t.csdn.cn/h6Pnn文章來源:http://www.zghlxwxcb.cn/news/detail-760121.html
參考文檔:
1、https://blog.csdn.net/ChinarCSDN/article/details/82914541
2、http://t.csdn.cn/NfaMx
3、http://t.csdn.cn/wqenA文章來源地址http://www.zghlxwxcb.cn/news/detail-760121.html
到了這里,關(guān)于Unity 場景加載和資源加載的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!