您好,登錄后才能下訂單哦!
異步任務(wù)相信大家應(yīng)該不會陌生,那么下面介紹一下Unity中的一些異步任務(wù)。在同步加載游戲場景的時候通常會使用方法 Application.LoadLevel(“yourScene”); 這句代碼執(zhí)行完畢后程序會干什么呢??如下圖所示,這是我隨便找了一個游戲場景, 在Hierarchy視圖中我們可以看到該場景中“天生”的所有游戲?qū)ο?。天生的意思就是運(yùn)行程序前該場景中就已經(jīng)存在的所有游戲?qū)ο?。然后這些對象就會在執(zhí)行完Application.LoadLevel(“yourScene”);方法后加載至內(nèi)存當(dāng)中。如果該場景中的游戲?qū)ο筮^多那么瞬間將會出現(xiàn)卡一下的情況,因?yàn)?span >LoadLevel()方法是同步進(jìn)行的。MOMO把這種加載起個名字叫A形式加載。
下面我說說“后天“加載的游戲?qū)ο?。意思是這些游戲?qū)ο笫峭ㄟ^腳本動態(tài)的創(chuàng)建出來的。比如常用方法 :
[代碼]GameObject Obj = (GameObject)Instantiate(prefab); 這句代碼執(zhí)行完畢后同樣會在Hierarchy視圖中添加對應(yīng)的游戲?qū)ο?。MOMO把這種加載起個名字叫B形式加載。
下面我們學(xué)習(xí)異步加載游戲場景,異步異步顧名思義就是不影響當(dāng)前游戲場景的前提下加載新場景。通常異步加載的方式分為兩種:第一種是異步加載新游戲場景,當(dāng)新場景加載完成后進(jìn)入新場景并且銷毀之前的場景。第二種:同樣異步加載新場景,新場景加載完畢后,保留舊場景的游戲?qū)ο蟛⑶疫M(jìn)入新場景。 這里加載的內(nèi)容就是上面提到的A形式加載。然后B形式加載不會記入這里的加載。 第一種異步加載游戲場景對應(yīng)的方法是:
[代碼]:Application.LoadLevelAsync("yourScene"); 這兩種方法加載的方式完全一樣。異步加載其實(shí)重要還是應(yīng)用于游戲LOADING界面,畢竟LOADING如果采用同步的機(jī)制會影響用戶體驗(yàn),說到這里MOMO告訴大家如何在Unity中制作游戲進(jìn)度條。我們應(yīng)當(dāng)在Unity中創(chuàng)建一個專門用于讀取進(jìn)度的場景,假設(shè)A場景到C場景,我們應(yīng)當(dāng)讓A場景先到讀取進(jìn)度的場景B場景,當(dāng)異步任務(wù)完成后在進(jìn)入C場景。 A – 》B -》 C ,在B場景中繪制游戲進(jìn)度條或讀取動畫。因?yàn)锽場景僅僅是個顯示LOADING動畫的場景,所以讀取該場景是瞬間就完成的。 程序在切換場景時應(yīng)當(dāng)有一個全全局的靜態(tài)變量來記錄簡要讀取的場景名稱。這里簡單的寫一下。
[代碼]:using UnityEngine; using System.Collections; public class Globe { //在這里記錄當(dāng)前切換場景的名稱 public static string loadName; }
[代碼]://記錄LOADING場景中需要讀取的C場景名稱 Globe.loadName = "C"; //先進(jìn)入B場景 Application.LoadLevel ("B");
[代碼]:using UnityEngine; using System.Collections; public class Loading : MonoBehaviour { private float fps = 10.0f; private float time; //一組動畫的貼圖,在編輯器中賦值。 public Texture2D[] animations; private int nowFram; //異步對象 AsyncOperation async; //讀取場景的進(jìn)度,它的取值范圍在0 - 1 之間。 int progress = 0; void Start() { //在這里開啟一個異步任務(wù), //進(jìn)入loadScene方法。 StartCoroutine(loadScene()); } //注意這里返回值一定是 IEnumerator IEnumerator loadScene() { //異步讀取場景。 //Globe.loadName 就是A場景中需要讀取的C場景名稱。 async = Application.LoadLevelAsync(Globe.loadName); //讀取完畢后返回, 系統(tǒng)會自動進(jìn)入C場景 yield return async; } void OnGUI() { //因?yàn)樵诋惒阶x取場景, //所以這里我們可以刷新UI DrawAnimation(animations); } void Update() { //在這里計(jì)算讀取的進(jìn)度, //progress 的取值范圍在0.1 - 1之間, 但是它不會等于1 //也就是說progress可能是0.9的時候就直接進(jìn)入新場景了 //所以在寫進(jìn)度條的時候需要注意一下。 //為了計(jì)算百分比 所以直接乘以100即可 progress = (int)(async.progress *100); //有了讀取進(jìn)度的數(shù)值,大家可以自行制作進(jìn)度條啦。 Debug.Log("xuanyusong" +progress); } //這是一個簡單繪制2D動畫的方法,沒什么好說的。 void DrawAnimation(Texture2D[] tex) { time += Time.deltaTime; if(time >= 1.0 / fps){ nowFram++; time = 0; if(nowFram >= tex.Length) { nowFram = 0; } } GUI.DrawTexture(new Rect( 100,100,40,60) ,tex[nowFram] ); //在這里顯示讀取的進(jìn)度。 GUI.Label(new Rect( 100,180,300,60), "lOADING!!!!!" + progress); } } OK 下面我們繼續(xù)學(xué)習(xí)在游戲場景中加載對象,文章的開始MOMO已經(jīng)告訴大家,游戲場景中Hierarchy視圖中的所有的對象在切換場景的時候都會加載。其實(shí)有一種方法可以讓某些游戲?qū)ο蟛粫患虞d,如下圖所示,首先在Hierarchy視圖中選擇一個游戲?qū)ο?,在右?cè)監(jiān)測面板視圖中我們可以看到一個 “小對勾”默認(rèn)情況下是勾選狀態(tài),說明該游戲?qū)ο筇幱诩せ顮顟B(tài),如果點(diǎn)掉的話該對象將被隱藏。這個小功能在開發(fā)中其實(shí)用處非常大,請大家務(wù)必記住哈。
此時此刻大家相像一個游戲場景,默認(rèn)進(jìn)入的時候是沒有任何游戲?qū)ο蟮模缓筮\(yùn)行游戲時開啟一個異步任務(wù)將它們一個一個的加載顯示出來,這種方式適合異步的加載一個比較大的游戲場景。 Test.cs 把它掛在攝像機(jī)對象中。
[代碼]:using UnityEngine; using System.Collections; public class Test : MonoBehaviour { //這里是需要加載激活的游戲?qū)ο? public GameObject [] Objects; //當(dāng)前加載的進(jìn)度 int load_index =0; void Start () { //開啟一個異步任務(wù),加載模型。 StartCoroutine(loadObject()); } IEnumerator loadObject() { //便利所有游戲?qū)ο? foreach(GameObject obj in Objects) { //激活游戲?qū)ο? obj.active = true; //記錄當(dāng)前加載的對象 load_index ++; //這里可以理解為通知主線程刷新UI yield return 0; } //全部便利完畢返回 yield return 0; } void OnGUI () { //顯示加載的進(jìn)度 GUILayout.Box("當(dāng)前加載的對象ID是: " + load_index); } } 如下圖所示,我們把需要加載的游戲?qū)ο笠詳?shù)組的形式放在Objects數(shù)組中,因?yàn)檫@些對象屬于未激活狀態(tài),所以不能通過Find 等方法在腳步那種中找到他們。講到這里我們在說說 編輯器賦值與代碼中賦值的區(qū)別,編輯器中賦值所消耗的時間都會記在loadlevel ()讀取場景中。而代碼中使用Resource.load()這類方法所消耗的時間會記在腳本中。開發(fā)中還得自行的把握一下把loading加在那里。
當(dāng)然我們還可以使用Instantiate(prefab);方法來動態(tài)的創(chuàng)建游戲?qū)ο蟆?/span> Main.cs 把它掛在攝像機(jī)中。
[代碼]:using UnityEngine; using System.Collections; public class Main : MonoBehaviour { public int count; //在編輯器中預(yù)設(shè)一個游戲?qū)ο? public GameObject prefab; void Start () { StartCoroutine(loaditem()); } void OnGUI() { GUILayout.Box("游戲?qū)ο笠呀?jīng)加載到 : " + count); } IEnumerator loaditem() { //開始加載游戲?qū)ο? for(int i =0; i< 1000; i++) { Instantiate(prefab); count = i; //可以理解為刷新UI,顯示新加載的游戲?qū)ο? yield return 0; } //結(jié)束 yield return 0; } } |
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。