- Unity游戲案例開發大全
- 吳亞峰 杜化美 于復興編著
- 1582字
- 2019-01-02 05:50:25
4.4 主菜單界面
前一小節介紹了游戲的整體架構,從本節開始將介紹本案例場景的開發,首先介紹本案例的主菜單場景,該場景在游戲開始時呈現,控制所有界面之間的跳轉,主要開發步驟如下。
4.4.1 基本場景的搭建
(1)創建項目文件夾。首先在電腦的某個磁盤下新建一個空的文件夾“FPSGame”,筆者的項目文件夾創建在“E:\Unit3DWorkspace”文件夾下,如圖4-14所示。

▲圖4-14 創建項目文件夾
(2)創建工程。雙擊桌面的Unity快捷方式打開Unity,選擇“Create New Project”,然后單擊“Browse...”按鈕選擇剛剛創建的“FPSGame”空文件夾,最后單擊“Create”按鈕,如圖4-15所示。

▲圖4-15 創建工程
(3)導入資源。將本游戲所要用到的資源分類整理好,然后將分類好的資源都復制到項目文件夾下的“Assets”文件夾下,如圖4-16所示。然后在Unity界面,單擊“File”→“Save Scene”保存場景,取名為“MenuScene.unity”。

▲圖4-16 導入資源
說明
本游戲中所有的資源文件都已經整理好了,放在“第04章/資源包”文件夾下。讀者可自行將“第04章/資源包”文件夾下的所有文件夾復制到項目文件夾下的“Assets”文件夾下。
(4)導入NGUI資源包。雙擊NGUI安裝包,導入NGUI資源,如圖4-17所示。單擊“import”按鈕,導入完成后重啟Unity,可以看到在工具欄處出現了NGUI按鈕。讀者如果電腦上沒有NGUI資源包,可自行從網上搜索下載。

▲圖4-17 導入NGUI資源包
(5)因為NGUI自帶攝像機,所以需要首先刪除“Main Camera”對象,然后單擊“NGUI”→“Create”→“Panel”按鈕,即可看到在左側窗口創建了一個NGUI Panel,選中“Panel”,將其重命名為“Window_Panel”,如圖4-18所示。

▲圖4-18 創建NGUI Panel
(6)制作圖集。單擊“NGUI”→“Open”→“Atlas Maker”,之后讀者可以在Project視窗中打開Assets/MenuTestures文件夾,用鼠標選中所有圖片,在Atlas Maker窗口中寫上圖集名字“menuAtlas”,單擊Create按鈕。之后可看到在MenuTestures文件夾下面多了三個文件menuAtlas.mat、menuAtlas.png、menuAtlas.prefab,如圖4-19所示。

▲圖4-19 制作圖集
(7)創建NGUI Button。單擊“NGUI”→“Open”→“Widget Wizard”,在Template中選擇“Button”,Atlas選擇剛才創建的menuAtlas圖集,Background選擇想要在按鈕上顯示的圖片,之后單擊“Add To”即可在Window_Panel下面創建一個按鈕,如圖4-20所示。

▲圖4-20 創建NGUI Button
(8)單擊“Add Component”→“NGUI”→“Interaction”→“Button Message”。之后設置在Inspector屬性窗口中將Camera拖動到“Target”中,Trigger選中為“OnClick”,Function Name填上“ExitGame”。編寫腳本“CameraEventMask.cs”并掛載到攝像機上。腳本代碼如下。
代碼位置:見隨書光盤中源代碼/第04章/FPSGame/Assets/Scripts/MenuScripts目錄下的CameraEventMask.cs。
1 using UnityEngine; 2 using System.Collections; 3 public class CameraEventMask : MonoBehaviour { 4 ......//此處省略了其他函數和變量等的聲明,請讀者自行查閱光盤 5 void ExitGame(){ //退出游戲按鈕的回調方法 6 Application.Quit(); //退出應用 7 }}
說明
當單擊“Exit_Btn”按鈕的時候,此按鈕會向Target指定的對象發送消息,該消息將尋找所有掛載到Target對象上的Scripts腳本中的Function Name函數,并執行此函數。
(9)其他按鈕也是通過這樣的方式創建的,當用戶單擊某個按鈕的時候,此按鈕會發送消息,然后調用相應的函數,完成指定的功能。接下來介紹一下幾個搭建NGUI其他效果的方法。
4.4.2 其他常用界面效果的實現
(1)關閉窗口效果的實現。為不同的NGUI控件設置不同的LayerMask,然后當單擊關閉窗口的時候,設置攝像機只渲染游戲需要的Layer,這樣可以達到顯示和隱藏NGUI控件的效果。在CameraEventMask.cs腳本中,大家可看到這樣的函數。
代碼位置:見隨書光盤中源代碼/第04章/FPSGame/Assets/Scripts/MenuScripts目錄下的CameraEventMask.cs。
1 using UnityEngine; 2 using System.Collections; 3 public class CameraEventMask : MonoBehaviour { 4 ......//此處省略了其他函數和變量等的聲明,請讀者自行查閱光盤 5 public LayerMask mainMask; //主菜單界面mask 6 public LayerMask otherMask; //其他界面mask 7 void SetOtherMask(){ 8 uiCamera.eventReceiverMask = otherMask.value; //設置攝像機的mask為otherMask 9 } 10 void SetMainMask(){ 11 uiCamera.eventReceiverMask = mainMask.value; //設置攝像機的mask為mainMask 12 }
提示
給NGUI控件設置Layer名稱之后,一定要將Camera的Culling Mask(如圖4-21所示)和UICamera腳本中的Event Mask(如圖4-22所示)設置為相應的Layer層。攝像機默認Culling Mask層為default,即默認對default層進行渲染,因此如果不進行設置的話,屏幕上將什么也看不到。

▲圖4-21 設置Culling Mask

▲圖4-22 設置Event Mask
(2)界面圖片的變化。本游戲中,界面圖片的變化是通過設置NGUI控件的隱藏和顯示實現此效果的。以關閉聲音為例,當單擊按鈕的時候,聲音按鈕將會發送消息調用下面的函數以實現聲音開啟和關閉按鈕圖片的更換。腳本代碼如下。
代碼位置:見隨書光盤中源代碼/第04章/FPSGame/Assets/Scripts/MenuScripts目錄下的CameraEventMask.cs。
1 ......//此處省略了其他函數和變量等的聲明,請讀者自行查閱光盤 2 void SoundOn_Btn() { //開槍聲音按鈕的回調方法 3 PlayerPrefs.SetInt("sound",0); //存儲聲音狀態 4 audioListener.enabled = false; //禁用audioListener 5 soundOffBtn.SetActive(true); //聲音關閉按鈕的顯示 6 soundOnBtn.SetActive(false); //聲音開啟按鈕的隱藏 7 }
說明
通過調用精靈自身的SetActive方法來實現對相應精靈的隱藏和顯示。
(3)滑動條的實現。在設置面板中,利用滑動條控制敵人血量和游戲時間。制作滑動條需要先創建一個NGUI Slider控件,然后添加NGUI自帶的腳本Slider,然后在屬性窗口中,分別為各個屬性賦值。圖4-23所示給出的是血條屬性的設置窗口。

▲圖4-23 設置滑動條屬性
(4)編寫“SliderTest.cs”腳本,然后附加到上面Notify屬性指定的LabelObj對象上,則當移動滑動條的時候,會執行SliderTest.OnSliderChange方法,用PlayerPrefs達到動態存儲變量值的效果。腳本代碼如下。
代碼位置:見隨書光盤中源代碼/第04章/FPSGame/Assets/Scripts/MenuScripts目錄下的SliderTest.cs。
1 using UnityEngine; 2 using System.Collections; 3 public class SliderTest : MonoBehaviour { 4 ......//此處省略了其他函數和變量等的聲明,請讀者自行查閱光盤 5 public void OnSliderChange() { //當Slider的Value改變時的回調方法 6 float value = Slider.value; //獲取Slider的值 7 switch(curWidge) { 8 case Widget.time: //滑動時間軸 9 PlayerPrefs.SetInt(curWidge.ToString(), (int)(value * 300) + 300);//存儲時間 10 Lable.text = (PlayerPrefs.GetInt(curWidge.ToString())).ToString();//顯示 11 break; 12 case Widget.enemyblood: //滑動血條軸 13 PlayerPrefs.SetInt(curWidge.ToString(), (int)(value * 100) + 100);//存儲血量 14 Lable.text = (PlayerPrefs.GetInt(curWidge.ToString())).ToString();//顯示 15 break; 16 }}
說明
通過Slider.value來得到當前滑動條的值,再根據curWidge所指示的精靈的不同,來判斷當前操作的是滑動時間軸還是滑動血條軸,滑動的時候及時存儲滑動條的值,然后動態地改變標簽上值的顯示。
(5)動態加載界面滾動條的制作。單擊“開始”按鈕,將會進入異步加載游戲場景的界面,一個綠色的滾動條在屏幕上水平滾動。做到這樣的效果其實很簡單,只需要動態改變屏幕上文字和精靈(滾動條)的位置即可。
代碼位置:見隨書光盤中源代碼/第04章/FPSGame/Assets/Scripts/MenuScripts目錄下的LoadScene.cs。
1 using UnityEngine; 2 using System.Collections; 3 public class LoadScene : MonoBehaviour { 4 ......//此腳本省略了部分變量和函數,如需查看完整代碼,請參考光盤。 5 public GameObject showObj; //需要顯示的對象 6 public GameObject hideObj; //需要隱藏的對象 7 AsyncOperation asyncOperation; //異步對象 8 private UILabel loadingLabel; //顯示“加載中”的Label組件 9 public Transform progressBar; 10 private string[] loadTxt = { "加載中。 ", 11 "加載中。。", "加載中。。。" }; //加載場景時顯示的字符串 12 private float count = 0; //計數器 13 private float currentTime; //記錄當前時間 14 void LoadGameScene() { 15 hideObj.SetActive(false); //隱藏對象 16 showObj.SetActive(true); //顯示對象 17 StartCoroutine(LoadingAnimation()); //啟動加載動畫的協程方法 18 } 19 IEnumerator LoadingAnimation() { 20 yield return new WaitForSeconds(0.1f); //等待0.1秒 21 asyncOperation = Application.LoadLevelAsync("GameScene"); 22 while (!asyncOperation.isDone) { //加載未完成 23 int index = (int)count % 3; //對count取值 24 loadingLabel.text = loadTxt[index]; //更新UILabel 25 count += Time.deltaTime * 3; //計數器自加 26 Vector3 locationPosition = progressBar.localPosition;//獲取進度條父節點 27 locationPosition.x += Time.deltaTime * 500; //改變進度條位置 28 locationPosition.x=(locationPosition.x>200)?-200:locationPosition.x; 29 yield return new WaitForSeconds(0.01f); //等待0.01秒 30 }}}
第14行~第18行先使界面中需要隱藏的界面隱藏,接著使界面需要顯示的元素顯示,然后使用StartCoroutine方法異步調用LoadingAnimation方法,這樣可以實現在不至于影響前臺界面元素顯示的情況下,后臺動態加載主游戲場景資源的效果。
第19行~第29行用Application.LoadLevelAsync異步加載主游戲界面未完成的情況下,每隔0.01秒便重新給加載文字和加載滾動條的位置賦值,從而使其達到動態更新Label文字和滾動條位置的效果。