天天看點

U3D——Unity3D的腳本-script入門

 Unity3D的基本操作很容易就能掌握了,接下來就是遊戲系統的核心部分:腳本。 什麼是Script(腳本)?簡而言之,就是使用代碼來執行一系列動作指令的特殊文本,它需要編譯器來從新解讀。U3D内部如何解讀腳本,這不是我們所要關心的—這是引擎開發人員的活,我們所要知道的就是腳本的使用規則。

【三種語言的特點】 U3D支援C#,JavaScript,BOO三種語言格式的代碼編寫。首先來簡單介紹下這三種語言的特點:

U3D——Unity3D的腳本-script入門

對U3D來說,這是入門級的腳本語言,U3D内置的函數都能通過JS友善的調用。文法上,JS和傳統的C語言差不多,需要分号結束符,變量類型定義,大括号……不過它的變量類型定義,是通過冒号接在變量右邊,如: Name:string=”Li”。相對其他兩種語言,使用JS文法,很多函數不需要執行個體化就能直接使用,如:

vector3 direction=vector3(1,2,3)。如果使用C#,則需要使用new關鍵字: vector3 direction=new vector3(1,2,3)。JavaScript直接繼承自U3D的MonoBehaviour類,是以不像C#和BOO那樣需要使用Using或Import來加載類庫。這看似省心,不過因為缺少了加載特殊類庫,JavaScript能調用的第三方函數不多(當然,我們可以載入net類庫給JavaScript調用,雖然看着有點奇怪……)。 *注意:JavaScript不是Java,同時,U3D中的JavaScript也有别于獨立的JavaScript語言。

U3D——Unity3D的腳本-script入門
U3D——Unity3D的腳本-script入門

C#(發音C Sharp), 微軟開發的面向對象程式設計語言。由于有強大的net類庫支援,以及由此衍生出的很多跨平台語言,C#逐漸成為U3D開發者推崇的程式語言。U3D内置的腳本範例中,C#腳本也占了很大一部分(其他腳本是JavaScript腳本)。另外,在裝有VisualStudio的電腦上,我們也可以使用微軟的腳本編輯工具來編寫U3D腳本。C開頭,那麼文法上和C語言是很接近的,除了面向對象語言所具有的一些特點。當然,我不用在這進行太多說明,因為C#的相關學習資料很多。

U3D——Unity3D的腳本-script入門

BOO是新興的基于Python的語言。文法上,BOO和Python大同小異,都是通過換行來實作語句的結束,它省略了分号、大括号,甚至條件語句的小括号等。Python在很多大型三維圖形軟體上都有應用,由此可以看出它的跨平台性能很不錯,我也選擇使用Python來編寫maya特效腳本;不過,對于遊戲事件的編寫,個人感到這種精簡的文法反而有些難以适應。如基本的變量類型定義,BOO(類Python)文法就顯得不那麼便捷: direction as vector3 =vector3(1,2,3)。遊戲事件不同于特效腳本,前者是過程中的互動,而後者隻需要看到結果。是以,遊戲中經常需要大量的具有明确類型的變量出現,BOO語言可以省略變量類型的優勢在這裡反而容易引發問題。

U3D——Unity3D的腳本-script入門

引擎編譯時,三種語言的執行效率是一樣的,因為U3D會内部進行它自己的語言格式的轉換。盡管我們可以在不同語言編寫的腳本之間進行變量和方法的調用,但是我不推薦那麼做,因為測試确實會存在一些意想不到的問題。使用不同語言編寫多個腳本時,應盡量讓腳本之間沒有直接聯系。 最後,個人認為,在windows平台下,C#是U3D腳本語言的最佳選擇。

【腳本的使用規則】 U3D的腳本作用方式很有趣,我稱之為“拖放法”。無論是作用在一個具體的場景物體還是管理着批量的物體,腳本首先必須依附于場景中的一個元素才能被執行。要将腳本賦予物體的方式很簡單,就是按住滑鼠左鍵将腳本檔案拖放到物體的屬性面闆上(也可以拖放到場景的物體上)。U3D有個概念,那就是component(成分)--類似Maya的節點。包括腳本,所有元素屬性都是遊戲物體的component。添加、删除、停用、讀取、寫入component資訊,就是腳本所要做的(盡管腳本也是個component)。

U3D——Unity3D的腳本-script入門

net語言的C#,在不同腳本之間調用變量和方法時,如果腳本位于同一路徑下,那麼隻需要對非static(靜态)成員進行new執行個體化即可。例如a.cs和b.cs,要調用腳本a中的一個非靜态變量cc,需要在腳本b中寫入:a  c=new a(),然後c.cc的格式完成調用。不過,作為一個component,要調用不同腳本之間的成員,U3D的規則是使用GetComponent函數來完成(其實也就相當于new的作用,隻是U3D不支援這種腳本間調用的寫法)。如:      someScript = GetComponent<ExampleScript>(); 如果是在C#腳本中調用JavaScript腳本,則使用強制類型轉換文法:     someScript = GetComponent(“ExampleScript”) as ExampleScript ; *<>這個特殊的符号表示使用的是C#中的泛型功能,用于避免強制類型的轉換,減少裝箱量(将值類型專為引用類型的操作)。

根據腳本使用的情況,可以有以下做法: 1.腳本位于同一個物體上。 可直接使用泛型或者類型轉換文法調用。 如:someScript = GetComponent<ExampleScript>(); 2.腳本位于不同物體上。 需要使用Find或相關的搜尋函數,取得指定名稱的物體資訊後,再+”.GetComponent”函數。如:GameObject.Find("stone").GetComponent<ExampleScript>()。 3.腳本位于同一路徑或者被調用腳本位于主腳本的路徑及以下(腳本是否被物體使用都可)。 将被調用腳本中的成員(變量或方法)使用static辨別,然後可以通過”腳本.成員”的格式直接調用。例如: ScriptA.CS … public static mm(); … ScriptB.CS … ScriptA.mm(); … 不過,static成員的調用雖然提高了效率,但因為它常駐記憶體,是以在會産生大量系統資源要求的情況下要慎用。 *static是C#定義變量或方法類型的關鍵字,使用static的變量或方法,不需要new執行個體化即可直接調用。

【腳本内容】 除了JavaScript函數,C#和BOO的腳本都需要預先載入類庫。這裡以C#為例: using UnityEngine; using System.Collections; public class NewBehaviourScript : MonoBehaviour { } NewBehaviourScript是腳本的名稱,它必須和腳本檔案的外部名稱一緻(如果不同,腳本無法在物體上被執行) 。所有遊戲執行語句,都包含在這個繼承自MonoBehaviour類的自創腳本中(大括号内)。 以下介紹一些常用的内置運作函數(定義函數時,JavaScript的關鍵字是function,C#是void,BOO是def。如:void Start()。

Awake:在遊戲運作時調用,用于初始化。 Start : 隻在遊戲開始時執行一次,在Awake()函數後執行; Update:在遊戲每一幀都執行一次,在Start()函數後執行; LateUpdate:同Update,隻是它會在Update()函數執行後再執行; FixedUpdate:當遊戲中引入剛體系統,使用适配的方式同步實體時鐘,可以讓動力學更精确的計算; OnGUI:繪制遊戲界面的函數,因為每一幀執行多次,是以一些時間相關的函數要盡量避免直接在其内部使用。 OnMouseOver:滑鼠停留在物體上時執行該函數的内容。 OnMouseEnter:滑鼠進入物體範圍時執行該函數的内容。和OnMouseOver不同,該函數隻執行一次。 OnMouseExit:滑鼠離開物體範圍時執行該函數的内容。 OnMouseDown:滑鼠按下時執行該函數的内容。 OnMouseUp:當滑鼠釋放時執行該函數的内容。 OnMouseDrag:按住滑鼠拖動時執行該函數的内容。

OnMouse系列函數是針對指定物體的,如果要使用全局滑鼠控制操作,則需要使用射線相關函數。 還有很多特殊的遊戲觸發事件的函數,這裡就不一一列出。 U3D内置的代碼有個命名規則,開頭第一個字母大寫的詞組都屬于類或者函數,而開頭小寫的詞組則是變量。新手經常會混淆它們之間的差別。簡單說來,函數詞組可以作為變量的類型,還可以直接執行功能,詞組後必接成對小括号;變量是對應函數的分支,實作的是對一個具體屬性的控制。例如:

U3D——Unity3D的腳本-script入門

Camera和camera。當場景中存在一個預設的主錄影機,腳本位于錄影機時,Camera.mainCamera.transform和camera.transform是等同的;假如腳本在其他物體上,Camera.mainCamera.transform仍舊直接擷取了主錄影機,而camera.transform必須要使用Find函數先找到指定名稱的錄影機:GameObject.Find("mainCamera").camera.transform。當然,這裡是列出細節來比較,實際運用時,腳本位于特殊元素上我們可以不用聲明這個元素的類别,如camera.transform可以簡化到transform。

U3D——Unity3D的腳本-script入門

GameObject和gameObject。前者包含查找,破壞和産生遊戲物體的函數,同時可以将一個變量定義為“遊戲物體”類型;後者則包含豐富的遊戲物體屬性,例如名稱,變形資訊,動畫,渲染等。

U3D——Unity3D的腳本-script入門

同上面列舉的camera,對于直接作用于指定物體的腳本,gameObject也可以省略掉。不過,在開始學寫代碼時,書寫完整的變量名能讓我們更深刻的記憶每個屬性和變量的關系。 通過以上對比後可以這麼了解,函數通常是全局控制(包含腳本外的其他物體),而變量是需要指出具體的應用對象。 *如果書寫代碼時語句不在函數作用範圍内,編譯器将無法智能完成一些變量的全名顯示。 更多函數的運用方法,使用者可參考官方提供的幫助文檔。

【簡單例子】 在一個箱子上按下滑鼠左鍵,箱子就開始旋轉,同時燈光被點亮,螢幕出現“Test”的字樣。

1.點選Hierarchy欄下的Create,建立一個Cube,Plane和Spotlight。

U3D——Unity3D的腳本-script入門

2.在Assets目錄下,建立檔案夾(右鍵,Create->Folder),用于存放遊戲的各種資源:模型,動畫,材質,腳本,Prefab等。 3.輕按兩下進入myScript檔案夾,建立一個C#腳本。

U3D——Unity3D的腳本-script入門

4.給腳本命名,然後再輕按兩下開啟腳本編輯工具(如果腳本名稱和内部的類名稱不同,一定要更正)。

U3D——Unity3D的腳本-script入門

5.加入滑鼠相關函數,這裡我需要用到OnMouseOver,OnMouseExit,OnMouseDown。此類特殊函數不會有智能拼寫出現。

U3D——Unity3D的腳本-script入門

6.文法方面就不傻瓜式的一步步進行了,實作的思路是: 當滑鼠移動到物體上,物體的材質色彩變為黃色,同時将一個初始值為假的布爾變量1的值取真;當滑鼠離開後,物體材質色彩還原,布爾變量1值為假;當按下滑鼠左鍵,且布爾變量1的值為真,布爾變量2的值為真。 *OnMouse函數都是執行一次的函數,是以不能将和動畫有關的控制函數放于其内執行,通常會使用布爾開關來控制Update函數中的動畫函數 。

U3D——Unity3D的腳本-script入門

7.接着在Update函數内實作: 當布爾變量2的值為真,物體旋轉。

U3D——Unity3D的腳本-script入門

8.将寫好的腳本拖拽到場景中的方塊上(或者先選擇方塊,将腳本拖到方塊的屬性欄),調好錄影機位置,執行測試;

U3D——Unity3D的腳本-script入門

9.因為腳本隻作用于其所依附的物體,要控制燈光,我們有兩個選擇:建立新的腳本,使用查找物體函數。很顯然,我沒必要為這麼簡單的功能加入一個新的腳本。是以我使用Find函數擷取燈光的強度屬性。 *腳本中遇到這樣一串長長的語句時,通常會使用一個自定義變量來替代,而且很多時候還能降低計算量。例如: float LightInt =GameObject.Find("Spotlight").light.intensity。如果在Start函數中初始化,Update中就不必每幀執行查找函數,降低遊戲效率。不過這裡作為一個測試,我也就很省事的忽略了。

U3D——Unity3D的腳本-script入門

10.GUI的使用。要在遊戲視圖顯示各種UI資訊,都需要使用U3D的UI元件或者GUI函數。為友善閱讀,我将其他函數的内容收起,并使用GUI函數的Label建立簡單的文字顯示功能(有關GUI更多的詳細資訊,請參閱官方文檔,我會在後面再做讨論)。

U3D——Unity3D的腳本-script入門

11.最終測試:

U3D——Unity3D的腳本-script入門

12.釋出。執行File->BuildSettings,開啟釋出界面。設定好要釋出遊戲的平台以及一些釋出的資訊,點選Build按鈕即可釋出一個完整的遊戲用戶端。U3D支援釋出的平台與使用者授權和作業系統有關,如IOS遊戲需要MAC平台的U3D才能釋出,Android需要在系統安裝安卓SDK包,次世代主機平台則需要使用者向官方購買額外解決方案。

U3D——Unity3D的腳本-script入門

*由于商業政策的分歧,U3D剛宣布了中止flash平台的後續開發,看來想玩U3D開發的網頁遊戲,還是需要先安裝U3D官方的網頁插件。

【結語】 遊戲制作并不簡單,這裡僅僅是一個初入門的小例子,主要是對腳本使用方式的練習。後面會逐漸深入學習U3D豐富的函數功能。

繼續閱讀