轉載請註明出處:http://www.cnblogs.com/yuxiuyan/p/7565345.html
上回書說到了unity的基本操作。這回我們來侃侃unity中的組件與腳本。
目錄結構
1.組件
組件(Component),顧名思義,就是遊戲物體的組成部件。
這和我們對現實生活的認識是一致的。就比如說一臺主機,是有CPU,顯卡,主板,內存條等等組成的。這些部件就是主機的“組件”。這些組件一旦有不滿意的,隨時可以增刪改查。
Unity3D就是一個“組件式”的遊戲引擎,它使用各種各樣的的組件“拼裝”了遊戲物體,最終再把遊戲物體拼裝成遊戲。
上圖是一個Plane的自帶組件。
Unity3D爲我們提供了許多種類的組件。後期其實就是各種組件的使用和特性,以及它們能實現的功能和效果。
按照我們老祖宗的理論,五行是組成世界的最基本元素。那麼在Unity3D中,組件就是組成遊戲世界的最基本元素。
我總結出了上面一幅圖,這幅圖相當重要,大家需要認真看看。因爲這涉及到了遊戲物體與腳本中類和對象的聯繫。
2.Transform組件
在這裏提一個最最基本的組件之一——Transform組件。
Transform,中文爲“變換”,這個組件有三大基本屬性,Position(世界位置座標),Rotation(相對自身座標系的旋轉角度),Scale(相對於初始的縮放比例)。
這個組件是每一個遊戲物體都有的屬性,並且不能刪除。其實想想也是,在現實生活中,只要是一個物體必定有方位、旋轉、縮放的屬性。
通過修改這三大屬性的X\Y\Z值,我們就可以控制物體的“變換”信息了。這裏有一個小技巧,當把鼠標放到X\Y\Z上時,鼠標變成了可以左右拖動的標誌,可以直接左右拖動改變值,當然直接修改值也是ok的。
3.腳本
腳本(Script),也就是給遊戲物體寫的代碼,用來控制遊戲的邏輯。在Unity3D 5.x版本後,只支持C#腳本和JavaScript腳本。在國內開發的主流的C#。
4.創建與管理腳本
我們說過,Assets文件夾是總管,所以我們在Assets中新建一個Scripts文件夾,用來管理腳本資源。
在Scripts文件夾中右鍵-->Create-->C# Script。C#腳本文件的後綴是“.cs”。雙擊腳本文件,可以調用代碼編輯器進行編輯。
5.原始腳本代碼組成
在上一步我們新建了一個腳本,這次打開它看看究竟是什麼東東。
ok,我們看到這次unity幫我們新建立了一個類,類名就是我們的腳本文件名。然後它繼承自MonoBehaviour類,這個類呢,在unity的地位和作用,類似於在java中的Object類,所以重要性不言而喻。有興趣的童鞋可以去看看這個類的實現。可以看一下這篇文章:http://blog.csdn.net/yuyueliuliu/article/details/43795333。還能看到,這個腳本using了UnityEngine的引擎。然後unity還幫我們寫了兩個方法Start()和Update()。
Start():當遊戲運行起來,這個方法就會馬上執行且只執行一次。由此看來,這個方法非常適合做初始化的工作。事實上也是這樣的,我們常常在這個方法中做一些GetComponent()的操作。
Update():循環調用,每一幀就調用一次。我大致測了一下,一般的場景大概是每秒60次的樣子。
這裏還要介紹一個方法:Debug.Log()。這個用來輸出調試。如果你的目標是“helloworld”,ok,這個方法正好就是這樣。
順便提一句,Start()和Update()都是unity內部的“事件方法”,不需要我們人工調用,系統會自動調用和管理這些方法的。
6.使用腳本
- 直接將腳本拖拽到Hiearchy面板的物體上
- 直接將腳本拖拽到物體的Inspector面板上
運行遊戲,腳本自動執行。
這是一個first.cs腳本:
using UnityEngine; using System.Collections; public class first : MonoBehaviour { void Start () { Debug.Log("這是Start方法"); } void Update () { Debug.Log("這是Update方法"); } }
把它添加到燈光上,運行遊戲,控制檯效果:
上面我們已經知道了C#腳本的大致套路。說到寫代碼就是各位童鞋的長處了。這次我們實現一下讓遊戲讀出我們的輸入。
unity很友好地爲我們都寫好了方法,我們只需要調用這些接口就ok了。
1.獲取鍵盤輸入
案例如下:
1 using UnityEngine; 2 using System.Collections; 3 4 public class InputTest : MonoBehaviour { 5 6 void Update () { 7 if (Input.GetKey(KeyCode.A)) 8 { 9 Debug.Log("按下了A鍵"); 10 } 11 if (Input.GetKeyDown(KeyCode.A)) 12 { 13 Debug.Log("GetKeyDown"); 14 } 15 if (Input.GetKeyUp(KeyCode.A)) 16 { 17 Debug.Log("GetKeyUp"); 18 } 19 } 20 }
2.獲取鼠標輸入
直接上方法。
用法和監聽鍵盤輸入類似,在這裏就不再寫代碼舉例了(笑~)。
上面提到了鼠標鍵盤監聽控制,也提到了Transform組件,我們利用腳本,可以把兩者組合起來,實現通過鍵盤讓遊戲物體動起來!
備註:腳本也可以看成組件,一般是要控制哪個遊戲物體就把腳本掛載到哪個物體上。
下面就是一個例子:
1 using UnityEngine; 2 using System.Collections; 3 4 public class StudentMove : MonoBehaviour 5 { 6 private Transform trans; 7 8 // Use this for initialization 9 void Start() 10 { 11 trans = gameObject.GetComponent<Transform>(); 12 } 13 14 // Update is called once per frame 15 void Update() 16 { 17 if (Input.GetKey(KeyCode.W)) 18 { 19 trans.Translate(Vector3.forward * 0.1f, Space.World); 20 } 21 if (Input.GetKey(KeyCode.A)) 22 { 23 trans.Translate(Vector3.left * 0.1f, Space.World); 24 } 25 if (Input.GetKey(KeyCode.S)) 26 { 27 trans.Translate(Vector3.back * 0.1f, Space.World); 28 } 29 if (Input.GetKey(KeyCode.D)) 30 { 31 trans.Translate(Vector3.right * 0.1f, Space.World); 32 } 33 } 34 }
把這個腳本,拖到遊戲物體的Inspector面板上,然後點擊遊戲的“運行”按鈕,可以發現我們已經可以通過鍵盤的W\A\S\D鍵控制物體的前左後右的移動了!amazing!
在上面我們通過Transform組件實現了物體位置的移動,但是仔細研究一下發現了以下幾個特點:
- 移動的物體會“穿透”場景中其他的物體模型
- 移動的物體不會受到重力影響(即使到達場景之外,也不會下落)
這樣看起來物體動是動了,但是不太真實,和我們現實生活中有很大差別。
大家應該都聽過或者玩過《憤怒的小鳥》,小鳥的拋物線運動,石頭的坍塌,都是符合物理規律的。
我們說過,組件是構成遊戲物體的基礎。所以,我們需要其他組件來使物體符合物理規律。
1.剛體
剛體(Rigidbody),屬於物理類組件。添加了剛體組件的遊戲物體,就有了重力,就會做自由落體運動,也就實現了現實物體的物理運動。
選擇遊戲物體-->菜單欄點擊Componment-->Physics-->Rigidbody,給物體添加剛體組件成功!
2.常用屬性
看着上圖,我們瞭解一下它的幾個常用屬性。
Mass[質量],可以設置物體的質量,你可以認爲單位是KG。
Drag[阻力],一般是指空氣阻力,0表示沒有空氣阻力,空氣阻力越大,物體自由落體越慢。當值很大時,物體甚至會停止運動,漂浮在空中。
Angular Drag[角阻力],收到扭曲力時候的空氣阻力,0表示沒有阻力,當值很大時,物體甚至會停止運動。
Use Gravity[使用重力]。當勾選之後,如果物體掉入場景之外,會落入“深淵”。
3.在腳本中使用剛體組件移動遊戲物體
直接上腳本:
1 using UnityEngine; 2 using System.Collections; 3 4 public class RigidbodyMove : MonoBehaviour 5 { 6 private Transform trans; 7 private Rigidbody rigid; 8 9 // Use this for initialization 10 void Start() 11 { 12 trans = gameObject.GetComponent<Transform>(); 13 rigid = gameObject.GetComponent<Rigidbody>(); 14 } 15 16 // Update is called once per frame 17 void Update() 18 { 19 if (Input.GetKey(KeyCode.W)) 20 { 21 rigid.MovePosition(trans.position + Vector3.forward * 0.1f); 22 } 23 if (Input.GetKey(KeyCode.A)) 24 { 25 rigid.MovePosition(trans.position + Vector3.left * 0.1f); 26 } 27 if (Input.GetKey(KeyCode.S)) 28 { 29 rigid.MovePosition(trans.position + Vector3.back * 0.1f); 30 } 31 if (Input.GetKey(KeyCode.D)) 32 { 33 rigid.MovePosition(trans.position + Vector3.right * 0.1f); 34 } 35 } 36 }
代碼很簡略,但是卻實現了像現實物體一樣的物理運動,很神奇。
1.碰撞體
上面使用剛體組件的物體,在場景中其他物體可以產生碰撞的效果。其實碰撞目標物體的,是專門有一個組件來負責的,就是碰撞體組件(Collider)。
換個說法,我們控制的物體A與物體B的碰撞,實質上是物體A與物體B的碰撞體組件發生了作用關係。
碰撞體可以理解成我們模型的“外骨骼”。
這是一個什麼也沒有動的原來的Cube。
把物體的渲染器(上面的Renderer的勾選去掉)屏蔽,可以發現物體的碰撞體長得什麼樣子:
顯示的就是Cube外層的碰撞體組件。
只要我們創建了物體,unity就默認爲我們加上了碰撞體組件,沒有碰撞體的剛體是沒有意義的,就失去了剛體本該有的物理特性。
換句話說,物理特性是剛體組件和碰撞體組件一起表現出來的。
其實這一對“好基友”有很多很多的故事,大致總結了一下。
碰撞體組件按照它們的形狀,大致可以分爲以下幾類。
2.Box Collider
盒子碰撞體,形狀是立方體,用來包裹盒子狀的模型,比如箱子、門、房子,等等。有幾個常用屬性:
Is Trigger:設置是否爲觸發器。這個屬性非常重要,在後面講觸發器會經常使用。
Material:物理材質。
Center:碰撞體也可以設置中心點。一般來說碰撞體中心點就是物體的幾何中心點。
Size:設置物體的“外骨骼”的尺寸。
3.Sphere Collider
球形碰撞體,和上面的盒子碰撞體基本類似,Radius是半徑。
4.Capsule Collider
膠囊碰撞體,屬性和球形碰撞體類似,Direction是指設置它的高度的方向。
5.Mesh Collider
網格碰撞體,用來包裹複雜結構的模型
Mesh:根據指定的網格,生成碰撞體。
有了組件,必然有新帶來的方法。
1.AddForce()
作用:給剛體一個力,使剛體按照“世界座標系”進行運動。
其中的ForceMode是力的模式,是一個枚舉類型,決定以什麼樣的方式添加力給剛體。
1 using UnityEngine; 2 using System.Collections; 3 4 public class ForceTest : MonoBehaviour 5 { 6 private Rigidbody rigid; 7 void Start() 8 { //獲取物體的剛體組件 9 rigid = gameObject.GetComponent<Rigidbody>(); 10 } 11 void Update() 12 { //給剛體施加一個相對世界座標系向前的力 13 rigid.AddForce(Vector3.forward, ForceMode.Force); 14 } 15 }
2.AddRelativeForce()
作用:給剛體添加一個力,讓剛體按照“自身座標系”進行運動。
由此可以知道,AddForce()和AddRelativeForce()是非常像的,這倆其實就是雙胞胎,只不過一個是相對世界座標系,另一個是相對自身座標系罷了。
3.FixedUpdate()
這個是固定的更新方法。這個方法值得說道說道。一查網上資料還真不少,那就不獻醜了~
Update()方法是每一幀刷新一次,但是時間間隔是不確定的。而FixedUpdate()方法是固定時間間隔(默認0.02秒)刷新一次。
這個值是可以自己設定的。Edit-->Project Settings-->Time-->Fixed Timestep。
基本上和物理相關的操作,代碼都是寫在FixedUpdate()方法裏面。如果你寫在了Update()裏,會出現卡頓的現象。
1.碰撞事件簡介
啥叫“碰撞事件”呢?當一個用剛體控制的物體與另外一個物體碰撞時,就會觸發碰撞事件。
注:目標物體必須帶有Collider組件。
碰撞 Collision
比如,一個射擊類遊戲,我們發射了子彈,子彈是一個由剛體控制運動的物體。子彈射中了敵人,我們怎麼監測這個碰撞呢?
2.碰撞事件監測方法
- OnCollisionEnter(Collision) //當碰撞開始時調用,只會調用該方法一次
- OnCollisionExit(Collision) //當碰撞結束時調用,只會調用該方法一次
- OnCollisionStay(Collision) //當碰撞進行中時,會持續調用該方法
這個Collision參數是什麼呢?
這個是“碰撞”的一個類,用來傳遞碰撞信息。
Collision.gameObject屬性,與當前物體碰撞的物體的引用。
gameObject.name屬性,當前物體的名字。
上代碼示例:
1 using UnityEngine; 2 using System.Collections; 3 4 public class CollisionCube : MonoBehaviour { 5 6 void OnCollisionEnter(Collision coll) 7 { 8 if(coll.gameObject.name != "Ground") 9 Debug.Log ("Enter " + coll.gameObject.name); 10 } 11 12 void OnCollisionExit(Collision coll) 13 { 14 if(coll.gameObject.name != "Ground") 15 Debug.Log ("Exit " + coll.gameObject.name); 16 } 17 18 void OnCollisionStay(Collision coll) 19 { 20 if(coll.gameObject.name != "Ground") 21 Debug.Log ("Stay " + coll.gameObject.name); 22 } 23 24 }
1.觸發事件簡介
將碰撞體組件上的Is Trigger選項選中,當前的遊戲物體的碰撞體組件就變成了觸發器。
我想大家應該都理解“觸發器”的概念。
注:移動的剛體物體都會穿透碰撞體勾選了“Is Trigger”選項的物體。
當一個用剛體控制的物體進入到另一個物體的觸發器範圍內,就產生了觸發事件。
這個不與目標物體發生直接的碰撞(接觸),而是隻要進入目標物體的“觸發範圍”就能執行某些操作。
那怎麼設定“觸發範圍”呢?其實和我們上面設置碰撞體範圍的方法是一致的。
2.觸發事件監測方法
- OnTriggerEnter(Collider) //當進入觸發範圍開始時調用,只會調用該方法一次
- OnTriggerExit(Collider) //當退出觸發範圍開始時調用,只會調用該方法一次
- OnTriggerStay(Collider) //在觸發範圍內,會持續調用該方法
這個Collider參數是什麼呢?
這個是“碰撞體”的一個類,用來傳遞觸發信息。
Collision.gameObject屬性,進入觸發範圍內的目標物體的引用。
gameObject.name屬性,當前物體的名字。
1 using UnityEngine; 2 using System.Collections; 3 4 public class TriggerCube : MonoBehaviour { 5 6 void OnTriggerEnter(Collider coll) 7 { 8 Debug.Log (coll.gameObject.name+"on trigger enter"); 9 } 10 void OnTriggerStay(Collider coll) 11 { 12 Debug.Log (coll.gameObject.name+"on trigger stay"); 13 } 14 void OnTriggerExit(Collider coll) 15 { 16 Debug.Log (coll.gameObject.name+"on trigger exit"); 17 } 18 }
好了,當我們製作好了一個遊戲,怎麼把它發佈到各個平臺呢?
其實很簡單。untiy已經幫我們做好了絕大部分事情。
我們要做的事情:
1.Build Settings[生成設置]
2.Player Settings[詳細設置]
3.成品介紹
一個exe文件,一個data數據文件夾,兩者缺一不可。
這個階段我們從最簡單的組件與腳本學起,介紹了鼠標鍵盤的交互,怎麼移動物體,瞭解了剛體、碰撞體以及常用的幾個方法,還學習了怎麼打包發佈。那麼unity的基本操作差不多告一段落。雖然還有很多沒有介紹到,那我們在做demo的過程中再學再用吧。我還把上面介紹到的所有的方法和屬性寫了一個思維導圖文件,縮略圖:
詳細的地址:鏈接:http://pan.baidu.com/s/1dFMXvpf 密碼:8xq0
ok,今天告一段落。
------------------------------------9.26更新---------------------------------------------------------------------------------------------------------------
最近規劃了一下,發現看似簡單的一個demo做起來需要用到許多unity的其他知識,什麼動畫系統,粒子系統,物理引擎,所以準備開一個新的案例,如《貪吃蛇大作戰》等,補充自己的知識後,再來更好地做這個農藥的demo。再加上本人還是某不知名雙一流大學的學生,課程比較緊,期間會穿插其他知識,所以這個專欄更新會比較慢。