C#開發Unity遊戲教程迴圈遍歷做出判斷及Unity遊戲示例

大學霸發表於2015-07-10

C#開發Unity遊戲教程迴圈遍歷做出判斷及Unity遊戲示例

Unity中迴圈遍歷每個資料,並做出判斷

很多時候,遊戲在玩家做出判斷以後,遊戲程式會遍歷玩家身上大量的所需資料,然後做出判斷,即首先判定玩家是否有許可權做出這種選擇,然後才決定是否為玩家執行此選擇。例如,《仙劍奇俠傳》這款遊戲,進入劇情“荷葉迷宮時”,會要求玩家擊碎迷宮裡的5尊雕塑,如圖5-12所示。但是擊碎的前提是,玩家身上必須攜帶有“錘子”。也就是說系統會遍歷玩家身上所有的資源,如果有錘子才能擊碎雕塑。


5-12  《仙劍奇俠傳》,荷葉迷宮全圖

判斷是否有指定的資料,可以使用本章前面所學的if語句來解決。但是目前還存在兩個其它的問題:

  • q  如何在指令碼中儲存和引用這大量的資料,如果使用變數,顯然要宣告大量的變數,這樣做顯然不妥;

  • q  如果已經得到了大量的資料,該使用什麼方式去一一判別呢,難道說要使用大量if語句,去對資料一一判別,這樣做顯然也不妥;

C#倒是提供了兩種機制,可以很有效的解決以上的兩個問題,本節會逐個詳解介紹它們。

Unity中大量資料的儲存與引用

C#指定了3種儲存與引用大量資料的方法,分別是:陣列、列表和字典。本小節會使用簡單的小示例依次講解它們,至於大的遊戲示例,會在本章講解完所有的知識點以後給出。

1.陣列

陣列可以儲存大量同型別的資料,它的宣告格式為:

  • 資料型別[ ] 陣列名;

  • q  所有常用的資料型別,在本書第3章中已經使用表格列出了;

  • q  資料型別後面跟著的是一對中括號“[ ]”;

  • q  陣列名與變數名一樣,必須遵循C#的命名規定;

例如,下面的程式碼語句宣告,並且初始化了陣列:

  • int[] myIntArray = {1,3,5,7,9};

讀者應該可以從這條語句中看出,宣告的是int型別的陣列,陣列名為myIntArray,儲存了5int型別的資料,分別是13579

引用陣列中指定資料的格式為:

  • 陣列名[下標];

  • q  下標是從0開始的整數,當下標為0時,表示引用的是陣列中的第1個資料;若為3時,表示引用的是陣列中的第4個資料;其它資料的引用方式依此類推;

為指令碼MyScript新增下面的程式碼:

  • 01     using UnityEngine;

  • 02     using System.Collections;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              private int[] myIntArray = {1,3,5,7,9};                //陣列的宣告和初始化

  • 07              void Start()

  • 08              {

  • 09                        Debug.Log ("陣列中的第1個資料是:" + myIntArray[0]);          //陣列資料的引用

  • 10                        Debug.Log ("陣列中的第5個資料是:" + myIntArray[4]);          //陣列資料的引用

  • 11              }

  • 12     }

執行遊戲,在Console檢視裡檢視指令碼輸出的資訊,如圖5-13所示。


5-13  使用陣列的示例

2.列表

列表與陣列類似,同樣用於儲存大量同類的資料。但是似乎C#開發人員相對於陣列,更偏愛列表一些。除非逼不得已,否則他們不會從列表和陣列二者間選擇後者,基本上是因為下面的幾個原因:

  • q  陣列在被宣告瞭以後,儲存的資料的個數就是固定的了,而列表則比較靈活,沒有這方面的限制,如果開發者需要,它還可以儲存更多的資料;

  • q  列表可以更方便的增加和刪除儲存於其中的資料;

這次作者打算在演示一個示例以後,在具體介紹列表的宣告和使用等等。為指令碼MyScript新增下面的程式碼:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;                                                                 //必須新增的語句

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              private List myIntList = new List();                                       //宣告列表

  • 07              void Start()

  • 08              {

  • 09                       myIntList.Add (1);                                                                               //新增資料到列表

  • 10                       myIntList.Add (3);

  • 11                       myIntList.Add (5);

  • 12                        Debug.Log ("列表中總共儲存的資料個數是:" + myIntList.Count);

  • 13                        Debug.Log ("列表中第1個資料是:" + myIntList[0]);                 //引用列表中的資料

  • 14                        Debug.Log ("列表中第3個資料是:" + myIntList[2]);

  • 15    

  • 16                       myIntList.Add (7);

  • 17                        Debug.Log ("列表中第4個資料是:" + myIntList[3]);

  • 18              }

  • 19     }

執行遊戲,在Console檢視裡檢視指令碼輸出的資訊,如圖5-14所示。


5-14  使用列表的示例

  • q  指令碼02行的語句,與以往不同,需要讀者主動修改成這個樣子,此語句是在指令碼中使用列表的前提,順便提及新建指令碼時,語句是下面的這個樣子:

  • 02     using System.Collections;

  • q  指令碼06行的語句如下:

  • 06              private List myIntList = new List();                                       //宣告列表

此語句宣告瞭列表,其名為myIntList,目前還沒有儲存任何資料;和陣列一樣,宣告列表時也需要指定指定列表中可以儲存的資料的型別,本示例中儲存的型別是int

  • q  指令碼09~11行編寫了類似於下面的語句:

  • 09                       myIntList.Add (1);                                                                               //新增資料到列表

透過這種方式,一個int型別的資料1,才被儲存到了列表中。

  • q  指令碼1314行,引用列表資料的方式如下:

  • 09                       myIntList[0]

單從編寫樣式上看,它的引用方式與陣列引用自身資料的方式一模一樣,而且它的下標也是從0開始,表示儲存的第1個資料,其它資料的儲存下標以此類推。

  • q  指令碼1617行,是列表區別於陣列的使用方法,因為列表中可以儲存的資料的個數是沒有限定的;

3.字典

字典的使用方法與列表類似,但是它的宣告需要指定一對資料型別,即鍵(Key)和值(Value)這兩個資料的資料型別。使用字典最大的好處就是,可以透過Key,找到與之對應的Value。對於遊戲的實際意義是,一個網路遊戲一定需要儲存大量使用者的遊戲資訊,而遊戲程式定位這些資訊的方式通常是使用ID。也就是說,一個玩家就有一個ID,而ID關聯了使用者的所有資訊,所以只要知道使用者的ID,就不愁找不到玩家的其它遊戲資訊了。

在講解字典的語法前,同樣先演示一個示例,為指令碼MyScript新增下面的程式碼:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              private Dictionary myDic = new Dictionary();              //宣告字典

  • 07              void Start()

  • 08              {

  • 09                       myDic.Add(10,"Monday");                                   //新增資料到字典

  • 10                       myDic.Add(20,"Tuesday");

  • 11                       myDic[30] = "Wednesday";

  • 12                        Debug.Log ("字典中總共儲存的資料個數是:" + myDic.Count);

  • 13                        Debug.Log ("字典中key10的資料是:" + myDic[10]);                   //引用字典中的資料

  • 14                        Debug.Log ("字典中key20的資料是:" + myDic[20]);

  • 15                       myDic[40] = "Thursday";

  • 16                        Debug.Log ("字典中key40的資料:" + myDic[40]);

  • 17              }

  • 18     }

執行遊戲,在Console檢視裡檢視指令碼輸出的資訊,如圖5-15所示。


5-15  使用字典的示例

  • q  指令碼02行的語句,對於在指令碼中使用字典同樣是不可缺少的,

  • q  指令碼06行的語句:

  • 06              private Dictionary myDic = new Dictionary();

是字典的宣告部分,從格式上來看與列表的宣告方式十分相近。只不過宣告字典需要同時指定鍵和值兩個資料的資料型別。

  • q  指令碼09~10行,為字典新增資料的方式與列表相似:

  • 09                       myDic.Add(10,"Monday");                                   //新增資料到字典

但是字典還有其它的方式,即指令碼11行的程式碼

  • 11                       myDic[30] = "Wednesday";

這種方式,乍看之下與陣列儲存資料的方式一樣,但是此種方式裡,中括號“[ ]”裡的數字可不是“下標”,而是“鍵”。

  • q  指令碼131416行,字典引用資料的形式與陣列和列表一致,但是中括號“[ ]”裡的數字可不是“下標”,而是“鍵”。

  • 13                        myDic[10]

Unity中遍歷大量的資料

如果需要在指令碼中使用同樣的操作去一一判別大量的資料,C#倒是提供了一種不錯的機制,讀者或許會有興趣,就是“迴圈”。C#裡有3種用於實現迴圈的語句,分別是:foreachforwhile。本小節打算依次介紹它們的使用方法,最後再將這種機制應用到遊戲中。

1.foreach迴圈

為了更好的說明foreach迴圈的使用方法,下面將演示一個示例,此示例會使用foreach迴圈遍歷陣列、列表和字典裡的所有資料,並使用if語句選擇所需的資料。為MyScript指令碼新增下面的程式碼:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              void Start()

  • 07              {

  • 08                       string[] myArray = new string[] {"Monday","Tuesday","Wednessday"};

  • 09                       foreach(string myStrArray in myArray)                                        //迴圈遍歷陣列

  • 10                       {

  • 11                                 if(myStrArray == "Monday")

  • 12                                          Debug.Log("There is "+myStrArray+" in array.");

  • 13                       }

  • 14    

  • 15                       List myList = new List {"Monday","Tuesday","Wednessday"};

  • 16                       foreach(string myStrList in myList)                                              //迴圈遍歷列表

  • 17                       {

  • 18                                 if(myStrList == "Tuesday")

  • 19                                          Debug.Log("There is "+myStrList+" in list.");

  • 20                       }

  • 21    

  • 22                       Dictionary myDict = new Dictionary

  • 23                                          {{10,"Monday"},{20,"Tuesday"},{30,"Wednessday"}};

  • 24                       foreach(KeyValuePair myStrDic in myDict)          //迴圈遍歷字典

  • 25                       {

  • 26                                 if(myStrDic.Key == 30)

  • 27                                          Debug.Log ("There is "+myStrDic.Value+" in dictionary");

  • 28                       }

  • 29              }

  • 30     }

執行遊戲,在Console檢視裡檢視指令碼輸出的資訊,如圖5-16所示。


5-16  使用foreach迴圈的示例

  • q  指令碼081522行的程式碼,分別宣告瞭陣列、列表和字典,並且為它們初始化了3組資料;

  • q  指令碼091624行的程式碼,則分別開始使用foreach語句遍歷陣列、列表和字典。以09行的語句為例:

  • 09                       foreach(string myStrArray in myArray)                                        //迴圈遍歷陣列

foreach後括號“( )”裡的語句,表示的含義是:要遍歷的是myArray陣列,而陣列中的每個資料都將先被儲存於同型別的myStrArray變數中。語句的書寫格式如下:

  • foreach(資料型別 變數名 in 陣列名)

  • q  指令碼111826行的程式碼,分別使用if語句判斷變數中的資料,是否是指定的資料。以11行的程式碼為例:

  • 11                                 if(myStrArray == "Monday")

if後括號“( )”裡的語句,是一個關係表示式,當變數myStrArray裡的資料字串是Monday時,表示式的值才是true

  • q  指令碼121927行的程式碼,則表示當使用if語句判斷出陣列、列表和字典中存在指定資料時,會輸出文字資訊到Console檢視。以12行的程式碼為例:

  • 12                                          Debug.Log("There is "+myStrArray+" in array.");

如果陣列中存在資料“Monday”,則會在Console檢視裡輸出“There is Monday in array”。

2.for迴圈

for迴圈也可以遍歷陣列、列表與字典中的所有資料,但是它與foreach語句的些許區別在於,for迴圈表達的含義更像是:讓一段程式碼執行指定的次數。例如,執行5次輸出語句,做10次同樣的操作等等。下面是使用for迴圈的一個簡單示例:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              void Start()

  • 07              {

  • 08                       List myList = new List {"Monday","Tuesday","Wednessday"};

  • 09                       for(int i = 0;i < myList.Count;i++)

  • 10                       {

  • 11                                 Debug.Log(myList[i]);

  • 12                                 if(myList[i] == "Tuesday")

  • 13                                          Debug.Log("There is "+myList[i]+" in list.");

  • 14                       }

  • 15              }

  • 16     }

執行遊戲,在Console檢視裡檢視指令碼輸出的資訊,如圖5-17所示。


5-17  使用for迴圈的示例

  • q  指令碼08行的程式碼,宣告瞭一個列表,且為列表新增了3組資料

  • q  指令碼09行的程式碼,就是一個for語句,如下:

  • 09                       for(int i = 0;i < myList.Count;i++)

for後面括號裡的語句,所表示的含義是:一共要迴圈myList.Count次。變數i類似於一個計數器,記錄著當前迴圈的次數。例如,要迴圈15次,可以使用下面的for迴圈語句:

  • for(int i = 0;i < 15;i++)

  • q  指令碼11~13行的多條語句,是要執行指定迴圈次數的程式碼。其中11行的語句用於在Console檢視中輸出列表中的所有資料;1213行的程式碼,是一個if語句,用於判斷列表中是否存在指定的資料,如果存在就會輸出相應的資訊到Console檢視;

3.while迴圈

while迴圈與for迴圈的操作效果是相同的,即讓迴圈執行一定的次數。但不同的是,從for迴圈的語句中可以很明確的看出迴圈的次數,在達到指定次數以後就停止。while迴圈表達的沒有這麼明確,但它會明確的告訴Unity,什麼時候停止迴圈。下面的指令碼程式碼,是將for迴圈的示例改寫成了while迴圈,如下:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              void Start()

  • 07              {

  • 08                       List myList = new List {"Monday","Tuesday","Wednessday"};

  • 09                       int i = 0;

  • 10                       while(i < myList.Count)

  • 11                       {

  • 12                                 Debug.Log(myList[i]);

  • 13                                 if(myList[i] == "Tuesday")

  • 14                                          Debug.Log("There is "+myList[i]+" in list.");

  • 15                                 i++;

  • 16                       }

  • 17              }

  • 18     }

執行遊戲,在Console檢視裡檢視指令碼輸出的資訊,如圖5-18所示。


5-18  使用while迴圈的示例

  • q  指令碼10行的語句,就是while迴圈語句,它後面的括號裡,只有一個關係表示式,此關係表示式決定了迴圈在什麼時候結束;

其它部分與for迴圈的示例一樣,這裡就不做重複說明了。

Unity遊戲示例

本章先後學習了C#語法裡,3個部分的內容。這3個部分是:

  • q  判斷語句,包括ifif-elseif-else-ifswitch

  • q  資料儲存方式,包括陣列(array)、列表(list)和字典(dictionary);

  • q  大量資料的遍歷方式,包括foreachforwhile

為了更方便的說明各部分的語法實現,以及書寫方式,前面多以非遊戲的示例來說明。但是讀者也許並不知道它們在遊戲中的應用是怎樣的,因此本節應用本章所學習的知識編寫了本節的遊戲示例。

Unity遊戲執行效果

本遊戲想要實現的效果是:遊戲會要求玩家按照順序依次按下指定的幾個按鍵,如果玩家成功的按下這組按鍵,就給出表示成功的圖片提示;反之,就給出表示失敗的圖片提示。遊戲執行效果如圖5-195-205-21所示。


5-19  遊戲檢視中給出了3組預定義的組合鍵


5-20  按照組合鍵2的提示                        5-21  沒有按照任何組合鍵的提示

補充:此遊戲示例的靈感來源於,《拳皇》打鬥時的組合鍵。玩過此遊戲的讀者,應該知道在此種遊戲中,只有玩家按下了指定的按鍵以後,角色才會打出絕技!如圖5-22所示。


5-22  《拳皇》中,按下指定的按鍵以後,所展示出的絕技

雖然本遊戲示例沒有這麼精彩的打鬥畫面,但是卻和它有著一樣的對特定按鍵組合的判斷,也就是說,程式首先需要知道玩家是否按下了指定的組合鍵,然後才決定是否展示特定的特技。而本示例就是運用了本節所學的知識,實現了前一部分的功能。

Unity遊戲實現步驟

遊戲的具體實現步驟如下:

1為遊戲專案匯入6張圖片,其中4個是用於表示方向的,2個是用於表示成功和失敗時的表情的。本遊戲示例匯入的6張圖片,如圖5-23所示。


5-23  為遊戲專案匯入的6張圖片

2新建遊戲專案時,新的遊戲場景也被建立了,而且此遊戲場景中還有一個遊戲物件——Main Camera。本節所建立的遊戲示例,由於是透過介面的繪製實現的,因此不需要讀者繼續往遊戲場景裡新增其它遊戲物件了。

3Project檢視裡,新建一個指令碼,命名為MyScript。本遊戲的所有執行邏輯都將在此指令碼中實現。此指令碼將被賦予Main Camera遊戲物件。

Unity遊戲指令碼的編寫

指令碼的程式碼,涉及了遊戲的所有執行邏輯,內容較多,就將其劃分成了一個小節。本小節也因此得以為讀者詳細介紹指令碼程式碼的思考和編寫過程。

1.宣告變數

1遊戲專案中有6張圖片,指令碼會操作這6張圖片,然後按照指定的遊戲邏輯,將它們顯示在遊戲檢視中。因此指令碼中需要宣告儲存這6張圖片(資料)的變數,如下:

  •          public Texture[] image;

既然都是圖片,聯想到本章所學的知識,就很容易想到使用陣列,當然讀者也可以選擇使用列表。

提示:TextureUnity指令碼中是表示用於儲存圖片這種資料的資料型別。

因為變數被public修飾,所以它會以屬性的形式,出現在Inspector檢視的元件下。讀者需要在此檢視裡,將圖片作為屬性值,賦予這個陣列。具體的賦值方式就是拖動,即將圖片從Project檢視,拖動到Inspector檢視,如圖5-24所示。


5-24  指令碼元件屬性的設定

提示:讀者一定要注意陣列各圖片資料的排列順序,因為後面要編寫的指令碼程式碼將直接使用下標,引用陣列中儲存的圖片資料。對於本示例,圖片陣列中的儲存順序是:updownleftrightsuccessfail

2同樣需要宣告陣列的地方,還有表示預定義的3組組合鍵的資料,如下:

  •          int[,] Sample =

  •          {

  •                    //++++空格

  •                    {KEY_UP,KEY_DOWN,KEY_LEFT,KEY_RIGHT,KEY_SPACE},

  •                    //++++空格

  •                    {KEY_UP,KEY_DOWN,KEY_UP,KEY_DOWN,KEY_SPACE},

  •                    //+++

  •                    {KEY_LEFT,KEY_RIGHT,KEY_LEFT,KEY_RIGHT,KEY_SPACE},

  •          };

程式碼中宣告的是“二維陣列”,而本節詳細介紹的是“一維陣列”,關於二維陣列的介紹讀者可以參考專業的書籍。實際上,讀者可以簡單的將“二維陣列”看作是“一維陣列中儲存的資料是一維陣列”。這段程式碼在宣告二維陣列的時候,還對陣列進行了初始化。初始化的資料是預定義的3組組合鍵,從程式碼的註釋中,讀者很容易就可以看出哪些按鍵,及其順序構成了組合鍵。但是,讀者也許對於那些大些字母感到陌生,它們實際上是“整型常量”,同樣需要宣告在MyScript指令碼中,如下:

  •          public const int KEY_UP = 0;

  •          public const int KEY_DOWN = 1;

  •          public const int KEY_LEFT = 2;

  •          public const int KEY_RIGHT = 3;

  •          public const int KEY_SPACE = 4;

3指令碼還需要宣告的變數有:

  • q  實時記錄玩家按下了哪些按鍵的變數,由於玩家肯定會按下不只一個按鍵,因此這裡選擇列表儲存這類資料,如下:

  •          private List playerInput;

  • q  玩家在一個時間點,按下的是何種按鍵:

  •          private int currentKeyDown;

  • q  玩家是否成功的按下了一組組合按鍵:

  •          private bool isSuccess = false;

2.定義方法

1在宣告表示列表的變數,並不意味著就為列表變數分配了儲存空間。因此,指令碼需要在被初始化時,為列表分配儲存空間,如下:

  •          void Start()

  •          {

  •                    playerInput = new List();

  •          }

Start()方法是Unity定義的方法,此方法會在指令碼被初始化時呼叫,因此將為列表分配儲存空間的程式碼置於此方法中,再合適不過。

2在指令碼中,自己定義一個方法,用於記錄每一個時刻,玩家按下的指定按鍵,如下:

  •          void UpdateKey()

  •          {

  •                    if(Input.GetKeyDown (KeyCode.UpArrow))

  •                             currentKeyDown = KEY_UP;

  •                    if(Input.GetKeyDown (KeyCode.DownArrow))

  •                             currentKeyDown = KEY_DOWN;

  •                    if(Input.GetKeyDown (KeyCode.LeftArrow))

  •                             currentKeyDown = KEY_LEFT;

  •                    if(Input.GetKeyDown (KeyCode.RightArrow))

  •                             currentKeyDown = KEY_RIGHT;

  •                    if(Input.GetKeyDown (KeyCode.Space))

  •                             currentKeyDown = KEY_SPACE;

  •          }

判斷玩家是否按下了指定按鍵,可以使用if語句,如果按下的話,就將表示此按鍵的資料儲存於變數currentKeyDown中。if語句的判斷部分,是用於檢測鍵盤上的按鍵是否被按下的Unity定義的方法。從此段程式碼中可以看出,遊戲檢測的按鍵有5個,包括鍵盤上的4個方向鍵和1個空格鍵。

3Unity每幀呼叫的Update()方法中,新增表示下列用途的程式碼:

  • q  要想確保前面定義的方法UpdateKey(),在遊戲中的每個時刻都被呼叫,最好藉助於Update()方法;

  • q  指令碼還需要時刻將玩家按下的按鍵,儲存於列表中;

  • q  當列表中有5個資料的時候,就去與預定義的組合鍵做比較,如果一致就表示輸入成功,不一致就表示輸入失敗;

  • q  無論失敗與否,都需要將列表清空,因為列表還需要儲存下一輪玩家按下的按鍵。

具體的程式碼實現過程如下:

  • 01              void Update()

  • 02              {

  • 03                        //檢測當前玩家按下的按鍵

  • 04                       UpdateKey ();

  • 05                        //當前有任何按鍵被按下的時候

  • 06                       if(Input.anyKeyDown)

  • 07                       {

  • 08                                 if(isSuccess)

  • 09                                 {

  • 10                                          isSuccess = false;

  • 11                                          playerInput.Clear ();

  • 12                                 }

  • 13                                 //將玩家按下的方向鍵新增到列表中

  • 14                                 playerInput.Add (currentKeyDown);

  • 15                                 //獲取當前列表資料個數

  • 16                                 int listCount = playerInput.Count;

  • 17                                 //如果已經按下了5個鍵,就判斷是否是組合鍵

  • 18                                 if(listCount == 5)

  • 19                                 {

  • 20                                          for(int i = 0;i < 3;i++)

  • 21                                          {

  • 22                                                   int SuccessCount = 0;

  • 23                                                   for(int j = 0;j < 5;j++)

  • 24                                                   {

  • 25                                                             int tempKey = playerInput[j];

  • 26                                                             if(tempKey == Sample[i,j])

  • 27                                                                      SuccessCount++;

  • 28                                                   }

  • 29                                                   if(SuccessCount == 5)

  • 30                                                             isSuccess = true;

  • 31                                          }

  • 32                                 }

  • 33                                 if(listCount > 5)

  • 34                                          playerInput.Clear();

  • 35                       }

  • 36              }

4對於本遊戲示例,遊戲檢視需要實時顯示的元素有,如圖5-25所示。

  • q  玩家此時按下了哪些預定義的按鍵,即“上、下、左、右”4個方向鍵中的哪一個,至於“空格”按鍵嘛,由於沒有表示此按鍵的圖片,所以就不顯示了;

  • q  表示玩家是否按下了5個指定按鍵的圖片,即successfail所表示的圖片;

  • q  用於提示玩家有哪些組合按鍵的文字資訊;


5-25  遊戲檢視上,各元素的顯示

因為Unity是透過呼叫OnGUI()方法來決定,在遊戲檢視上繪製哪些介面元素的,因此需要將顯示上面所列元素的程式碼,置於此方法中,如下:

  • 01              void OnGUI()

  • 02              {

  • 03                       GUILayout.BeginHorizontal();

  • 04                        //表示連結串列中儲存的資料個數

  • 05                       int listCount = playerInput.Count;

  • 06                        //遍歷連結串列中的所有資料

  • 07                       for(int i = 0;i < listCount;i++)

  • 08                       {

  • 09                                 //顯示方向按鍵對應的圖片到遊戲檢視

  • 10                                 int key = playerInput[i];

  • 11                                 Texture tempTex = null;

  • 12                                 switch(key)

  • 13                                 {

  • 14                                 case KEY_UP:

  • 15                                          tempTex = image[0];

  • 16                                          break;

  • 17                                 case KEY_DOWN:

  • 18                                          tempTex = image[1];

  • 19                                          break;

  • 20                                 case KEY_LEFT:

  • 21                                          tempTex = image[2];

  • 22                                          break;

  • 23                                 case KEY_RIGHT:

  • 24                                          tempTex = image[3];

  • 25                                          break;

  • 26                                 }

  • 27                                 if(tempTex != null)

  • 28                                          GUILayout.Label (tempTex,GUILayout.Width (70),GUILayout.Height (70));

  • 29                       }

  • 30                       if(isSuccess)

  • 31                                 GUILayout.Label (image[4],GUILayout.Width (70),GUILayout.Height (70));

  • 32                       else if(!isSuccess && listCount == 5)

  • 33                                 GUILayout.Label (image[5],GUILayout.Width (70),GUILayout.Height (70));

  • 34                       GUILayout.EndHorizontal();

  • 35                       GUILayout.Space (20);

  • 36                        GUILayout.Label ("組合鍵1:上、下、左、右、空格");

  • 37                        GUILayout.Label ("組合鍵2:上、下、上、下、空格");

  • 38                        GUILayout.Label ("組合鍵3:左、右、左、右、空格");

  • 39              }

3.指令碼程式碼概覽

前面已經詳細的介紹了在指令碼中,方法的宣告、方法的定義,以及變數和方法對於遊戲效果的意義。但是讀者也許還無法將它們組合成一個整體,相信下面的指令碼程式碼概覽對讀者有幫助,如下:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              //4個方向圖片,2個表示按鍵成功和失敗的圖示

  • 07              public Texture[] image;

  • 08              //自定義方向鍵的儲存值

  • 09              public const int KEY_UP = 0;

  • 10              public const int KEY_DOWN = 1;

  • 11              public const int KEY_LEFT = 2;

  • 12              public const int KEY_RIGHT = 3;

  • 13              public const int KEY_SPACE = 4;

  • 14              //表示各組合鍵

  • 15              int[,] Sample =

  • 16              {

  • 17                        //++++空格

  • 18                       {KEY_UP,KEY_DOWN,KEY_LEFT,KEY_RIGHT,KEY_SPACE},

  • 19                        //++++空格

  • 20                       {KEY_UP,KEY_DOWN,KEY_UP,KEY_DOWN,KEY_SPACE},

  • 21                        //+++

  • 22                       {KEY_LEFT,KEY_RIGHT,KEY_LEFT,KEY_RIGHT,KEY_SPACE},

  • 23              };

  • 24              //記錄玩家按下的所有鍵

  • 25              private List playerInput;

  • 26              //記錄當前的按鍵

  • 27              private int currentKeyDown;

  • 28              //表示是否成功的按下了組合鍵

  • 29              private bool isSuccess = false;

  • 30              //初始化指令碼

  • 31              void Start()

  • 32              {

  • 33                       playerInput = new List();

  • 34              }

  • 35              //獲取玩家按下的方向鍵

  • 36              void UpdateKey()

  • 37              {

  • 38                        …                                                                       //省略

  • 39              }

  • 40              void Update()

  • 41              {

  • 42                        …                                                                       //省略

  • 43              }

  • 44              //繪製遊戲檢視的介面元素

  • 45              void OnGUI()

  • 46              {

  • 47                        …                                                                       //省略

  • 48              }

  • 49     }

小結

一款遊戲,玩家可以百玩不厭,究其原因就在於遊戲允許玩家透過選擇,進而左右遊戲劇情的發展。遊戲本身則需要判斷玩家做出了怎樣的選擇,判斷的方式就是使用判斷語句,因此本章介紹了ifswitch。又由於玩家有時需要從大量的資料中做出選擇,例如,玩家的角色會數十種技能,要從中選擇一個技能。這又涉及到大量資料的儲存,因此本章介紹了陣列、列表和字典。遊戲本身要從大量資料中判斷出玩家選擇的是哪一個資料,因此最後介紹了遍歷大量資料的方式,即foreachforwhile迴圈。本章的末尾,還以一個較大的遊戲示例,展示了本章所學知識在遊戲中的應用。

本文選自:C#遊戲開發快速入門大學霸內部資料,轉載請註明出處,尊重技術尊重IT人!


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29597077/viewspace-1728499/,如需轉載,請註明出處,否則將追究法律責任。

相關文章