unity遊戲程式設計(05) 2d移動與碰撞處理ii

31
電子工程系 電腦遊戲設計組 Unity遊戲程式設計(05) 2D移動與碰撞處理II 吳錫修 Oct 24, 2016

Upload: -

Post on 23-Jan-2018

2.664 views

Category:

Software


0 download

TRANSCRIPT

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

電子工程系應 用 電 子 組電 腦 遊 戲 設 計 組

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

吳錫修

Oct 24, 2016

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

shap

e th

e fu

ture

遊戲世界裡必須透過碰撞器來模擬現實世界的物體碰撞情形

碰撞器是在元件加入⼀層透明的偵測層,代表元件物理效應發⽣的範圍

選單命令Component>Physics 2D內可找到所有碰撞器

Rigidbody 2D (剛體)

具備物理性質:摩擦力 (Mass)、線性阻力 ( Linear Drag)、旋轉阻力(Angular Drag)、重力 (Gravity Scale)

剛體會被碰撞器阻擋

IsKinematic屬性

設定為運動物件,本身不受重力影響

埸景中的活動物件都應使用剛體來實現

剛體、碰撞器與觸發器 1/3

2 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

碰撞器

Box Collider 2D (方框碰撞器)

適用於矩形物件上

Circle Collider 2D (圓形碰撞器)

適用於球形物件上

Edge Collider 2D (邊緣碰撞器)

適用於邊界、地板或天花板

可編輯/調整線段節點

Polygon Collider 2D (多邊形碰撞器)

能較精準貼近不規則物件,但會耗用較多運算資源

剛體、碰撞器與觸發器 2/3

3 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

觸發器

當碰撞器被設定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

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

shap

e th

e fu

ture

在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

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

shap

e th

e fu

ture

預設場景上的物件都是放置在Default圖層

Layer屬性是用來做碰撞管理

Sorting Layer是2D遊戲物體前後層次管理

同圖層物件則依Order in Layer值,數值較大者在上層, 若Order in Layer值相同時依Position Z值 (與Main Camera遠近)

遊戲圖層及碰撞管理 1/4

Wu, ShyiShiou Dept. of E.E., NKUT6

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

shap

e th

e fu

ture

管理圖層

選單命令Edit>Project Settings>Tags and Layers來管理圖層

在Sorting Layers增加Background、Interactive、Player圖層

遊戲圖層及碰撞管理 2/4

下層

上層

Wu, ShyiShiou Dept. of E.E., NKUT7

新增圖層

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

shap

e th

e fu

ture

將在Sorting Layers中加入的圖層,同步更新到Layers中

遊戲圖層及碰撞管理 3/4

8 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

碰撞管理

選單命令Edit>Project Settings>Physics 2D進行碰撞管理

設定Layer Collision Matrix

預設全部圖層間都會進行碰撞檢測處理

依據遊戲設計需求,設定圖層碰撞檢核

遊戲圖層及碰撞管理 4/4

9 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

冒險家可左、右移動及跳躍

冒險家接觸到毒霧會受傷

冒險家靠近寶箱時會顯示提示箭頭,此時按空白鍵可開啟寶箱

探險遊戲設計 1/2

10 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

新增2D遊戲專案

將預設場景以adventure名稱存檔

將floor.png、trap0.png、trap1.png、trap2.png、tresure0.png、treasure1.png、up.png及主角分鏡素材滙入到專案Assets\Sprite資料夾

Main Camera

Size設定為16

Background設定為深藍色

探險遊戲設計 2/2

11 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

選單命令Edit>Project Settings>Tags and Layers

在Sorting Layers增加Background、Interactive、Player圖層

在Layers加入Background、Interactive、Player圖層

建立遊戲圖層

12 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

將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

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

shap

e th

e fu

ture

下載主角素材 http://gameart.eu.org/files/adventure_girl.zip

將Assets\Sprite\idle1拖曳到場景

命名為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

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

shap

e th

e fu

ture

選取girl物件

選單命令Window>Animation開啟動畫編輯器,使用girl分鏡素材建立以下動畫

建立girl_idle動畫

建立girl_walk動畫

建立girl_jump動畫

建立主角動畫

15 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

選取girl物件

選單命令Window>Animator開啟Animator編輯器

建立⼀個名為act的Int參數

設定girl_idlegirl_walk動作狀態切換條件

取消Has Exit Time

Settings/Transtion Duration設為0

在Consitions中新增act Equals 1

設定girl_idlegirl_jump動作狀態切換條件

取消Has Exit Time

Settings/Transtion Duration設為0

在Consitions中新增act Equals 2

設定主角動畫狀態切換控制 1/2

16 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

設定其它狀態girl_idle動作狀態切換條件

勾選Has Exit Time

Settings/Exit Time設定為1

Settings/Transtion Duration設為0

設定主角動畫狀態切換控制 2/2

17 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

將Assets\Sprite\trap0拖曳到場景

命名為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

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

shap

e th

e fu

ture

在trap物件加入方框碰撞器

選取trap物件

選單命令Component>Physics 2D>Circle Collider 2D

勾選「Is Trigger」屬性 (會偵測物體碰接,但允許剛體物件穿過)

Offset Y=-2.2,讓碰撞邊界比貼近陷阱外緣

製作陷阱道具 2/2

19 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

選取trap物件

選單命令Window>Animation開啟動畫編輯器,使用trap分鏡素材建立以下動畫

建立trap動畫

製作陷阱道具動畫

20 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

將Assets\Sprite\treasures0拖曳到場景

命名為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

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

shap

e th

e fu

ture

在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

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

shap

e th

e fu

ture

在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

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

shap

e th

e fu

ture

// Update is called once per framevoid 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

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

shap

e th

e fu

ture

//玩家到達寶箱位置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

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

shap

e th

e fu

ture

將Assets\Sprite\treasures1素材(寶箱開啟圖片)拖曳到寶箱之Treasure Control下的Open屬性

製作寶箱道具 6/6

26 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

在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 initializationvoid Start () {_animator = this.GetComponent<Animator> ();_playerSprite = this.GetComponent<SpriteRenderer> ();

}

設計主角程式腳本 1/5

27 Wu, ShyiShiou Dept. of E.E., NKUT

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

shap

e th

e fu

ture

//動畫撥放副程式private void PlayAnimation(int action){_animator.SetInteger ("act", action);

}

// Update is called once per framevoid 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

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

shap

e th

e fu

ture

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

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

shap

e th

e fu

ture

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

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

shap

e th

e fu

ture

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