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遊戲程式設計(05) 2D移動與碰撞處理II

5,045 views

Published on

介紹使用剛體物件及碰撞器進行遊戲物件移動及碰撞處理

Published in: Software
  • Be the first to comment

Unity遊戲程式設計(05) 2D移動與碰撞處理II

  1. 1. 電子工程系應 用 電 子 組 電 腦 遊 戲 設 計 組 Unity遊戲程式設計(05) 2D移動與碰撞處理II 吳錫修 Oct 24, 2016
  2. 2. shapethefuture  遊戲世界裡必須透過碰撞器來模擬現實世界的物體碰撞情形  碰撞器是在元件加入⼀層透明的偵測層,代表元件物理效應發⽣的 範圍  選單命令Component>Physics 2D內可找到所有碰撞器  Rigidbody 2D (剛體)  具備物理性質:摩擦力 (Mass)、線性阻力 ( Linear Drag)、旋轉阻力 (Angular Drag)、重力 (Gravity Scale)  剛體會被碰撞器阻擋  IsKinematic屬性  設定為運動物件,本身不受重力影響  埸景中的活動物件都應使用剛體來實現 剛體、碰撞器與觸發器 1/3 2 Wu, ShyiShiou Dept. of E.E., NKUT
  3. 3. shapethefuture  碰撞器  Box Collider 2D (方框碰撞器)  適用於矩形物件上  Circle Collider 2D (圓形碰撞器)  適用於球形物件上  Edge Collider 2D (邊緣碰撞器)  適用於邊界、地板或天花板  可編輯/調整線段節點  Polygon Collider 2D (多邊形碰撞器)  能較精準貼近不規則物件,但會耗用較多運算資源 剛體、碰撞器與觸發器 2/3 3 Wu, ShyiShiou Dept. of E.E., NKUT
  4. 4. shapethefuture  觸發器  當碰撞器被設定Is Trigger屬性,即成為觸發器  剛體物件可以穿透觸發器物件,但支援碰撞偵測  剛體物件之程式腳本必須實作OnTriggerXXX2D函式來處理碰撞作業 void OnTriggerEnter2D(Collider2D other) { //進入碰撞時 } void OnTriggerStay2D(Collider2D other) { //在碰撞物上時 } void OnTriggerExit2D(Collider2D other) { //結束碰撞時 } 剛體、碰撞器與觸發器 3/3 4 Wu, ShyiShiou Dept. of E.E., NKUT
  5. 5. shapethefuture  在Update()中控制物件移動  更新座標方式 (自行計算位移,物體移動⽣硬不自然) 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); 物件移動控制 5 Wu, ShyiShiou Dept. of E.E., NKUT
  6. 6. shapethefuture  預設場景上的物件都是放置在Default圖層  Layer屬性是用來做碰撞管理  Sorting Layer是2D遊戲物體前後層次管理  同圖層物件則依Order in Layer值,數值較 大者在上層, 若Order in Layer值相同時依 Position Z值 (與Main Camera遠近) 遊戲圖層及碰撞管理 1/4 Wu, ShyiShiou Dept. of E.E., NKUT6
  7. 7. shapethefuture  管理圖層  選單命令Edit>Project Settings>Tags and Layers來管理圖層  在Sorting Layers增加Background、Interactive、Player圖層 遊戲圖層及碰撞管理 2/4 下層 上層 Wu, ShyiShiou Dept. of E.E., NKUT7 新增圖層
  8. 8. shapethefuture  將在Sorting Layers中加入的圖層,同步更新到Layers中 遊戲圖層及碰撞管理 3/4 8 Wu, ShyiShiou Dept. of E.E., NKUT
  9. 9. shapethefuture  碰撞管理  選單命令Edit>Project Settings>Physics 2D進行碰撞管理  設定Layer Collision Matrix  預設全部圖層間都會進行碰撞檢測處理  依據遊戲設計需求,設定圖層碰撞檢核 遊戲圖層及碰撞管理 4/4 9 Wu, ShyiShiou Dept. of E.E., NKUT
  10. 10. shapethefuture  冒險家可左、右移動及跳躍  冒險家接觸到毒霧會受傷  冒險家靠近寶箱時會顯示提示箭頭,此時按空白鍵可開啟寶箱 探險遊戲設計 1/2 10 Wu, ShyiShiou Dept. of E.E., NKUT
  11. 11. shapethefuture  新增2D遊戲專案  將預設場景以adventure名稱存檔  將floor.png、trap0.png、trap1.png、trap2.png、tresure0.png、 treasure1.png、up.png及主角分鏡素材滙入到專案AssetsSprite 資料夾  Main Camera  Size設定為16  Background設定為深藍色 探險遊戲設計 2/2 11 Wu, ShyiShiou Dept. of E.E., NKUT
  12. 12. shapethefuture  選單命令Edit>Project Settings>Tags and Layers  在Sorting Layers增加Background、Interactive、Player圖層  在Layers加入Background、Interactive、Player圖層 建立遊戲圖層 12 Wu, ShyiShiou Dept. of E.E., NKUT
  13. 13. shapethefuture  將floor拖曳到場景  Position設定為 (x, y, z) = (0, -8, 0)  Scale設定為 (x, y, z) = (2.5, 0.2, 1)  Sorting Layer設定為"Interactive"  Layer設定為"Interactive"  設定碰撞器  在floor加入 Edge Collider 20邊緣碰撞器  選單命令Component>Physics 2D>Edge Collider 2D 建造地板 13 Wu, ShyiShiou Dept. of E.E., NKUT
  14. 14. shapethefuture  下載主角素材 http://gameart.eu.org/files/adventure_girl.zip  將AssetsSpriteidle1拖曳到場景  命名為girl  Position設定為 (x, y, z) = (-16, -5, 0)  Sorting Layer設定為"Player"  Layer設定為"Player"  加入剛體性質  選單命令Component>Physics 2D>Rigidbody 2D  加入圓形碰撞器  選單命令Component>Physics 2D>Circle Collider 2D  Radius = 2.5,Offset X = -0.5 建立主角 14 Wu, ShyiShiou Dept. of E.E., NKUT
  15. 15. shapethefuture  選取girl物件  選單命令Window>Animation開啟動畫編輯器,使用girl分鏡素材建立 以下動畫  建立girl_idle動畫  建立girl_walk動畫  建立girl_jump動畫 建立主角動畫 15 Wu, ShyiShiou Dept. of E.E., NKUT
  16. 16. shapethefuture  選取girl物件  選單命令Window>Animator開啟Animator編輯器  建立⼀個名為act的Int參數  設定girl_idlegirl_walk動作狀態切換條件  取消Has Exit Time  Settings/Transtion Duration設為0  在Consitions中新增act Equals 1  設定girl_idlegirl_jump動作狀態切換條件  取消Has Exit Time  Settings/Transtion Duration設為0  在Consitions中新增act Equals 2 設定主角動畫狀態切換控制 1/2 16 Wu, ShyiShiou Dept. of E.E., NKUT
  17. 17. shapethefuture  設定其它狀態girl_idle動作狀態切換條件  勾選Has Exit Time  Settings/Exit Time設定為1  Settings/Transtion Duration設為0 設定主角動畫狀態切換控制 2/2 17 Wu, ShyiShiou Dept. of E.E., NKUT
  18. 18. shapethefuture  將AssetsSpritetrap0拖曳到場景  命名為trap  Position設定為 (x, y, z) = (6, -6, 0)  Scale設定為 (x, y, z) = (0.8, 0.8, 1)  Sorting Layer設定為"Interactive"  Layer設定為"Interactive"  在Tag欄新增"trap"標籤 製作陷阱道具 1/2 18 Wu, ShyiShiou Dept. of E.E., NKUT
  19. 19. shapethefuture  在trap物件加入方框碰撞器  選取trap物件  選單命令Component>Physics 2D>Circle Collider 2D  勾選「Is Trigger」屬性 (會偵測物體碰接,但允許剛體物件穿過)  Offset Y=-2.2,讓碰撞邊界比貼近陷阱外緣 製作陷阱道具 2/2 19 Wu, ShyiShiou Dept. of E.E., NKUT
  20. 20. shapethefuture  選取trap物件  選單命令Window>Animation開啟動畫編輯器,使用trap分鏡素材建立 以下動畫  建立trap動畫 製作陷阱道具動畫 20 Wu, ShyiShiou Dept. of E.E., NKUT
  21. 21. shapethefuture  將AssetsSpritetreasures0拖曳到場景  命名為treasure  Position設定為 (x, y, z) = (21, -6, 0)  Scale設定為 (x, y, z) = (0.6, 0.6, 1)  Sorting Layer設定為"Interactive"  Layer設定為"Interactive"  在Tag欄新增"treasure"標籤 製作寶箱道具 1/6 21 Wu, ShyiShiou Dept. of E.E., NKUT
  22. 22. shapethefuture  在treasure物件加入方框碰撞器  選取treasure物件  Component->Physics 2D->Box Collider 2D  勾選「Is Trigger」屬性  將up素材拖曳到treasure物件上,做為treasure的子物件  命名為up  Position設定為 (x, y, z) = (0, 6.5, 0) 製作寶箱道具 2/6 22 Wu, ShyiShiou Dept. of E.E., NKUT
  23. 23. shapethefuture  在treasure物件加入TreasureControl程式腳本 public class TreasureControl : MonoBehaviour { public Sprite open; //寶箱已開啟之Sprite圖片 public bool isOpen; //寶箱狀態 private bool _isShow = false; //指示箭頭顯示旗號 private float _alpha = 0.0f; private float _da = -0.01f; private GameObject _prompt; private SpriteRenderer _upSprite; void Awake () { _prompt=GameObject.Find("up"); //指示箭頭物件參照 _prompt.gameObject.SetActive (_isShow); //隱藏指示箭頭 } void Start () { _upSprite = _prompt.GetComponent<SpriteRenderer> (); } 製作寶箱道具 3/6 23 Wu, ShyiShiou Dept. of E.E., NKUT
  24. 24. shapethefuture // Update is called once per frame void Update () { if (isOpen) { //寶箱已被開啟 this.GetComponent<SpriteRenderer> ().sprite = open; _prompt.gameObject.SetActive (false); //隱藏指示箭頭 } else { if (_isShow) { _alpha += _da; //使指示箭頭淡入淡出動態顯示 _upSprite.material.color = new Color (1f, 1f, 1f, _alpha); if (_alpha>1.0f || _alpha<0.0f) _da = -_da; } } } 製作寶箱道具 4/6 24 Wu, ShyiShiou Dept. of E.E., NKUT
  25. 25. shapethefuture //玩家到達寶箱位置 void OnTriggerEnter2D(Collider2D c) { if (c.gameObject.name == "girl") { _isShow = true; _prompt.gameObject.SetActive (_isShow); //顯示指示箭頭 } } //玩家離開寶箱位置 void OnTriggerExit2D(Collider2D c) { if (c.gameObject.name == "girl") { _isShow = false; _prompt.gameObject.SetActive (_isShow); //隱藏指示箭頭 _alpha = 0.0f; } } } 製作寶箱道具 5/6 25 Wu, ShyiShiou Dept. of E.E., NKUT
  26. 26. shapethefuture  將AssetsSpritetreasures1素材(寶箱開啟圖片)拖曳到寶箱之 Treasure Control下的Open屬性 製作寶箱道具 6/6 26 Wu, ShyiShiou Dept. of E.E., NKUT
  27. 27. shapethefuture  在girl物件加入GirlControl程式腳本 public class GirlControl : MonoBehaviour { private Animator _animator; //主角動畫控制器 public float speed = 10f; //主角移動速度 private float _alpha = 0.0f; private float _da = -0.1f; private SpriteRenderer _playerSprite; private bool _isInjure = false; //主角跳躍旗號 private bool _isJump = false; //主角跳躍旗號 // Use this for initialization void Start () { _animator = this.GetComponent<Animator> (); _playerSprite = this.GetComponent<SpriteRenderer> (); } 設計主角程式腳本 1/5 27 Wu, ShyiShiou Dept. of E.E., NKUT
  28. 28. shapethefuture //動畫撥放副程式 private void PlayAnimation(int action){ _animator.SetInteger ("act", action); } // Update is called once per frame void Update () { if (Input.GetKey (KeyCode.RightArrow)) { this.transform.eulerAngles = Vector3.zero; //使主角面向右 this.transform.Translate (speed * Time.deltaTime, 0, 0); //主角向右移動 if (!_isJump) PlayAnimation (2); //跑步動畫 } else if (Input.GetKey (KeyCode.LeftArrow)) { this.transform.eulerAngles = new Vector3 (0, 180, 0); //使主角面向左 this.transform.Translate (speed * Time.deltaTime, 0, 0); //主角向左移動 if (!_isJump) PlayAnimation (2); //跑步動畫 } 設計主角程式腳本 2/5 28 Wu, ShyiShiou Dept. of E.E., NKUT
  29. 29. shapethefuture else if (Input.GetKey (KeyCode.UpArrow)) { if (!_isJump) { this.GetComponent<Rigidbody2D> ().AddForce (Vector2.up * 500); _isJump = true; //主角為跳躍狀態 PlayAnimation (1); //跳躍動畫 } } else if (!_isJump) { PlayAnimation (0); } if (_isInjure) { //顯示主角受傷效果 _alpha += _da; _playerSprite.material.color = new Color (1f, 1f, 1f, _alpha); if (_alpha > 1.0f || _alpha < 0.0f) _da = -_da; } } 設計主角程式腳本 3/5 29 Wu, ShyiShiou Dept. of E.E., NKUT
  30. 30. shapethefuture void OnTriggerEnter2D(Collider2D c) { if (c.gameObject.tag == "trap") { //主角碰到陷阱 _isInjure = true; //主角為受傷狀態 } } void OnTriggerExit2D(Collider2D c) { if (c.gameObject.name == "trap") { //主角脫離陷阱 _isInjure = false; //主角為正常狀態 _playerSprite.material.color = new Color (1f, 1f, 1f, 1f); } } 設計主角程式腳本 4/5 30 Wu, ShyiShiou Dept. of E.E., NKUT
  31. 31. shapethefuture void OnTriggerStay2D (Collider2D c) { if (c.gameObject.tag == "treasure") { //主角在寶箱處 if (Input.GetKeyDown (KeyCode.Space)) { //按空白鍵取得寶藏 c.gameObject.GetComponent<TreasureControl>().isOpen=true; } } } void OnCollisionEnter2D(Collision2D c) { if (c.gameObject.name == "floor") { //主角接觸地板 _isJump = false; } } } 設計主角程式腳本 5/5 31 Wu, ShyiShiou Dept. of E.E., NKUT

×