Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Unity遊戲程式設計(04) 2D運動與碰撞處理I

3,182 views

Published on

Updated on July 4, 2017
介紹使用剛體物件及碰撞器來控制物體移動及碰撞處理
使用多邊形碰撞器設計不規則按鈕
Update與FixedUpdate

Published in: Software
  • Be the first to comment

  • Be the first to like this

Unity遊戲程式設計(04) 2D運動與碰撞處理I

  1. 1. 電子工程系 Unity遊戲程式設計(04) 2D運動與碰撞處理I 吳錫修 July 4, 2017
  2. 2. shapethefuture  剛體是受物理引擎控制的元件  埸景中運動元件都應加上剛體  具備物理性質:質量 (Mass)、移動阻力 ( Linear Drag)、旋轉阻力 (Angular Drag)、重力 (Gravity Scale)  Body Type決定剛體的運動及碰撞互動特性,直接影響剛體的屬性 項目  Dynamic 動態剛體具有質量和阻力,並受重力和力的影響,並可在物理 模擬下移動。動態剛體會與其他剛體碰撞,也是最耗效能的剛體類型  Kinematic 運動剛體不受到重力和力的影響,可在物理模擬下移動,對 系統資源的要求較低  Static 靜態剛體是⼀個不可移動的物體 (就好像它有無限的質量)。只需 最少最少的系統資源 剛體 1/5 Wu, ShyiShiou Dept. of E.E., NKUT2
  3. 3. shapethefuture  動態剛體屬性  Material 剛體材料  Simulated 是否啟用物理引擎模擬剛體功能  Use Auto Mass 是否依據元件的碰撞器自動計算物體質量  Mass 物體質量  Linear Drag 物體移動的阻力係數  Angular Drag 物體旋轉的阻力係數 剛體 2/5 Wu, ShyiShiou Dept. of E.E., NKUT3
  4. 4. shapethefuture  Gravity Scale 物體受重力影響的程度  Collision Detection 碰撞檢測方式  Discrete 新位置產生時才檢測 如果物體移動速度太快,在物理更新期間,剛體可能與碰撞器重疊或 穿過  Continuous Unity先計算新位置座標是否碰撞再移動剛體。會耗用較多運算資源  Sleeping Mode 物體休眠模式,以節省處理器時間  Never Sleep 禁用休眠 (會影響系統資源,儘可能不用) 剛體 3/5 Wu, ShyiShiou Dept. of E.E., NKUT4
  5. 5. shapethefuture  Start Awake 初始為清醒  Start Asleep 初始為休眠,但可以被碰撞喚醒  Interpolate 在物理更新之間進行插值方式 (當運動趨於劇烈時有用)  None  Interpolate 基於前⼀幀中的位置計算插值使運動平滑  Extrapolate 基於其在下⼀幀中的位置計算插值使運動平滑  Constraints 是否限制剛體移動及旋轉 剛體 4/5 Wu, ShyiShiou Dept. of E.E., NKUT5
  6. 6. shapethefuture  運動剛體屬性  Use Full Kinematic Contacts 勾選時,運動剛體能與所有剛體產生碰撞;否則運動剛體只能與動態剛 體碰撞  其餘屬性詳見動態剛體屬性說明  靜態剛體屬性 剛體 5/5 Wu, ShyiShiou Dept. of E.E., NKUT6
  7. 7. shapethefuture  物理世界兩個物體撞在⼀起會發生碰撞,遊戲世界裡要透過碰撞器 來模擬現實世界的碰撞情形  碰撞器是在元件加入⼀層透明的偵測層,代表元件物理效應發生的 範圍  Component> Physics 2D選單內可找到所有碰撞器  Circle Collider 2D  Box Collider 2D  Polygon Collider 2D  Edge Collider 2D  Capsule Collider 2D  Composite Collider 2D 碰撞器 1/4 Wu, ShyiShiou Dept. of E.E., NKUT7
  8. 8. shapethefuture  Box Collider 2D (方框碰撞器)  適用於矩形物體  Circle Collider 2D (圓形碰撞器)  適用於球形物體  Edge Collider 2D (邊緣碰撞器)  適用於邊界、地板或天花板  可編輯/調整線段節點  即使將它編輯成矩形,也只有在線段上才會碰撞,內部不會產生碰撞  Polygon Collider 2D (多邊形碰撞器)  能較精準貼近不規則物體,但會耗用較多運算資源 碰撞器 2/4 Wu, ShyiShiou Dept. of E.E., NKUT8
  9. 9. shapethefuture  Capsule Collider 2D (膠囊碰撞器)  適用於⻑條形物體  Composite Collider 2D (複合碰撞器)  使用其它已設置的Box Collider 2D或Polygon Collider 2D之幾何頂點, 將它們合併成複合碰撞器幾何形狀 碰撞器 3/4 Wu, ShyiShiou Dept. of E.E., NKUT9
  10. 10. shapethefuture  Is Trigger屬性  通常道具元件會勾選Is Trigger  其它剛體可穿透被設定為Is Trigger之元件  剛體元件程式腳本可使用下列函式來處理碰撞事件 void OnTriggerEnter2D(Collider2D other) { //進入碰撞時 } void OnTriggerExit2D(Collider2D other) { //結束碰撞時 } 碰撞器 4/4 Wu, ShyiShiou Dept. of E.E., NKUT10
  11. 11. shapethefuture  新增2D專案  將不規則按鈕素材圖片拖曳到Assets/Sprites目錄  將triangle_blue、triangle_yellow、triangle_green拖曳到場景, 組合成大三角形 使用多邊形碰撞器設計不規則按鈕 1/4 Wu, ShyiShiou Dept. of E.E., NKUT triangle_blue triangle_yellow triangle_green 11
  12. 12. shapethefuture  設定Ploygon Collider 2D碰撞器  選取triangle_blue  選單命令Component>Physics 2D> Polygon Collider 2D  編輯多邊形碰撞器端點  Points>Size調整為3  點擊Edit Collider按鈕,調整端點位置使其 貼齊三角形邊緣 使用多邊形碰撞器設計不規則按鈕 2/4 Wu, ShyiShiou Dept. of E.E., NKUT12
  13. 13. shapethefuture  以同樣方式為triangle_yellow及triangle_green加入Ploygon Collider 2D碰撞器,並調整多邊形碰撞器端點  新增ButtonController程式腳本 public class ButtonController : MonoBehaviour { ... void Update () { } void OnMouseDown() { if(gameObject.name == "triangle_blue") Debug.Log("blue!"); if(gameObject.name == "triangle_green") Debug.Log("green!"); if(gameObject.name == "triangle_yellow") Debug.Log("yellow!"); } } 使用多邊形碰撞器設計不規則按鈕 3/4 Wu, ShyiShiou Dept. of E.E., NKUT13
  14. 14. shapethefuture  將ButtonController程式腳本加到triangle_xxx元件上  將ButtonController程式腳本拖曳到triangle_blue、triangle_green及 triangle_yellow元件上  執行遊戲專案  滑鼠點擊三角形時,console窗格會顯示按鈕顏色 使用多邊形碰撞器設計不規則按鈕 4/4 Wu, ShyiShiou Dept. of E.E., NKUT14
  15. 15. shapethefuture  更新座標方式 (要計算位移,物體移動比較生硬不自然) transform.Translate(Vector3.up * 0.1f); transform.Translate(Vector3.down * 0.1f); transform.Translate(Vector3.right * 0.1f); transform.Translate(Vector3.left * 0.1f);  對剛體物件施力 _rigidbody2D = this.GetComponent<Rigidbody2D>(); Vector2 force2D = Vector2.zero; force2D.y += forceValue; // force2D.x += forceValue; _rigidbody2D.AddForce(force2D); 物件移動控制 Wu, ShyiShiou Dept. of E.E., NKUT15
  16. 16. shapethefuture  下載2D UFO Tutorial 實作2D UFO遊戲 Wu, ShyiShiou Dept. of E.E., NKUT16
  17. 17. shapethefuture  新增場景,以ufo名稱存檔  將Background.png、Pickup.png及UFO.png素材滙入到專案 AssetsSprites資料夾 2D UFO遊戲素材 Wu, ShyiShiou Dept. of E.E., NKUT17
  18. 18. shapethefuture  將Background.png拖曳到場景  Position (X, Y, Z) = (0, 0, 0)  Main Camera元件  將Camera Background設定為黑色  將Camera Size設定為16.5 設定場景背景 Wu, ShyiShiou Dept. of E.E., NKUT18
  19. 19. shapethefuture  將UFO.png拖曳到場景  Position (X, Y, Z) = (0, 0, 0)  Scale (X, Y, Z) = (0.75, 0.75, 0.75)  Order in Layer = 1 加入UFO物件 Wu, ShyiShiou Dept. of E.E., NKUT19
  20. 20. shapethefuture  為UFO元件加入UFOController程式腳本 讓UFO動起來 1/3 Wu, ShyiShiou Dept. of E.E., NKUT20
  21. 21. shapethefuture  編輯UFOController程式如下: public float speed; void Update() { if (Input.GetKey(KeyCode.W)){ this.transform.position += new Vector3 (0, speed*Time.deltaTime, 0); } if (Input.GetKey (KeyCode.S)) { this.transform.position += new Vector3 (0, -speed*Time.deltaTime, 0); } if (Input.GetKey(KeyCode.A)) { this.transform.position += new Vector3 (-speed*Time.deltaTime, 0, 0); } if (Input.GetKey(KeyCode.D)){ this.transform.position += new Vector3 (speed*Time.deltaTime, 0, 0); } } 讓UFO動起來 2/3 Wu, ShyiShiou Dept. of E.E., NKUT21
  22. 22. shapethefuture  將UFO之Speed欄設定為10,執行測試。可以用W、A、S、D鍵移動飛 碟,但是…  飛碟移動並不自然  飛碟會穿透邊界 讓UFO動起來 3/3 Wu, ShyiShiou Dept. of E.E., NKUT22
  23. 23. shapethefuture  在UFO元件加上剛體性質  選取UFO元件  選單命令Component> Physics 2D> Rigidbody 2D  執行測試發現UFO會自動往下掉  把Gravity Scale改成0,模擬太空無重力狀態 改用物理加速度方式移動 1/3 Wu, ShyiShiou Dept. of E.E., NKUT23
  24. 24. shapethefuture  修改UFOController程式如下: public float speed; private Rigidbody2D _rigidbody2D = null; void Start () { _rigidbody2D = this.GetComponent<Rigidbody2D> (); } void FixedUpdate() { float moveHorizontal = Input.GetAxis ("Horizontal"); float moveVertical = Input.GetAxis ("Vertical"); Vector2 movement = new Vector2 (moveHorizontal, moveVertical); _rigidbody2D.AddForce (movement * speed); } 改用物理加速度方式移動 2/3 Wu, ShyiShiou Dept. of E.E., NKUT24
  25. 25. shapethefuture  ForceValue設定為3,執行測試;UFO能以加速度移動了,但是…  UFO還是會飛出邊界 改用物理加速度方式移動 3/3 Wu, ShyiShiou Dept. of E.E., NKUT25
  26. 26. shapethefuture  在UFO元件加入圓形碰撞器  選取UFO元件  選單命令Component> Physics 2D >Circle Collider 2D  調整Radius = 2.12,使讓圓形碰撞器大小符合UFO元件 設定UFO飛行邊界 1/2 Wu, ShyiShiou Dept. of E.E., NKUT26
  27. 27. shapethefuture  在Background元件加上邊緣碰撞器  選取Background元件  選單命令Component> Physics 2D> Edge Collider 2D  點擊Edit Collider按鈕,使邊緣碰撞器環繞背景內緣四週  執行測試,飛碟不會穿牆出去了 設定UFO飛行邊界 2/2 Wu, ShyiShiou Dept. of E.E., NKUT27
  28. 28. shapethefuture  將 Main Camera拖曳到UFO元件底下  執行測試  遊戲鏡頭會以飛碟為中心  飛碟撞到邊界,飛碟會旋轉;由於Camera鏡頭是跟附在飛碟上,飛碟 時旋轉遊戲鏡頭也會跟著旋轉 讓Camera鏡頭跟著飛碟移動 1/2 Wu, ShyiShiou Dept. of E.E., NKUT28
  29. 29. shapethefuture  Main Camera元件加入CameraController程式腳本,關閉鏡頭旋轉 public class CameraController : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { this.transform.eulerAngles = Vector3.zero; } }  執行測試  飛碟可以在邊界內飛行,背景圖也不會旋轉了 讓Camera鏡頭跟著飛碟移動 2/2 Wu, ShyiShiou Dept. of E.E., NKUT29
  30. 30. shapethefuture  將Pickup.png拖曳到場景,命名為Pickup  Order in Layer = 1  Tag = PickUp  加上剛體性質  選單命令Component> Physics 2D> Rigidbody 2D  Body Type設定為Kinematic 佈置金塊道具 1/5 Wu, ShyiShiou Dept. of E.E., NKUT30
  31. 31. shapethefuture  加入圓形碰撞器  選單命令Component> Physics 2D> Circle Collider 2D  勾選Is Trigger  Raduis = 1 佈置金塊道具 2/5 Wu, ShyiShiou Dept. of E.E., NKUT31
  32. 32. shapethefuture  Pickups元件加入PickupController程式腳本,讓金塊自主旋轉 public class PickupController : MonoBehaviour { public float RotateSpeed; // Use this for initialization void Start () { } // Update is called once per frame void Update () { this.transform.Rotate (new Vector3(0,0,RotateSpeed*Time.deltaTime)); } } 佈置金塊道具 3/5 Wu, ShyiShiou Dept. of E.E., NKUT32
  33. 33. shapethefuture  Rotate Speed設定為45  執行測試,金塊會自主旋轉 佈置金塊道具 4/5 Wu, ShyiShiou Dept. of E.E., NKUT33
  34. 34. shapethefuture  將Pickup元件拖曳到Assets/Prefabs資料夾,建立Pickup預製元件  從Assets/Prefabs資料夾拖曳Pickup預製元件到場景,擺設如下  執行測試  飛碟會穿過金塊 佈置金塊道具 5/5 Wu, ShyiShiou Dept. of E.E., NKUT34
  35. 35. shapethefuture  當飛碟碰到金塊,讓金塊消失;開啟UFOController.cs,加入以下 程式碼 void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.CompareTag ("PickUp")) { other.gameObject.SetActive(false); } } void OnTriggerExit2D(Collider2D other) { }  執行測試  飛碟碰到金塊時,金塊會自動消失了 讓UFO收集金塊 Wu, ShyiShiou Dept. of E.E., NKUT35
  36. 36. shapethefuture  選單命令GameObject> UI> Text新增Text元件, 命名為CountText  Anchor設為左上角  Pos (X, Y, Z) = (10, -10, 0) (依實際情形調整)  Width設為100,Height設為100  Pivot(X, Y) = (0, 1)  Text = CountText  Font Size設為14  Color設為黃色 顯示遊戲訊息 1/6 Wu, ShyiShiou Dept. of E.E., NKUT36
  37. 37. shapethefuture  選單命令GameObject> UI> Text新增Text元件, 命名為WinText  Anchor設為中心  Pos (X, Y, Z) = (0, 75, 0) (依實際情形調整)  Width設為160,Height設為30  Text設為WinText  Alignment設為置中  Font Size設為24  Color設為黃色 顯示遊戲訊息 2/6 Wu, ShyiShiou Dept. of E.E., NKUT37
  38. 38. shapethefuture  新增UI元件時,會自動建立Canvas元件,而如果場景中已經有畫布, 新增的 UI 元素將會自動成為此畫布的子物件  遊戲執行時,Canvas會依據Render Mode自動調整Canvas大小及 位置  Render Mode預設為Screen Space - Overlay 顯示遊戲訊息 3/6 Wu, ShyiShiou Dept. of E.E., NKUT Canvas Game resolution 38
  39. 39. shapethefuture  修改UFOController程式腳本,當飛碟收集到金塊時更新CountText 訊息,收集滿12個金塊時顯示You win! using UnityEngine; using UnityEngine.UI; public class ScoreManager : MonoBehaviour { public float speed; private Rigidbody2D _rigidbody2D = null; public Text countText; public Text winText; private int _count; void Start () { _rigidbody2D = this.GetComponent<Rigidbody2D> (); _count = 0; winText.text = ""; SetCountText (); } 顯示遊戲訊息 4/6 Wu, ShyiShiou Dept. of E.E., NKUT 注意Text是定義在Unity.Engine.UI底下 39
  40. 40. shapethefuture void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.CompareTag ("PickUp")) { other.gameObject.SetActive(false); _count = _count + 1; SetCountText (); } } void SetCountText() { countText.text = "Count: " + _count.ToString (); if (_count >= 12) winText.text = "You win!"; } } 顯示遊戲訊息 5/6 Wu, ShyiShiou Dept. of E.E., NKUT40
  41. 41. shapethefuture  選取UFO物件,然後把Score拖進ScoreManager的欄位 顯示遊戲訊息 6/6 Wu, ShyiShiou Dept. of E.E., NKUT41
  42. 42. shapethefuture  Update()  每個frame執行⼀次,更新週期是變動性的  用來進行  非剛體物件之移動  簡單計時器  讀取週邊輸入  FixedUpdate()  更新週期是固定的  用來進行剛體物件調整  選單命令Edit> Project Settings> Time Update()與FixedUpdate() 1/3 42 Wu, ShyiShiou Dept. of E.E., NKUT
  43. 43. shapethefuture  在Main Camera新增以下程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class UpdateAndFixedUpdate : MonoBehaviour { // Update is called once per frame void Update () { Debug.Log ("Update time: " + Time.deltaTime); } void FixedUpdate(){ Debug.Log ("FixedUpdate time: " + Time.deltaTime); } } Update()與FixedUpdate() 2/3 43 Wu, ShyiShiou Dept. of E.E., NKUT
  44. 44. shapethefuture Update()與FixedUpdate() 3/3 44 Wu, ShyiShiou Dept. of E.E., NKUT 會變動 固定 會變動

×