




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、1 / 16Unity3D腳本中文教程 Part1 一、 腳本概覽 這是一個關(guān)于Unity內(nèi)部腳本如何工作的簡單概覽。 Unity內(nèi)部的腳本是通過附加自定義腳本對象到游戲物體組成的。在腳本對象內(nèi)部不同志的函數(shù)被特定的事件調(diào)用。最常用的列在下面 Update 這個函數(shù)在渲染一幀之前被調(diào)用這里是大部分游戲行為代碼被執(zhí)行的地方除了物理代碼。 FixedUpdate 這個函數(shù)在每個物理時間步被調(diào)用一次這是處理基于物理游戲的地方。 在任何函數(shù)之外的代碼 在任何函數(shù)之外的代碼在物體被加載的時候運行這個可以用來初始化腳本狀態(tài)。 注意文檔的這個部份假設(shè)你是用Javascript參考用C編寫獲取如何使
2、用C和Boo編寫腳本的信息。 你也能定義事件句柄它們的名稱都以O(shè)n開始例如OnCollisionEnter為了查看完整的預(yù)定義事件的列表參考MonoBehaviour 文檔。 概覽常用操作 大多數(shù)游戲物體的操作是通過游戲物體的Transform或Rigidbody來做的在行為腳本內(nèi)部它們可以分別通過transform和rigidbody訪問因此如果你想繞著Y軸每幀旋轉(zhuǎn)5度你可以如下寫 function Update transform.Rotate050 如果你想向前移動一個物體你應(yīng)該如下寫 function Update transform.Translate002 概覽跟蹤時間 Time類
3、包含了一個非常重要的類變量稱為deltaTime這個變量包含從上一次調(diào)用Update或FixedUpdate根據(jù)你是在Update函數(shù)還是在FixedUpdate函數(shù)中到現(xiàn)在的時間量。 所以對于上面的例子修改它使這個物體以一個恒定的速度旋轉(zhuǎn)而不依賴于幀率 function Update transform.Rotate05Time.deltaTime0 移動物體 function Update transform. Translate 0 02Time.deltaTime 如果你加或是減一個每幀改變的值你應(yīng)該將它與Time.deltaTime相乘。當(dāng)你乘以Time.deltaTime時你實際的
4、表達(dá)我想以10米/秒移動這個物體不是10米/幀。這不僅僅是因為你的游戲?qū)ⅹ毩⒂趲\行同時也是因為運動的單位容易理解。 米/秒 另一個例子如果你想隨著時間增加光照的范圍。下面的表達(dá)式以2單位/秒改變半 徑。 function Update light.range 2.0 Time.deltaTime 當(dāng)通過力處理剛體的時候你通常不必用Time.deltaTime因為引擎已經(jīng)為你考慮到了這一點。 概覽訪問其他組件 組件被附加到游戲物體附加Renderer到游戲物體使它在場景中渲染附加一個Camera使它變?yōu)橄鄼C(jī)物體所有的腳本都是組件因為它們能被附加到游戲物體。 最常用的組件可以作為簡單成員變量訪
5、問 Component 可如下訪問 Transform transform Rigidbody rigidbody Renderer renderer Camera camera only on camera objects Light light only on light objects Animation animation Collider collider 等等。 對于完整的預(yù)定義成員變量的列表。查看ComponentBehaviour和MonnoBehaviour類文檔。如果游戲物體沒有你想取的相同類型的組件上面的變量將被設(shè)置為null。 任何附加到一個游戲物體的組件或腳本都可以通
6、過GetComponent訪問。 transform.Translate030 /等同于 GetComponentTransform.Translate0 1 0 注意transfom和Transform之間大小寫的區(qū)別前者是變量小寫后者是類或腳本名稱大寫。大小寫不同使你能夠從類和腳本名中區(qū)分變量。 應(yīng)用我們所學(xué)你可以使用GetComponent找到任何附加在同一游戲物體上的腳本和組件請注意要使用下面的例子能夠工作你需要有一個名為OtherScript的腳本其中包含一個DoSomething函數(shù)。OtherScript腳本必須與下面的腳本附加到相同的物體上。 /這個在同一游戲物體桑找到名為Ot
7、herScript的腳本 /并調(diào)用它上加的DoSomething function Update otherScript GetComponentOtherScript otherScript.DoSomething 概覽訪問其它游戲物體 大多數(shù)高級的代碼不僅需要操作一個物體Unity腳本接口有各種方法來找到并訪問其他游戲物體和組件。在下面我們假定有個一名為OtherScriptjs的腳本附加到場景的游戲物體上。 var foo 5 function DoSomething param : String printparam quot with foo: quot foo 1.通過檢視面板賦值
8、引用 你可以通過檢視面板賦值變量到任何物體 /變換拖動到target的物體 var target : Transform function Update target.Translate0 1 0 你也可以在檢視面板中公開到其他物體的引用下面你可以拖動一個包含的游戲物體到檢視面板中的target槽。 /設(shè)置在檢視面板中賦值的target變量上的foo調(diào)用DoSomething var target : OtherScript function Update /設(shè)置target物體的foo變量 target.foo 2 / 調(diào)用target上的DoSomething target.DoSomet
9、hingquotHelloquot 2.通過物體層次定位 對于一個已經(jīng)存在的物體可以通過游戲物體的Transform組件來找到子和父物體 /找到腳本所附加的 /游戲物體的子Hand transform.FindquotHandquot.Translate0 1 0 一旦在層次視圖中找到這個變換你可以使用GetComponent來獲取其他腳本 /找到名為Hand的子 /在附加到它上面的OtherScript中設(shè)置foo為2 transform.FindquotHandquot.Translate0 1 0 /找到名為Hand的子 /然后應(yīng)用一個力到附加在hand上的剛體 transform.Fi
10、ndquotHandquot.GetComponentOtherScript.DoSomethingquotHelloquot / 找到名為Hand的了 / 然后應(yīng)用一個力到附加在hand上的剛體 transform.FindquotHandquot.rigidbody.AddForce0 10 0 你可以循環(huán)所有的子 /變換的所有子向上移動10個單位 for var child : Transform in transform child.Translate0 1 0 參考Transform類文檔獲取更多信息。 Part 2 3.根據(jù)名稱或標(biāo)簽定位. 你可以使用GameObject.Find
11、WithTag和GameObject.FindGameObjectsWithTag搜索具有特定標(biāo)簽的游戲物體使用GameObject.Find根據(jù)名稱查找物體。 function Start / 按照名稱 var go GameObject.FindquotSomeGuyquot go.transform.Translate0 1 0 / 按照標(biāo)簽 var player GameObject.FindWithTagquotPlayerquot player.transform.Translate0 1 0 你可以在結(jié)果上使用GetComponent在找到的游戲物體上得到任何腳本或組件。 fun
12、ction Start / 按名稱 var go GameObject.FindquotSomeGuyquot go.GetComponentOtherScript.DoSomething / 按標(biāo)簽 var player GameObject.FindWithTagquotPlayerquot player.GetComponentOtherScript.DoSomething 一些特殊的物體有快捷方式如主相機(jī)使用Camera.main。 4.作為參數(shù)傳遞 一些事件消息在事件包含詳細(xì)信息。例如觸發(fā)器事件傳遞碰撞物體的Collider組件到處理函數(shù)。 OnTriggerStay給我們一個到碰撞
13、器的引用。從這個碰撞器我們可以獲取附加到其上的剛體。 function OnTriggerStay other : Collider / 如果另一個碰撞器也有一個剛體 / 應(yīng)用一個力到它上面 if other.rigidbody other.rigidbody.AddForce0 2 0 或者我們可以通過碰撞器獲取附加在同一個物體上的任何組件。 function OnTriggerStay other : Collider / 如果另一個碰撞器附加了OtherScript / 調(diào)用它上面的DoSomething / 大多數(shù)時候碰撞器不會附加腳本 / 所以我們需要首先檢查以避免null引用異常
14、if other.GetComponentOtherScript other.GetComponentOtherScript.DoSomething 注意通過上述例子中的other變量你可以訪問碰撞物體中的任何組件。 5.一種類型的所有腳本 使用Object.FindObjectsOfType找到所有具有相同類或腳本名稱的物體或者使用Object.FindObjectOfType.找到這個類型的第一個物體。 function Start / 找到場景中附加了OtherScript的任意一個游戲物體 var other : OtherScript FindObjectOfTypeOtherScr
15、ipt other.DoSomething 概覽向量 Unity使用Vector3類同一表示全體3D向量3D向量的不同組件可以通過想xy和z成員變量訪問。 var aPosition : Vector3 aPosition.x 1 aPosition.y 1 aPosition.z 1 你也能夠使用Vector3構(gòu)造函數(shù)來同時初始化所有組件。 var aPosition Vector31 1 1 Vector3也定義了一些常用的變量值。 var direction Vector3.up / 與 Vector30 1 0相同 單個向量上的操作可以使用下面的方式訪問 someVector.Norm
16、alize 使用多個向量的操作可以使用Vector3類的數(shù) theDistance Vector3.DistanceoneVector otherVector 注意你必須在函數(shù)名之前寫Vector3來告訴JavaScript在哪里找到這個函數(shù)這適用于所有類函數(shù) 你也可以使用普通數(shù)學(xué)操作來操縱向量。 combined vector1 vector2 查看Vector3類文檔獲取完整操縱和可用屬性的列表。 概覽成員變量 amp 全局變量變量 定義在任何函數(shù)之外的變量是一個成員變量。在Unity中這個變量可以通過檢視面板來訪問任何保存在成員變量中的值也可以自動隨工程保存。 var memberVar
17、iable 0.0 上面的變量將在檢視面板中顯示為名為quotMember Variablequot的數(shù)值屬性。 如果你設(shè)置變量的類型為一個組件類型例如Transform Rigidbody Collider任何腳本名稱等等然后你可以在檢視面板中通過拖動一個游戲物體來設(shè)置它們。 var enemy : Transform function Update if Vector3.Distance enemy.position transform.position lt 10 printquotI sense the enemy is nearquot 你也可以創(chuàng)建私有成員變量。私有成員變量可以用來
18、存儲那些在該腳本之外不可見的狀態(tài)。私有成員變量不會被保存到磁盤并且在檢視面板中不能編輯。當(dāng)它被設(shè)置為調(diào)試模式時它們在檢視面板中可見。這允許你就像一個實時更新的調(diào)試器一樣使用私有變量。 private var lastCollider : Collider function OnCollisionEnter collisionInfo : Collision lastCollider collisionInfo.other 全局變量 你也可以使用static關(guān)鍵字創(chuàng)建全局變量 這創(chuàng)造了一個全局變量名為someGlobal / TheScriptName.js中的一個靜態(tài)變量 static var
19、 someGlobal 5 / 你可以在腳本內(nèi)部像普通變量一樣訪問它 printsomeGlobal someGlobal 1 為了從另一個腳本訪問它你需要使用這個腳本的名稱加上一個點和全局變量名。 printTheScriptName.someGlobal TheScriptName.someGlobal 10 Part3 概覽實例化 實例化復(fù)制一個物體。包含所有附加的腳本和整個層次。它以你期望的方式保持引用。到外部物體引用的克隆層次將保持完好在克隆層次上到物體的引用映射到克隆物體。 實例化是難以置信的快和非常有用的。因為最大化地使用它是必要的。 例如 這里是一個小的腳本當(dāng)附加到一個帶有碰撞
20、器的剛體上時將銷毀它自己并實例化一個爆炸物體。 var explosion : Transform / 當(dāng)碰撞發(fā)生時銷毀我們自己 / 并生成給一個爆炸預(yù)設(shè) function OnCollisionEnter Destroy gameObject var theClonedExplosion : Transform theClonedExplosion Instantiateexplosion transform.position transform.rotation 實例化通常與預(yù)設(shè)一起使用 概覽Coroutines amp Yield 在編寫游戲代碼的時候常常需要處理一系列事件。這可能導(dǎo)致像
21、下面的代碼。 private var state 0 function Update if state 0 / 做步驟0 state 1 return if state 1 / 做步驟1 state 2 return / 更方便的是使用yield語句。yield語句是一個特殊類型的返回這個確保在下次調(diào)用時該函數(shù)繼續(xù)從該yield語句之后執(zhí)行。 whiletrue / 做步驟0 yield /等待一幀 / 做步驟1 yield /等待一幀 / . 你也可以傳遞特定值給yield語句來延遲Update函數(shù)的執(zhí)行直到一個特定的事件發(fā)生。 / 做一些事情 yield WaitForSeconds5.0
22、 /等待5秒 /做更多事情 可以疊加和連接coroutines。 這個例子執(zhí)行Do在調(diào)用之后立即繼續(xù)。 Do print quotThis is printed immediatelyquot function Do printquotDo nowquot yield WaitForSeconds 2 printquotDo 2 seconds laterquot 這個例子將執(zhí)行Do并等待直到它完成才繼續(xù)執(zhí)行自己。 /鏈接coroutine yield StartCoroutinequotDoquot printquotAlso after 2 secondsquot print quotTh
23、is is after the Do coroutine has finished executionquot function Do printquotDo nowquot yield WaitForSeconds 2 printquotDo 2 seconds laterquot 任何事件處理句柄都可以是一個coroutine 注意你不能在Update或FixedUpdate內(nèi)使用yield但是你可以使用StartCoroutine來開始一個函數(shù)。 參考YieldInstruction WaitForSeconds WaitForFixedUpdate Coroutine and Mono
24、Behaviour.StartCoroutine獲取更多使用yield的信息。 概覽用C編寫腳本 除了語法使用C或者Boo編寫腳本還有一些不同。最需要注意的是 1.從MonoBehaviour繼承 所有的行為腳本必須從MonoBehaviour繼承直接或間接。在Javascript中這自動完成但是必須在C或Boo腳本中顯示申明。如果你在Unity內(nèi)部使用Asset -gt Create -gt C Sharp/Boo Script菜單創(chuàng)建腳本創(chuàng)建模板已經(jīng)包含了必需的定義。 public class NewBehaviourScript : MonoBehaviour . / C class N
25、ewBehaviourScript MonoBehaviour: . Boo 2.使用Awake或Start函數(shù)來初始化 Javascript中放置在函數(shù)之外的代碼在C或Boo中要放置在Awake或Start中。 Awake和Start的不同是Awake在場景被加載時候運行而Start在第一次調(diào)用Update或FixedUpdate函數(shù)之前被調(diào)用所有Awake函數(shù)在任何Start函數(shù)調(diào)用之前被調(diào)用。 3.類名必須與文件名相同 Javascript中類名被隱式地設(shè)置為腳本的文件名不包含文件擴(kuò)展名。在c和Boo中必須手工做。 4.在C中Coroutines有不同語法。 Coroutines必有一個
26、IEnumerator返回類型并且yield使用yield return 而不是yield using System.Collections using UnityEngine public class NewBehaviourScript : MonoBehaviour / C coroutine IEnumerator SomeCoroutine / 等一幀 yield return 0 /等兩秒 yield return new WaitForSeconds 2 5不要使用命名空間 目前Unity還不支持將代碼放置在一個命名空間中這個需要將會出在未來的版本中。 6.只有序列化的成員變量會
27、顯示在檢視面板中 私有和保護(hù)成員變量只在專家模式中顯示屬性不被序列化或顯示在檢視面板中。 7避免使用構(gòu)造函數(shù) 不要在構(gòu)造函數(shù)中初始化任何變量使用Awake或Start實現(xiàn)這個目的。即使是在編輯模式中Unity也自動調(diào)用構(gòu)造函數(shù)這通常發(fā)生在一個腳本被編譯之后因為需要調(diào)用構(gòu)造函數(shù)來取向一個腳本的默認(rèn)值。構(gòu)造函數(shù)不僅會在無法預(yù)料的時刻被調(diào)用它也會為預(yù)設(shè)或未激活的游戲物體調(diào)用。 單件模式使用構(gòu)造函數(shù)可能會導(dǎo)致嚴(yán)重的后果帶來類似隨機(jī)null引用異常。 因此如果你想實現(xiàn)如一個單件模式不要使用構(gòu)造函數(shù)而是使用Awake。其實上沒有理由一定要在繼續(xù)自MononBehaviour類的構(gòu)造函數(shù)中寫任何代碼。 概覽
28、最重要的類 Javascript中可訪問的全局函數(shù)或C中的基類 移動/旋轉(zhuǎn)物體 動畫系統(tǒng) 剛體 FPS或第二人稱角色控制器 概覽性能優(yōu)化 1使用靜態(tài)類型 在使用Javascript時最重要的優(yōu)化是使用靜態(tài)類型而不是動態(tài)類型Unity使用一種叫做類型推理的技術(shù)來自自動轉(zhuǎn)換Javascript為靜態(tài)類型編碼而不需要你做任何工作。 var foo5 在上面的例子里foo會自動被推斷為一個整型值。因此Unity可能使用大量的編譯時間來優(yōu)化。而不使用耗時的動態(tài)名稱變量查找等。這就是為什么Unity比其他在JavaScript的實現(xiàn)平均快20倍的原因之一。 唯一的問題是有時并非一切都可以做類型推斷。Uni
29、ty將會為這些變量重新使用動態(tài)類型。通過回到動態(tài)類型編寫JavaScript代碼很簡單。但是這也使得代碼運行速度較慢。 讓我們看一些例子 function Start var foo GetComponentMyScript foo.DoSomething 這里foo將是動態(tài)類型因此調(diào)用DoSomething函數(shù)將使用較長時間因為foo的類型是未知的它必須找出它是否支持DoSomething函數(shù)如果支持調(diào)用它。 function Start var foo : MyScript GetComponentMyScript foo.DoSomething 這里我們強(qiáng)制foo為指定類型你將獲得更好的
30、性能。 2使用pragma strict 當(dāng)然現(xiàn)在問題是你通常沒有意識到你在使用動態(tài)類型。pragma strict解決了這個簡單的在腳本頂部添加pragma strict。然后unity將在腳本中禁用動態(tài)類型強(qiáng)制使用靜態(tài)類型如果一個類型未知。Unity將報告編譯錯誤。那么在這種情況下foo將在編譯時產(chǎn)生一個錯誤 pragma strict function Start var foo GetComponentMyScript foo.DoSomething 3.緩存組件查找 另一個優(yōu)化是組件緩存。不幸的是該優(yōu)化需要一點編碼并且不一定是值得的但是如 果你的腳本是真的用了很長時間了你需要把最后一
31、點表現(xiàn)出來這是一個很好的優(yōu)化。 當(dāng)你訪問一個組件通過GetComponent或訪問變量Unity會通過游戲?qū)ο笳业秸_的組件。這一次可以很容易地通過緩存保存在一個私有變量里引用該組件。 簡單地把這個 function Update transform.Translate0 0 5 變成 private var myTransform : Transform function Awake myTransform transform function Update myTransform.Translate0 0 5 后者的代碼將運行快得多因為Unity沒有找到變換在每一幀游戲組件中的對象。這同樣
32、適用于腳本組件在你使用GetComponent代替變換或者其它的東西。 4.使用內(nèi)置數(shù)組 內(nèi)置數(shù)組的速度非??焖哉埵褂盟鼈?。 而整列或者數(shù)組類更容易使用因為你可以很容易地添加元素他們幾乎沒有相同的速度。內(nèi)置數(shù)組有一個固定的尺寸但大多數(shù)時候你事先知道了最大的大小在可以只填寫了以后。關(guān)于內(nèi)置數(shù)組最好的事情是他們直接嵌入在一個結(jié)構(gòu)緊湊的緩沖區(qū)的數(shù)據(jù)類型沒有任何額外的類型信息或其他開銷。因此遍歷是非常容易的作為一切緩存在內(nèi)存中的線性關(guān)系。 private var positions : Vector3 function Awake positions new Vector3100 for var i0ilt100i positionsi Vector3.zero 5.如果你不需要就不要調(diào)用函數(shù) 最簡單的和所有優(yōu)化最好的是少
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 商業(yè)地產(chǎn)風(fēng)險量化-洞察及研究
- 工地安全教育資料范本
- 納米線晶體管設(shè)計-洞察及研究
- 網(wǎng)絡(luò)大數(shù)據(jù)挖掘策略-洞察闡釋
- 可生物降解蛋類包裝材料研究-洞察闡釋
- 教育政策在培養(yǎng)學(xué)生獨立思考與創(chuàng)新力方面的作用
- 信息技術(shù)在教育心理學(xué)中的應(yīng)用
- 尿素氮代謝與腎毒性關(guān)聯(lián)-洞察闡釋
- 基于神經(jīng)網(wǎng)絡(luò)的多文檔聯(lián)合理解方法-洞察闡釋
- 教育科技融合下游戲化積分的多維度研究
- 氣瓶充裝質(zhì)量保證體系手冊
- 《布病防控知識》課件
- 2024年社區(qū)工作者考試必考1000題及完整答案
- 起重裝卸機(jī)械3級復(fù)習(xí)試題附答案
- 2024年09月2024秋季中國工商銀行湖南分行校園招聘620人筆試歷年參考題庫附帶答案詳解
- 《北京市道路橋梁試驗檢測費用定額》
- 中醫(yī)院人才引進(jìn)績效考核方案
- 高速公路施工安全培訓(xùn)課件
- 2024年中級經(jīng)濟(jì)師考試經(jīng)濟(jì)基礎(chǔ)知識必考重點總結(jié)全覆蓋
- 轉(zhuǎn)崗人員安全知識培訓(xùn)
- 金屬非金屬地下礦山安全生產(chǎn)標(biāo)準(zhǔn)化定級評分標(biāo)準(zhǔn)(2023版)
評論
0/150
提交評論