2011年5月14日 星期六

Unity 的 JaveScript 利用 enum 定義常數

比較有點經驗的程式設計人員都知道,寫作時應該要多避免程式碼中有不可思議的值,所以通常我們會利用變數或常數來宣告一些值,需要變動的值,理所當然的會定義變數來代替,所以不容易使程式碼中出現不可思議的值,但很多時候只是為了判斷用的值,我們如果常常使用 if(status == 7) 這樣的方式寫作,程式結構越來越大或是將來回頭來維護時,可能很難想像到這個數值 7 究竟是代表什麼意義,所以此部份如果事先定義常數的話,將可以更方便於辨識及後續維護,例如 if(status == PLAYING),可以更清楚明白這個判斷的目的為何。


Unity 是個物件導向的引擎,Unity 中的每個程式檔案本身即代表一個獨立的 class (正確的說應該是 Component,當然也可以在一個程式檔內撰寫多個 class,但是比較不建議這樣做),在每個 class 中,我們會為其定義需要的變數成員,如果需要定義常數,通常也是在個別的 class 中利用變數成員來定義,在外部需要使用到時再 new 這個 class 來使用或是利用 GetComponent 從另一個 Component 中取得,如此常數則依照 class 功能的不同個別定義在不同地方來分類管理,這樣似乎會讓人感到程式架構相當清楚明白,分配得宜,但在使用上似乎不太方便。

大部份定義常數都是用來當做標記判斷用,在整個系統架構的任何地方都可能隨時會用到,所以最好能夠直接使用,而不需要透過其他程序來引用,同時最好也能夠集中管理,而不是散落在各處,此時,使用 enum 來定義將是最適合不過的,只需要建立一個 .js 檔,將所有需要定義的常數都寫在此檔內,之後在任何一個地方需要使用,直接取用就行了,而且每個 enum 本身也定義了個別的型態,所以常數間不容易發生重複使用的問題,以下就來說明幾個使用 enum 的用法:



定義方式:
enum STATUS {Playing , Start , End};

使用在 if :
if(status == STATUS.Playing) {....}

使用在 switch:
switch(status){

    case STATUS.Playing :
        ....
    break;
   
    case STATUS.Start :
        ....
    break;
   
    case STATUS.End :
        ....
    break;
}

使用在 function 的參數:
function CheckStatus(_status : STATUS):boolean{
    ....
}
if(CheckStattus(STATUS.Playing)){....}

使用在 public 變數成員:
public var status : STATUS;
將 Script 配置到物件上,此時 Component 的 status 設定欄位可以下拉選單的方式設定該值。



配置給物件


以下拉選單的方式設定值
判斷或選項用的常數本身所代表的值內容,對我們來講並不是最重要的,通常我們並不在意它是 1、2、4、9、12、66 ....等或者是其他的任何數值,而是它在程式碼中能正確的表現出其所代表的真正意義,使每個判斷執行都能是正確的,所以我們使用 enum 來定義,我們不需要知道狀態 Playing 是用什麼值來判斷,我們只需要知道狀態是 STATUS.Playing ,此時代表遊戲是在進行中的狀態,這樣就可以了,如此,程式敘述將會更簡單清楚。