Unity內(nèi)部的腳本,是通過附加自定義腳本對象到游戲物體組成的。在腳本對象內(nèi)部不同的函數(shù)被特定的事件調(diào)用。最常用的列在下面:
Update: 這個(gè)函數(shù)在渲染一幀之前被調(diào)用。這里是大部分游戲行為代碼被執(zhí)行的地方,除了物理代碼。 FixedUpdate 這個(gè)函數(shù)在每個(gè)物理時(shí)間步被調(diào)用一次。這是處理基于物理游戲行為的地方。 在任何函數(shù)之外的代碼: 在任何函數(shù)之外的代碼在物體被加載的時(shí)候運(yùn)行。這個(gè)可以用來初始化腳本狀態(tài)。 注意: 文檔的這個(gè)部分假設(shè)你是用Javascript,參考用C#編寫腳本獲取如何使用C#和Boo編寫腳本的信息。 你也能定義事件句柄。它們的名稱都以O(shè)n開始,(例如OnCollisionEnter).為了查看完整的預(yù)定義事件的列表,參考MonoBehaviour文檔。 常用操作 大多數(shù)游戲物體的操作是通過游戲物體的Transform和/或Rigidbody來做的。在行為腳本內(nèi)部它們可以分別通過transform和rigidbody訪問.因此如果你想繞著Y軸每幀旋轉(zhuǎn)5度,你可以如下寫: function Update() { 如果你想向前移動(dòng)一個(gè)物體,你應(yīng)該如下寫: function Update() { 跟蹤時(shí)間 Time類包含一個(gè)非常重要的類變量,稱為deltaTime.這個(gè)變量包含從上一次調(diào)用Update或FixedUpdate (根據(jù)你是在Update函數(shù)還是在FixedUpdate 函數(shù)中)到現(xiàn)在的時(shí)間量。 所以對于上面的例子,修改它使這個(gè)物體以一個(gè)恒定的速度旋轉(zhuǎn)而不依賴于幀率: function Update() { 移動(dòng)物體: function Update() { 如果你加或減一個(gè)每幀改變的值,你應(yīng)該將它與Time.deltaTime相乘。當(dāng)你乘以Time.deltaTime時(shí),你實(shí)際表達(dá):我想以 10米 /秒移動(dòng)這個(gè)物體而不是 10米 /幀。這不僅僅是因?yàn)槟愕挠螒驅(qū)ⅹ?dú)立于幀率運(yùn)行,同時(shí)也是因?yàn)檫\(yùn)動(dòng)的單位容易理解。( 10米 /秒) 另一個(gè)例子,如果你想隨著時(shí)間增加光照的范圍。下面的表達(dá)式,以2單位/秒改變半徑. function Update() { 當(dāng)通過力處理剛體的時(shí)候,你通常不必用Time.deltaTime乘,因?yàn)橐嬉呀?jīng)為你考慮到了這一點(diǎn)。 訪問其他組件 組件被附加到游戲物體。附加Renderer到游戲物體使它在場景中渲染,附加一個(gè)Camera使它變?yōu)橄鄼C(jī)物體。所有的腳本都是組件,因?yàn)樗鼈兡鼙桓郊拥接螒蛭矬w。 最常用的組件可以作為簡單成員變量訪問: Component Rigidbody Renderer Collider 任何附加到一個(gè)游戲物體的組件或腳本都可以通過GetComponent訪問。 transform.Translate(0, 1, 0); // 等同于 GetComponent(Transform).Translate(0, 1, 0); 注意transform和Transform之間大小寫的區(qū)別. 前者是變量(小寫),后者是類或腳本名稱(大寫). 大小寫不同使你能夠從類和腳本名中區(qū)分變量。 應(yīng)用我們所學(xué),你可以使用GetComponent找到任何附加在同一游戲物體上的腳本和組件。請注意要使下面的例子能夠工作,你需要有一個(gè)名為OtherScript的腳本,其中包含一個(gè)DoSomething函數(shù)。OtherScript腳本必須與下面的腳本附加到相同的游戲物體上。 //這個(gè)在同一個(gè)游戲物體上找到名為OtherScript的腳本 //并調(diào)用它上面的DoSomething. function Update () { 訪問其他游戲物體 大多數(shù)高級的代碼不僅需要操作一個(gè)物體。Unity腳本接口有各種方法來找到并訪問其他游戲物體和組件。在下面,我們假定有一個(gè)名為OtherScript.js的腳本附加到場景的游戲物體上。 var foo = 5; print(param + " with foo: " + foo); 1. 通過檢視面板賦值引用. 你可以通過檢視面板賦值變量到任何物體。 // 變換拖動(dòng)到target槽的物體 var target : Transform; function Update () { 你也可以在檢視面板中公開到其他物體的引用。下面你可以拖動(dòng)一個(gè)包含OtherScript的游戲物體到檢視面板中的target槽。 // 設(shè)置在檢視面板中賦值的target變量上的foo,調(diào)用DoSomething. var target : OtherScript; { 2. 通過物體層次定位. 對于一個(gè)已存在的物體,可以通過游戲物體的Transform組件來找到子和父物體: // 找到腳本所附加的 // 游戲物體的子"Hand" 一旦在層次視圖中找到這個(gè)變換,你可以使用GetComponent來獲取其他腳本. //找到名為"Hand"的子. //在附加到它上面的OtherScript中, 設(shè)置foo為2. transform.Find("Hand").GetComponent(OtherScript).foo = 2; //找到名為"Hand"的子. //調(diào)用附加到它上面的OtherScript腳本中的DoSomething. transform.Find("Hand").GetComponent(OtherScript).DoSomething("Hello"); //找到名為"Hand"的子. //然后應(yīng)用一個(gè)力到附加在hand上的剛體. transform.Find("Hand").rigidbody.AddForce(0, 10, 0); 你可以循環(huán)所有的子。 // 變換的所有子向上移動(dòng)10個(gè)單位! for (var child : Transform in transform) { 參考Transform類文檔獲取更多信息。 3.根據(jù)名稱或標(biāo)簽定位. 你可以使用GameObject.FindWithTag和GameObject.FindGameObjectsWithTag搜索具有特定標(biāo)簽的游戲物體。使用GameObject.Find根據(jù)名稱查找物體. function Start () // 按照標(biāo)簽 } 你可以在結(jié)果上使用GetComponent,在找到的游戲物體上得到任何腳本或組件。 function Start () //按標(biāo)簽 一些特殊的物體有快捷方式,如主相機(jī)使用Camera.main。 4. 作為參數(shù)傳遞. 一些事件消息在事件中包含詳細(xì)信息。例如,觸發(fā)器事件傳遞碰撞物體的Collider組件到處理函數(shù)。 OnTriggerStay給我們一個(gè)到碰撞器的引用。從這個(gè)碰撞器我們可以獲取附加到其上的剛體。 function OnTriggerStay (other : Collider ) { //如果另一個(gè)碰撞器也有一個(gè)剛體 或者我們可以通過碰撞器獲取附加在同一物體上的任何組件。 function OnTriggerStay (other : Collider ) { // 如果另一個(gè)碰撞器附加了OtherScript // 調(diào)用它上面的DoSomething. // 大多數(shù)時(shí)候碰撞器不會附加腳本, // 所以我們需要首先檢查以避免null引用異常。 if (other.GetComponent(OtherScript)) { 注意通過上述例子中的other變量,你可以訪問碰撞物體中的任何組件。 5.一種類型的所有腳本 使用Object.FindObjectsOfType找到所有具有相同類或腳本名稱的物體,或者使用Object.FindObjectOfType找到這個(gè)類型的第一個(gè)物體。 function Start () 向量 Unity使用Vector3類統(tǒng)一表示全體3D向量。3D向量的不同組件可以通過x, y 和 z成員變量訪問。 var aPosition : Vector3; aPosition.x = 1; aPosition.y = 1; aPosition.z = 1; 你也能夠使用Vector3構(gòu)造函數(shù)來同時(shí)初始化所有組件. var aPosition = Vector3(1, 1, 1); Vector3也定義了一些常用的常量值. var direction = Vector3.up; // 與Vector3(0, 1, 0);相同 單個(gè)向量上的操作可以使用下面方式訪問: someVector.Normalize(); 使用多個(gè)向量的操作可以使用Vector3類函數(shù): theDistance = Vector3.Distance(oneVector, otherVector); (注意你必須在函數(shù)名之前寫Vector3.來告訴Javascript在哪里找到這個(gè)函數(shù). 這適用于所有類函數(shù)。) 你也可以使用普通數(shù)學(xué)操作來操縱向量。 combined = vector1 + vector2; 查看Vector3類文檔獲取完整操作和可用屬性的列表。 成員變量 & 全局變量變量 定義在任何函數(shù)之外的變量是一個(gè)成員變量。在Unity中這個(gè)變量可以通過檢視面板來訪問。任何保存在成員變量中的值也可以自動(dòng)隨工程保存。 var memberVariable = 0.0; 上面的變量將在檢視面板中顯示為名為"Member Variable"的數(shù)值屬性。 如果你設(shè)置變量的類型為一個(gè)組件類型(例如Transform, Rigidbody, Collider, 任何腳本名稱, 等等.)然后你可以在檢視面板中通過拖動(dòng)一個(gè)游戲物體來設(shè)置它們。 var enemy : Transform; function Update() { print("I sense the enemy is near!"); 你也可以創(chuàng)建私有成員變量。私有成員變量可以用來存儲那些在該腳本之外不可見的狀態(tài)。私有成員變量不會被保存到磁盤并且在檢視面板中不能編輯。當(dāng)它被設(shè)置為調(diào)試模式時(shí),它們在檢視面板中可見。這允許你就像一個(gè)實(shí)時(shí)更新的調(diào)試器一樣使用私有變量。 private var lastCollider : Collider; function OnCollisionEnter( collisionInfo : Collision ) { 全局變量 你也可以使用static關(guān)鍵字創(chuàng)建全局變量。 這創(chuàng)造了一個(gè)全局變量,名為someGlobal。 // 'TheScriptName.js'中的一個(gè)靜態(tài)變量 static var someGlobal = 5; // 你可以在腳本內(nèi)部像普通變量一樣訪問它 print(someGlobal); someGlobal = 1; 為了從另一個(gè)腳本訪問它,你需要使用這個(gè)腳本的名稱加上一個(gè)點(diǎn)和全局變量名。 print(TheScriptName.someGlobal); TheScriptName.someGlobal = 10; 實(shí)例化 實(shí)例化,復(fù)制一個(gè)物體。包含所有附加的腳本和整個(gè)層次。它以你期望的方式保持引用,到外部物體引用的克隆層次將保持完好,在克隆層次上到物體的引用將映射到克隆物體。 實(shí)例化是難以置信的快和非常有用的。因此最大化地使用它是必要的。 例如,這里是一個(gè)小的腳本,當(dāng)附加到一個(gè)帶有碰撞器的剛體上時(shí)將銷毀它自己并實(shí)例化一個(gè)爆炸物體。 var explosion : Transform; // 當(dāng)碰撞發(fā)生時(shí)銷毀我們自己 // 并生成一個(gè)爆炸預(yù)設(shè) function OnCollisionEnter () var theClonedExplosion : Transform; 實(shí)例化通常與預(yù)設(shè)一起使用 |
|