1.一個(gè)游戲是由很多的場(chǎng)景組成的,比如游戲的開始頁(yè)面,戰(zhàn)斗場(chǎng)景,商店頁(yè)面...等等,這些都是一個(gè)個(gè)游戲場(chǎng)景
或者比如說:一進(jìn)入游戲,你一開始來到的是新手村這個(gè)場(chǎng)景,出了新手村后來到的就是荒野場(chǎng)景,過來荒野場(chǎng)景后來到的就是大城市場(chǎng)景.....
?一個(gè)游戲是由很多的場(chǎng)景組成的,而每個(gè)場(chǎng)景又由很多的游戲物體組成,而每個(gè)游戲物體又由很多的腳本組件組成
?之前我們一直是在默認(rèn)的場(chǎng)景中添加游戲物體,其實(shí)我們也可以添加新的游戲場(chǎng)景,并通過游戲代碼加載新的場(chǎng)景
這個(gè)就是一開始Unity自動(dòng)為我們創(chuàng)建的示例場(chǎng)景(默認(rèn)場(chǎng)景)?
1.新場(chǎng)景的創(chuàng)建:
首先我們要做的是在Assets文件夾下的scene文件夾中創(chuàng)建一個(gè)scene(場(chǎng)景)文件,創(chuàng)建好后再將這個(gè)場(chǎng)景文件拖拽到Hirarchy層級(jí)中,這樣一個(gè)新的場(chǎng)景就創(chuàng)建好啦
2.我們的期望是:能夠通過代碼使得游戲程序自動(dòng)從場(chǎng)景A加載到場(chǎng)景B中
3.實(shí)現(xiàn)方法:假定A是示例場(chǎng)景,B是我們創(chuàng)建的新場(chǎng)景
首先點(diǎn)開File中的Build Setting(生成設(shè)置)
?
這個(gè)是指構(gòu)建中的場(chǎng)景?
如果我們當(dāng)前創(chuàng)建的場(chǎng)景不是廢棄場(chǎng)景是有用的,我們就要把這個(gè)場(chǎng)景從HIrarchy中選中并拖到這個(gè)Scenes in Build(構(gòu)建中的場(chǎng)景)中
?拖進(jìn)去后就會(huì)自動(dòng)給里面的場(chǎng)景進(jìn)行編號(hào)
脫進(jìn)去之后我們就可以進(jìn)行場(chǎng)景跳轉(zhuǎn)啦?。?!
首先我們可以在任意一個(gè)腳本中寫場(chǎng)景跳轉(zhuǎn)代碼,所以我們隨便在一個(gè)游戲物體的腳本中進(jìn)行編寫
注意只有被我們加入到了scene in bulid 中的場(chǎng)景才能夠在腳本中被調(diào)用和訪問
首先和場(chǎng)景有關(guān)的是下面這兩個(gè)類
?在使用這兩個(gè)類的時(shí)候我們需要引入一個(gè)命名空間
?引入后如果我們想在一開始就跳轉(zhuǎn)到某個(gè)場(chǎng)景(注意這個(gè)場(chǎng)景必須已經(jīng)被放在了構(gòu)建中的場(chǎng)景的那個(gè)框框中了),我們可以在start方法中通過SceneManager類調(diào)用靜態(tài)方法 LoadScene,括號(hào)中傳的參數(shù)可以是我們要加載的場(chǎng)景的場(chǎng)景名,也可以是要加載的場(chǎng)景的場(chǎng)景編號(hào)
?
輸入名稱的時(shí)候要用字符串!
我們?nèi)绾潍@取當(dāng)前激活的場(chǎng)景呢?
?1.用Scene場(chǎng)景類創(chuàng)建一個(gè)場(chǎng)景對(duì)象,然后通過場(chǎng)景管理類調(diào)用靜態(tài)方法獲得當(dāng)前場(chǎng)景并賦值給我們創(chuàng)建的場(chǎng)景對(duì)象
??向上面這樣調(diào)用可以獲取這個(gè)場(chǎng)景對(duì)象指向的場(chǎng)景的場(chǎng)景名
如果被加載,這個(gè)屬性的值是ture,否則為false?
上面這個(gè)路徑指的是對(duì)應(yīng)場(chǎng)景的場(chǎng)景文件的文件路徑
?
獲取當(dāng)前場(chǎng)景在build in scene中的索引?
?這個(gè)方法返回的是一個(gè)數(shù)組,這個(gè)數(shù)組的類型是Object,然后這個(gè)方法的作用是獲取調(diào)用它的場(chǎng)景對(duì)象所指向的場(chǎng)景中的所有游戲物體?
對(duì)于場(chǎng)景管理類而言
這個(gè)sceneCount是當(dāng)前加載的場(chǎng)景的數(shù)量 --- 場(chǎng)景并不是同一時(shí)間只能存在一個(gè),它是能多個(gè)疊加起來的
括號(hào)內(nèi)的參數(shù)是我們給新場(chǎng)景的命名 (ps:創(chuàng)建了一個(gè)新場(chǎng)景后當(dāng)然也需要我們創(chuàng)建一個(gè)場(chǎng)景對(duì)象來接收這個(gè)新場(chǎng)景啦)
參數(shù)是我們要卸載的場(chǎng)景的場(chǎng)景名 --- 卸載后這個(gè)場(chǎng)景和對(duì)應(yīng)的場(chǎng)景文件都會(huì)被刪除
加載場(chǎng)景再拓展:
這個(gè)函數(shù)還有第二個(gè)參數(shù),第二個(gè)參數(shù)是枚舉變量,對(duì)應(yīng)的枚舉類型是LoadSceneMode,這個(gè)枚舉類型中只有兩個(gè)值
?(ps:枚舉變量只能被枚舉類型中的成員賦值,訪問枚舉類型中的成員的方法是 枚舉類型名 + 點(diǎn)操作符 + 要訪問的枚舉成員名)
1.當(dāng)我們給第二個(gè)參數(shù)賦值LoadSceneMode.Single的時(shí)候,這個(gè)加載場(chǎng)景方法就會(huì)使得當(dāng)前游戲中有且只有我們給定的場(chǎng)景(第一個(gè)參數(shù) -- 要加載的場(chǎng)景名)會(huì)被加載
2.當(dāng)我們給第二個(gè)參數(shù)賦值LoadSceneMode.Additive(添加劑)的時(shí)候,會(huì)讓我們給定的場(chǎng)景加載,并讓這個(gè)場(chǎng)景與當(dāng)前已經(jīng)加載好的場(chǎng)景同時(shí)顯示
這個(gè)LoadScene場(chǎng)景加載方法其實(shí)有一個(gè)問題,就是當(dāng)加載的場(chǎng)景很大很復(fù)雜的時(shí)候,加載速度會(huì)變慢,而且加載時(shí)會(huì)出現(xiàn)卡頓
為了解決這個(gè)問題,人們提供一種新的方法 --- LoadSceneAsync() --- 異步場(chǎng)景加載法
(Async --? 異步)
通過SceneManager調(diào)用的LoadSceneAsync() --- 異步場(chǎng)景加載法
以及如何設(shè)置加載進(jìn)度條
1.異步與同步的區(qū)別:正常執(zhí)行代碼就像下面一樣,從上到下一根筋執(zhí)行完
?
?假設(shè)是上面這樣一行行代碼執(zhí)行,前三行代碼計(jì)算機(jī)都能很快的執(zhí)行完畢,但是到了到了后三行代碼時(shí)計(jì)算機(jī)執(zhí)行代碼的速度將顯著下降,我們稱這種為代碼阻滯現(xiàn)象
造成這一現(xiàn)象的原因是后三行代碼需要的計(jì)算時(shí)間和操作時(shí)間與其它代碼相比明顯長(zhǎng)了很多
代碼阻滯現(xiàn)象會(huì)導(dǎo)致整個(gè)程序在這幾行代碼處直接卡住,后面的一些能夠快速執(zhí)行的代碼也無法執(zhí)行了,整個(gè)游戲就會(huì)出現(xiàn)卡頓
為了解決這個(gè)問題人們開發(fā)出了異步編程(多線程編程)
?當(dāng)有耗時(shí)操作的時(shí)候我們就多開一個(gè)線程,把耗時(shí)操作交給這個(gè)線程執(zhí)行,然后主線程繼續(xù)執(zhí)行耗時(shí)操作后面的代碼,這樣就能在執(zhí)行耗時(shí)操作的時(shí)候異步執(zhí)行其它的代碼了。
執(zhí)行耗時(shí)操作的線程在執(zhí)行完畢后將獲得的數(shù)據(jù)直接傳回給主線程就OK了?
在C#中上面這個(gè)異步操作就是通過多線程實(shí)現(xiàn)的,而在Unity中則是通過協(xié)程實(shí)現(xiàn)的
那么我們?nèi)绾卧赨nity中創(chuàng)建協(xié)程呢?
1.一個(gè)協(xié)程最好只能夠處理一個(gè)方法,所以我們首先創(chuàng)建一個(gè)在協(xié)程中執(zhí)行的方法:
?注意這個(gè)方法的返回值一定是 IEnumerator ,?在這個(gè)方法中寫我們想要實(shí)現(xiàn)的功能,到時(shí)候在寫協(xié)程中就會(huì)調(diào)用這個(gè)方法并執(zhí)行方法中的代碼
以異步場(chǎng)景加載為例:注意這個(gè)LoadSceneAsync()方法只能在協(xié)程中通過SceneManager調(diào)用,然后這個(gè)方法有返回值,返回值的類型是 AsyncOperation,我們要?jiǎng)?chuàng)建一個(gè)對(duì)應(yīng)的對(duì)象來接收這個(gè)返回值
接收到這個(gè)返回值后,在協(xié)程方法中用 yield(屈服) return 返回
2.協(xié)程方法寫完之后我們要在MonoBehaviour的方法中開啟這個(gè)協(xié)程:用下面這行代碼開啟協(xié)程,括號(hào)里的參數(shù)是我們要在協(xié)程中執(zhí)行的協(xié)程方法
?協(xié)程執(zhí)行完畢后會(huì)自動(dòng)關(guān)閉,不需要我們手動(dòng)關(guān)閉
?
3.如果已經(jīng)實(shí)現(xiàn)了協(xié)程異步加載場(chǎng)景了,我們?cè)撊绾螘r(shí)時(shí)刻刻都獲取到這個(gè)協(xié)程中的場(chǎng)景加載進(jìn)度呢?
在Updata方法中寫這行代碼就行:
1.異步場(chǎng)景加載的進(jìn)度可以通過承接異步場(chǎng)景加載方法返回值的場(chǎng)景對(duì)象調(diào)用progress屬性獲得
2.Updata方法每一幀都會(huì)被調(diào)用,所在Updata中輸出加載進(jìn)度我們就可以每一幀都獲取到當(dāng)前場(chǎng)景的加載進(jìn)度了
3.場(chǎng)景的加載進(jìn)度,即progress屬性的取值范圍是0到0.9,當(dāng)?shù)竭_(dá)0.9的時(shí)候場(chǎng)景加載完畢
4.上面這種方法在加載完場(chǎng)景后就會(huì)自動(dòng)跳轉(zhuǎn)到加載好的場(chǎng)景,那有沒有辦法讓我們手動(dòng)去選擇是否跳轉(zhuǎn)呢?
答案是有的:文章來源:http://www.zghlxwxcb.cn/news/detail-444812.html
通過承接把異步場(chǎng)景加載法加載好后的場(chǎng)景的場(chǎng)景對(duì)象調(diào)用allowSceneActivation屬性,這個(gè)屬性的默認(rèn)值是true,即允許自動(dòng)跳轉(zhuǎn),我們可以把這個(gè)默認(rèn)值手動(dòng)改為false,這樣就不會(huì)自動(dòng)跳轉(zhuǎn)了,然后我們可以設(shè)置按鈕讓玩家控制這個(gè)屬性的true/false文章來源地址http://www.zghlxwxcb.cn/news/detail-444812.html
到了這里,關(guān)于Unity --- 場(chǎng)景/場(chǎng)景管理類 與 異步場(chǎng)景加載法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!