2018.03.08新增:
這陣子以來,我的部落格每天最多人看的就是這篇文章,而在Google搜尋「Unity 場景切換」、「Unity 場景轉換」等關鍵字時,第一個出現的結果也是這裡XD,非常感謝大家的厚愛,也很高興能產出對大家有幫助的內容!不過現在回頭看當初寫的東西,還是有一些不夠完善的地方,且讓我做個遲來的補強。
※中肯辭典
(註:有別於官方文件上的嚴謹說明,在此以工程師的角度來簡短說明此元素的特質與使用時機。)
介紹如何在Unity實作「Replay」、「進入商店」等遊戲中常見的場景轉換機制。
在知名遊戲”Angry Bird”中,每當你通過關卡,就會出現這三個按鈕:「回到首頁」、「再玩一次」、「到下一關」,你有沒有想過這種場景的轉換是怎麼實作的呢?
廢話不多說,在Unity裡,若我們想要使用這樣的功能,就必須介紹一個關鍵的指令:
Application.LoadLevel(Scene序號 ex. 0、1 …)
or
Application.LoadLevel(“Scene名稱”)
大家應該都有發現,每當你開啟新的Project,編排了一些物件、撰寫了一些程式碼後,當你想儲存當前進度時,Unity會要求你先為這個”Scene”存檔。
Scene就是一個個畫面的感覺,「大廳」是一個Scene、「商店」可能是另一個Scene、每一個關卡也各自是一個Scene。因此,一款遊戲並不是同一個檔案從頭做到尾,而是很多個Scene檔(副檔名為.unity)拼裝而成的。所以,我們要做的就是把場景轉換的線路接好。
首先,我們到Unity上方的書籤列點選File -> Build Settings。
按下中間偏右的”Add Open Scenes”就可以把當前這個叫做”Stage1″的場景加入建置設定中,
已在清單中的Scene就會獲得一個自己的編號顯示在右邊。
為了測試場景切換,我們可以回到編輯介面中,將原有的場景佈置做一點更動,然後按下
File -> Save Scene as…來儲存第二個Scene,取名叫做”Stage2″。
如此一來,我們就有場景0和場景1了。透過點擊拖曳清單裡的項目,我們可以任意交換他們的順序。
接下來,我們可以在任意一個場上的物件裡加入以下的code。
一般都會將場景轉換放在「按鈕被觸發」、「分數達到過關目標」等時間點的,但在這裡為了直接測試效果,我們一樣利用鍵盤來控制。按下M就能在兩個關卡間往返。
Application.LoadLevel(0)代表前往第0個場景,在這裡也就是“Stage1”。
●也可以寫成Application.LoadLevel(“Stage1”),不僅可讀性更高,也不會因為不小心打亂場景序號而出問題。
而Application.loadedLevel回傳的值是一個int,代表的是當前的場景序號。
所以Line 16 撰寫的 Application.LoadLevel(Application.loadedLevel)就是把當前的場景重新載入的意思,所有的物件都會回到原位。
而Line 20 ~ 24 則是做一個直觀的切換,如果現在是場景0,按下按鍵後就切到場景1,以此類推。
在這裡我用小雞跟箱子來做出兩個箱子的區別
這個是Stage1
而這個是Stage2
如果上述的程序都有成功,就會有像影片這樣的效果:按下R時會Replay,按下M時則會切換關卡。
實用指令(2018.03.08新增)
離開此程式: Application.Quit()
推薦使用方式:若是PC遊戲,可以在Update()裡面撰寫:
if(Input.GetKeyDown(KeyCode.Escape))
Application.Quit();
若是手機遊戲,則可以將Application.Quit()放入一個public函數,然後搭配按鈕來觸發使用。
新版API (2018.03.08新增)
在當今版本的Unity中,Application.LoadLevel(…)系列依舊是一套可以使用的指令,但是撰寫時系統會推薦你使用SceneManager.LoadScene,如下圖:
那麼,SceneManager要怎麼使用呢?
步驟1:引用UnityEngine.SceneManagement這個Library
這是非常重要的一個步驟,若是忘記引用,系統就完全看不懂這些指令了!因此,在使用這些指令前,要先撰寫using UnityEngine.SceneManagement;(如下圖第4行)
步驟2:使用SceneManager.LoadScene(Scene序號)或SceneManager.LoadScene(“Scene名稱”)
到這裡應該就非常熟悉了!用法和Application.LoadLevel(…)無異,但是Unity基於效能、底層架構上的考量,決定改推崇這一套UnityEngine.SceneManagement的API,大家能養成習慣使用這個做法的話絕對是有益無害的!延續上面的例子,下圖18~22行展示了4行作用一模一樣的程式碼供大家參考。
謝謝你的教學 很有用 感謝~
LikeLiked by 1 person
感謝,有你真好
LikeLiked by 1 person
謝謝你,幫助良多
LikeLiked by 1 person
我無法載入場景可以幫忙解惑嗎?
LikeLike
file:///C:/Users/USER/Pictures/%E8%A8%BB%E8%A7%A3%202020-05-11%20190404.png
LikeLike
Hi
你要把圖片上傳到公共空間我才看得到喔
這是你電腦的本地路徑XD
LikeLike
求救
我用碰撞重啟,可程式沒反應
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag == “Player”)
{
SceneManager.LoadScene(0);
}
}
LikeLike
有無
using unityEngine.scenemanagement;
gameobject ” is trigger” 有無enable
player有無tag player
最後loadscene(0)是否存在
thanks
LikeLike