SlideShare a Scribd company logo
1 of 52
Download to read offline
2D移動與碰撞處理II
Revised on October 10, 2019
 使用剛體、碰撞器與觸發器
 遊戲圖層及碰撞管理
 探險遊戲關卡設計
 剛體是具物理性質的元件,可使物件在物理引擎控制下擬真運動
 由選單命令Component> Physics 2D> Rigidbody 2D為物件套用2D
剛體元件
 物理性質:質量(Mass)、移動阻力( Linear Drag)、旋轉阻力(Angular
Drag)、重力(Gravity Scale)
 運動剛體(Kinematic)不受重力及外力影響
 埸景中的活動物件可使用剛體來實現
 真實世界兩個物體撞在⼀起會發⽣碰撞,遊戲世界裡要透過碰撞器來
模擬現實世界的碰撞情形
 碰撞器像是包覆在物件上的透明防護罩,代表物件實體邊界
 加了碰撞器之剛體物件會被其它碰撞器阻隔
剛體、碰撞器與觸發器 1/5
2
 我們可依物件外觀,由選單命令Component> Physics 2D中選用合適
的碰撞器
 Box Collider 2D(方框碰撞器)
 適用於矩形物體
 Circle Collider 2D(圓形碰撞器)
 適用於圓形物體
 Edge Collider 2D(邊緣碰撞器)
 適用於邊界、地板或天花板
 可編輯/調整線段節點,即使編輯成封閉迴路,也只有在線段上才會碰
撞,其內部不會產⽣碰撞
剛體、碰撞器與觸發器 2/5
3
Circle Collider
Box Collider
 Polygon Collider 2D(多邊形碰撞器)
 能較精準貼近不規則物體,但耗用較多運算資源
 Capsule Collider 2D(膠囊碰撞器)
 適用於膠囊形狀物體
 Composite Collider 2D(複合碰撞器)
 用來將子物件的碰撞器(Box Collider 2D及Polygon Collider 2D)
合併成⼀個碰撞器
 子物件勾選Used By Composite
 會自動附加Rigidbody 2D元件
剛體、碰撞器與觸發器 2/5
4
Polygon Collider Capsule Collider
Composite Collider 2D
Polygon Collider
Box Collider
 兩個具有碰撞器之物件相互碰觸時,程式腳本可以實作
OnCollisionXXX2D函式來處理碰撞作業
void OnCollisionEnter2D (Collision2D other) {
//進入碰撞時
}
void OnCollisionStay2D(Collision2D other) {
//在碰撞物上時
}
void OnCollisionExit2D(Collision2D other) {
//結束碰撞時
}
剛體、碰撞器與觸發器 4/5
5
 觸發器
 當碰撞器被設定Is Trigger屬性,即成為觸發器;其它碰撞器物件可以穿
過觸發器物件
 通常道具元件會加上觸發器
 在物件之程式腳本可使用下列函式來處理碰撞事件
void OnTriggerEnter2D(Collider2D other) {
//進入碰撞範圍時
}
void OnTriggerStay2D(Collider2D other) {
//在碰撞物上時
}
void OnTriggerExit2D(Collider2D other) {
//脫離碰撞範圍時
}
剛體、碰撞器與觸發器 5/5
6
 更新座標方式 (自行計算位移,物體移動⽣硬不自然)
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);
遊戲物件移動控制
7
遊戲圖層及碰撞管理 1/4
8
 預設場景上的物件都是放置在Default圖層
 Layer用來做遊戲物件碰撞管理
 Sorting Layer用來管理場景物件前後層次
 同Sorting Layer之物件,Order in Layer
數值較大者在上層;若Order in Layer值也
相同,則由Position Z值(與Main Camera
遠近)決定
 Layer屬性與Sorting Layer屬性二者並不相關
 管理圖層
 選單命令Edit> Project Settings> Tags and Layers管理圖層
 在Sorting Layers增加Background、Interactive、Player圖層
遊戲圖層及碰撞管理 2/4
9
下層
上層新增圖層
 將在Sorting Layers中加入的圖層,同步更新到Layers清單中
遊戲圖層及碰撞管理 3/4
10
 碰撞管理
 選單命令Edit> Project Settings> Physics 2D進行碰撞管理
 設定Layer Collision Matrix
 預設全部圖層間都會進行碰撞檢測處理
 依據遊戲設計需求,設定圖層間的碰撞檢核
遊戲圖層及碰撞管理 4/4
11
 忍者可左、右移動、跳躍及射飛標
 忍者必須先射飛標消滅飛龍,才能躍過山溝
 忍者接觸到毒霧會受傷
 忍者靠近寶箱時會顯示提示箭頭,此時按空白鍵可開啟寶箱
探險遊戲關卡設計
12
 新增2D遊戲專案,將預設場景以main名稱存檔
 在Assets下建立以下資料夾
 Animations
 Prefabs
 Scripts
 Sprites
 SpritesNinja
建立遊戲專案 1/2
13
 將忍者動作分鏡圖匯入到AssetsSpritesNinja資料夾
 將background.png、trap0.png、trap1.png、trap2.png、
tresure0.png、treasure1.png、up.png、dragon.png素材滙入到
AssetsSprites資料夾
 Main Camera
 Size設定為16
建立遊戲專案 2/2
14
 選單命令Edit> Project Settings> Tags and Layers
 在Sorting Layers增加Background、Interactive、Player圖層
 在Layers加入Background、Interactive、Player圖層
建立遊戲圖層 1/2
15
 設定圖層碰撞關係
 選單命令Edit> Project Settings> Physics 2D進行碰撞管理
 設定Layer Collision Matrix,啟用以下碰撞檢核
 Player與Backgound
 Player與Interactive
建立遊戲圖層 2/2
16
 將background.png拖曳到場景,命名為Background
 Position(X,Y,Z) = (48.5, 0, 0)
 Scale(X,Y,Z) = (8, 8, 1)
 Layer = Background
 Sorting Layer = Background
 設定地面邊界
 選單命令Component> Physics 2D> Edge Collider 2D加入邊緣碰
撞器
 點擊Edit Collider編輯邊緣碰撞器,使其貼齊山谷左側地面
 選單命令Component> Physics 2D> Edge Collider 2D加入邊緣碰
撞器
 點擊Edit Collider編輯邊緣碰撞器,使其貼近貼齊山谷右側地面
建造背景及地面邊界
17
 點選AssetsSpritesdragon
 Sprite Mode = Multiple
 點擊Sprite Editor
 套用自動分割,並調整每個分鏡圖片座標基準點(Pivot)到胸口位置
建立飛龍 1/4
18
Pivot
 將dragon_0.png拖曳到場景,命名為Dragon
 Position(X,Y,Z) = (-3.5, -4, 0)
 Rotation(X,Y,Z) = (0, 180, 0)
 Scale(X,Y,Z) = (3, 3, 1)
 Layer = Interactive
 Sorting Layer = Interactive
 設定碰撞器
 選單命令Component> Physics 2D> Circle Collider 2D加入圓形
碰撞器
建立飛龍 2/4
19
 製作飛龍動畫
 選單命令Window> Animation> Animation開啟動畫編輯器,使用
dragon分鏡素材建立編輯飛龍動畫
建立飛龍 3/4
20
 加入Dragon程式腳本,飛龍被飛標擊中會損血,⽣命值歸零時消失
public class Dragon : MonoBehaviour {
[SerializeField]
private int life = 3;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter2D(Collider2D c) {
if (c.tag == "dart") life--;
if (life == 0) Destroy(this.gameObject);
}
}
建立飛龍 4/4
21
 點選AssetsSpritesNinja忍者動作分鏡圖片
 Texture Type = Sprite(2D and UI)
 透過Sprite Editor將所有忍者動作分鏡圖片的座標基準點(Pivot)
調整到角色雙腳底部重心位置
建立忍者角色 1/3
22
Pivot
 將AssetsSpritesNinjaidle_000拖曳到場景,命名為Ninja
 Position(X,Y,Z) = (-26, -9, 0)
 Sorting Layer = Player
 Layer = Player
 選單命令Component> Physics 2D> Rigidbody 2D加入剛體元件
 勾選Use Auto Mass
 Gravity Scale = 1.5
 勾選Freeze Rotation Z
 選單命令Component> Physics 2D> Capsule Collider 2D加入膠囊碰
撞器
 適當調整Offset(X, Y)及Size(X, Y)
建立忍者角色 2/3
23
 製作角色動畫
選單命令Window> Animation> Animation開啟動畫編輯器,使用Ninja
分鏡素材建立以下動畫
 建立ninja_idle動畫 (1秒)
 建立ninja_run動畫 (0.5秒)
 建立ninja_jump動畫 (1秒)
 建立ninja_throw動畫 (1秒)
建立忍者角色 3/3
24
 拖曳Kunai到場景中,命名為Dart
 Rotation(X,Y,Z) = (0, 0, -90)
 Layer = Player
 Sorting Layer = Player
 Tag = dart
 選單命令Component> Physics 2D> Rigirbody 2D加入剛體
 Gravity Scale=0
 選單命令Component> Physics 2D> Box Collider 2D加入矩形碰撞器
 勾選Is Trigger
製作飛鏢預製物件 1/3
25
 在Dart物件加上Dart程式腳本
public class Dart : MonoBehaviour{
//Use this for initialization
public float speed;
void Start(){
GetComponent<Rigidbody2D>().velocity = new Vector2(speed, 0.0f);
}
//Update is called once per frame
void Update(){
}
private void OnBecameInvisible(){ //飛出畫面
Destroy(this.gameObject);
}
void OnTriggerEnter2D(Collider2D c) { //射到其它物件
Destroy(this.gameObject);
}
}
製作飛鏢預製物件 2/3
26
 將Dart之Speed欄位設為10
 執行測試,飛標會向右射出,飛出場景時會
自動消失
 測試無誤後,由Hierarchy面板將Dart物件
拖曳到Prefabs資料夾,做成預製物件
 刪除場景上Dart物件
製作飛鏢預製物件 3/3
27
 選單命令GameObject> Create Empty,更名為Dart Spawn
 Position(X,Y,Z) = (0, 0, 0)
 Rotation(X,Y,Z) = (0, 0, -90)
 Scale(X,Y,Z) = (1, 1, 1)
 Layer = Player
 拖曳Dart Spawn成為Ninja子物件
 調整Dart Spawn位置到Ninja之前端,Position(X,Y,Z) = (2.1, 2.15, 0)
設定飛鏢發射點
28
 在Ninja物件加上NinjaController程式腳本
public class NinjaController : MonoBehaviour{
[SerializeField]
private GameObject dart;
[SerializeField]
private Transform dartSpawn;
private bool facingRight = true; //主角面向右旗號
...
public void ThrowDart(){
float speed;
speed = System.Math.Abs(dart.gameObject.GetComponent<Dart>().speed);
if (facingRight)
dart.gameObject.GetComponent<Dart>().speed = speed;
else
dart.gameObject.GetComponent<Dart>().speed = -speed;
Instantiate(dart, dartSpawn.position, dartSpawn.rotation);
}
}
飛鏢發射控制 1/3
29
 拖曳AssetsPrefabsDart預製物件到Ninja Controller之Dart欄
 拖曳Dart Spawn物件到Ninja Controller之Dart Spawn欄
飛鏢發射控制 2/3
30
 修改ninja_throw動畫,在時間軸0:15處新增Animation Event,設
定ThrowDart()做為事件函式
飛鏢發射控制 3/3
31
 選取Ninja物件
 選單命令Window> Animator,開啟Animator編輯器
 建立動畫狀態之間轉換
忍者狀態控制 1/7
32
 建立⼀個名為action的Int參數
 設定ninja_idle ninja_run狀態切換條件
 取消Has Exit Time
 Settings/Transtion Duration = 0
 在Consitions中新增action Equals 1
 設定ninja_idle ninja_jump狀態切換條件
 取消Has Exit Time
 Settings/Transtion Duration = 0
 在Consitions中新增action Equals 2
忍者狀態控制 2/7
33
 設定ninja_idle ninja_throw狀態切換條件
 取消Has Exit Time
 Settings/Transtion Duration設為0
 在Consitions中新增Action Equals 3
 設定ninja_run ninja_idle狀態切換條件
 取消Has Exit Time
 Settings/Transtion Duration = 0
 在Consitions中新增action Equals 0
忍者狀態控制 3/7
34
 設定ninja_jump ninja_idle狀態切換條件
 取消Has Exit Time
 Settings/Transtion Duration = 0
 在Consitions中新增action Equals 0
 設定ninja_throw ninja_idle狀態切換條件
 勾選Has Exit Time
 Settings/Exit Time = 1
 Settings/Transtion Duration設為0
 在Consitions中新增action Equals 0
忍者狀態控制 4/7
35
 編輯NinjaController程式腳本
public class NinjaController : MonoBehaviour{
...
private bool facingRight = true; //主角面向右旗號
[SerializeField]
private int speed = 10; //移動速度
private Animator animator;
private Rigidbody2D rigid;
private Vector3 startPos;
private bool isJump = false; //主角跳躍旗號
// Use this for initialization
void Start(){
animator = this.GetComponent<Animator>();
startPos = transform.position;
rigid = this.GetComponent<Rigidbody2D> ();
}
忍者狀態控制 5/7
36
void Update() {
if (Input.GetKey (KeyCode.RightArrow)) {
facingRight = true;
this.transform.eulerAngles = Vector3.zero; //使主角面向右
this.transform.Translate (speed*Time.deltaTime, 0, 0); //主角向右移動
if (!isJump) PlayAnimation (1); //跑步動畫
} else if (Input.GetKey (KeyCode.LeftArrow)) {
facingRight = false;
this.transform.eulerAngles = new Vector3 (0, 180, 0); //使主角面向左
this.transform.Translate (speed*Time.deltaTime, 0, 0); //主角向左移動
if (!isJump) PlayAnimation (1); //跑步動畫
} else if (Input.GetKeyDown (KeyCode.UpArrow)) {
if (!isJump) {
rigid.velocity = new Vector2(rigid.velocity.x, rigid.velocity.y+speed);
isJump = true; //主角進入跳躍狀態
PlayAnimation (2); //跳躍動畫
}
} else if (Input.GetKeyDown (KeyCode.X)) PlayAnimation (3); //射飛鏢動畫
else if (!isJump) PlayAnimation (0); //閒置動畫
}
忍者狀態控制 6/7
37
private void PlayAnimation(int action){
animator.SetInteger("action", action);
}
private void OnBecameInvisible(){
transform.position = startPos;
}
void OnCollisionEnter2D(Collision2D c) {
if (c.gameObject.name == "Background") { //主角接觸地板
isJump = false;
}
}
...
}
 測試遊戲專案
忍者狀態控制 7/7
38
 將AssetsSpritestrap0拖曳到場景
 命名為Trap
 Position(X,Y,Z) = (10, -11, 0)
 Rotation(X,Y,Z) = (0, 0, -3)
 Scale(X,Y,Z) = (0.6, 0.6, 1)
 Layer = Interactive
 Sorting Layer = Interactive
 Tag = trap
建立陷阱道具 1/2
39
 選單命令Component> Physics 2D> Circle Collider 2D加入圓形碰
撞器
 勾選「Is Trigger」屬性 (會偵測物體碰接,但允許剛體物件穿過)
 Offset Y = -2.25,讓碰撞邊界貼近陷阱外緣
建立陷阱道具 2/2
40
 選取Trap物件
 選單命令Window> Animation> Animation開啟動畫編輯器,使用trap
分鏡素材建立trap動畫
製作陷阱道具動畫
41
 將AssetsSpritestreasures0拖曳到場景
 命名為Treasure
 Position(X,Y,Z) = (24.5, -8, 0)
 Scale(X,Y,Z) = (0.6, 0.6, 1)
 Layer = Interactive
 Sorting Layer = Interactive
 Tag = treasure
建立寶箱道具 1/2
42
 選單命令Component> Physics 2D> Box Collider 2D加入矩形碰撞器
 勾選「Is Trigger」屬性
 將up素材拖曳到treasure物件上,做為treasure的子物件
 命名為up
 Position(X,Y,Z) = (0, 5, 0)
 Size(X,Y,Z) = (0.6, 0.6, 1)
 Sorting Layer = Interactive
 Layer = Interactive
建立寶箱道具 2/2
43
 在Treasure物件加入TreasureControl程式腳本
public class TreasureControl : MonoBehaviour {
[SerializeField]
private 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> ();
}
設計寶箱程式腳本 1/4
44
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;
}
}
設計寶箱程式腳本 2/4
45
void OnTriggerEnter2D (Collider2D c) { //玩家到達寶箱位置
if (c.gameObject.name == "Ninja") {
isShow = true;
prompt.gameObject.SetActive (isShow); //顯示指示箭頭
}
}
void OnTriggerExit2D (Collider2D c) { //玩家離開寶箱位置
if (c.gameObject.name == "Ninja") {
isShow = false;
prompt.gameObject.SetActive (isShow); //隱藏指示箭頭
alpha = 0.0f;
}
}
}
設計寶箱程式腳本 3/4
46
 將AssetsSpritestreasures1素材(寶箱開啟圖片)拖曳到寶箱之
Treasure Control下的Open屬性
設計寶箱程式腳本 4/4
47
 編輯NinjaController程式腳本,加入與陷阱及寶箱道具互動
public class NinjaController : MonoBehaviour{
...
private bool isJump = false; //主角跳躍旗號
private float alpha = 0.0f;
private float da = -0.1f;
private SpriteRenderer playerSprite;
private bool isInjure = false; //主角受傷旗號
// Use this for initialization
void Start(){
...
rigid = this.GetComponent<Rigidbody2D> ();
playerSprite = this.GetComponent<SpriteRenderer> ();
}
更新忍者程式腳本 1/3
48
// Update is called once per frame
void Update () {
...
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;
}
}
更新忍者程式腳本 2/3
49
void OnTriggerEnter2D(Collider2D c) {
if (c.gameObject.tag == "trap") { //主角碰到陷阱
isInjure = true; //主角為受傷狀態
}
}
void OnTriggerExit2D(Collider2D c) {
if (c.gameObject.tag == "trap") { //主角脫離陷阱
isInjure = false;
playerSprite.material.color = new Color(1f, 1f, 1f, 1f); //復原主角狀態
}
}
void OnTriggerStay2D (Collider2D c) {
if (c.gameObject.tag == "treasure") //主角在寶箱處
if (Input.GetKeyDown (KeyCode.Space)) //按下空白鍵取得寶藏
c.gameObject.GetComponent<TreasureControl>().isOpen = true;
}
}
更新忍者程式腳本 3/3
50
 PlayerPrefs可以在應用程式內做資料存取的動作,可存取的資料型
態包括int、float、string三種類型
 儲存資料
 PlayerPrefs.SetInt ("儲存名稱I", 整數變數);
 PlayerPrefs.SetFloat ("儲存名稱F", 浮點數變數);
 PlayerPrefs.SetString ("儲存名稱S", 字串變數);
 讀取資料
 整數變數 = PlayerPrefs.GetInt ("儲存名稱I");
 浮點數變數 = PlayerPrefs.GetFloat ("儲存名稱F");
 字串變數 = PlayerPrefs.GetString ("儲存名稱S");
設計儲存點 1/2
51
 清除全部資料
 PlayerPrefs.DeleteAll();
 清除個別變數資料
 PlayerPrefs.DeleteKey("儲存名稱I");
設計儲存點 2/2
52

More Related Content

What's hot

Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performanceintelliyole
 
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーション
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーションビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーション
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - UnityステーションUnity Technologies Japan K.K.
 
How to create a camera2
How to create a camera2How to create a camera2
How to create a camera2Booch Lin
 
레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다Lee Dustin
 
Introduction to three.js
Introduction to three.jsIntroduction to three.js
Introduction to three.jsyuxiang21
 
【CEDEC2018】CPUを使い切れ! Entity Component System(通称ECS) が切り開く新しいプログラミング
【CEDEC2018】CPUを使い切れ! Entity Component System(通称ECS) が切り開く新しいプログラミング【CEDEC2018】CPUを使い切れ! Entity Component System(通称ECS) が切り開く新しいプログラミング
【CEDEC2018】CPUを使い切れ! Entity Component System(通称ECS) が切り開く新しいプログラミングUnity Technologies Japan K.K.
 
それを早く言ってよ〜パフォーマンスを出すエフェクト制作のポイント
それを早く言ってよ〜パフォーマンスを出すエフェクト制作のポイントそれを早く言ってよ〜パフォーマンスを出すエフェクト制作のポイント
それを早く言ってよ〜パフォーマンスを出すエフェクト制作のポイントMakoto Goto
 
Mesh Bakerのご紹介 どんなアセット?
Mesh Bakerのご紹介 どんなアセット?Mesh Bakerのご紹介 どんなアセット?
Mesh Bakerのご紹介 どんなアセット?onotchi_
 
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそう
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそうビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそう
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそうUnity Technologies Japan K.K.
 
Dependency Injection with Dagger 2 presentation
Dependency Injection with Dagger 2 presentationDependency Injection with Dagger 2 presentation
Dependency Injection with Dagger 2 presentationJT Liew
 
Photon Fusionのはじめの一歩
Photon Fusionのはじめの一歩Photon Fusionのはじめの一歩
Photon Fusionのはじめの一歩聡 大久保
 
Exception Handling
Exception HandlingException Handling
Exception HandlingSunil OS
 
RenderPool Radeon ProRender for Blender 使い方マニュアル
RenderPool Radeon ProRender for Blender 使い方マニュアルRenderPool Radeon ProRender for Blender 使い方マニュアル
RenderPool Radeon ProRender for Blender 使い方マニュアルMORGENROTInc
 
Dagger Hilt Pros and Cons - Android Summit 2020
Dagger Hilt Pros and Cons - Android Summit 2020Dagger Hilt Pros and Cons - Android Summit 2020
Dagger Hilt Pros and Cons - Android Summit 2020Vasiliy Zukanov
 
Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)Yoshifumi Kawai
 
Direct x 11 입문
Direct x 11 입문Direct x 11 입문
Direct x 11 입문Jin Woo Lee
 
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019devCAT Studio, NEXON
 
3dsMax+UE4 ~映像制作におけるリアルタイムエンジンの活用~
3dsMax+UE4 ~映像制作におけるリアルタイムエンジンの活用~3dsMax+UE4 ~映像制作におけるリアルタイムエンジンの活用~
3dsMax+UE4 ~映像制作におけるリアルタイムエンジンの活用~弘幸 赤崎
 

What's hot (20)

Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performance
 
gcc and friends
gcc and friendsgcc and friends
gcc and friends
 
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーション
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーションビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーション
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーション
 
How to create a camera2
How to create a camera2How to create a camera2
How to create a camera2
 
【Unity】Scriptable object 入門と活用例
【Unity】Scriptable object 入門と活用例【Unity】Scriptable object 入門と活用例
【Unity】Scriptable object 入門と活用例
 
레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다
 
Introduction to three.js
Introduction to three.jsIntroduction to three.js
Introduction to three.js
 
【CEDEC2018】CPUを使い切れ! Entity Component System(通称ECS) が切り開く新しいプログラミング
【CEDEC2018】CPUを使い切れ! Entity Component System(通称ECS) が切り開く新しいプログラミング【CEDEC2018】CPUを使い切れ! Entity Component System(通称ECS) が切り開く新しいプログラミング
【CEDEC2018】CPUを使い切れ! Entity Component System(通称ECS) が切り開く新しいプログラミング
 
それを早く言ってよ〜パフォーマンスを出すエフェクト制作のポイント
それを早く言ってよ〜パフォーマンスを出すエフェクト制作のポイントそれを早く言ってよ〜パフォーマンスを出すエフェクト制作のポイント
それを早く言ってよ〜パフォーマンスを出すエフェクト制作のポイント
 
Mesh Bakerのご紹介 どんなアセット?
Mesh Bakerのご紹介 どんなアセット?Mesh Bakerのご紹介 どんなアセット?
Mesh Bakerのご紹介 どんなアセット?
 
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそう
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそうビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそう
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそう
 
Dependency Injection with Dagger 2 presentation
Dependency Injection with Dagger 2 presentationDependency Injection with Dagger 2 presentation
Dependency Injection with Dagger 2 presentation
 
Photon Fusionのはじめの一歩
Photon Fusionのはじめの一歩Photon Fusionのはじめの一歩
Photon Fusionのはじめの一歩
 
Exception Handling
Exception HandlingException Handling
Exception Handling
 
RenderPool Radeon ProRender for Blender 使い方マニュアル
RenderPool Radeon ProRender for Blender 使い方マニュアルRenderPool Radeon ProRender for Blender 使い方マニュアル
RenderPool Radeon ProRender for Blender 使い方マニュアル
 
Dagger Hilt Pros and Cons - Android Summit 2020
Dagger Hilt Pros and Cons - Android Summit 2020Dagger Hilt Pros and Cons - Android Summit 2020
Dagger Hilt Pros and Cons - Android Summit 2020
 
Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)
 
Direct x 11 입문
Direct x 11 입문Direct x 11 입문
Direct x 11 입문
 
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019
 
3dsMax+UE4 ~映像制作におけるリアルタイムエンジンの活用~
3dsMax+UE4 ~映像制作におけるリアルタイムエンジンの活用~3dsMax+UE4 ~映像制作におけるリアルタイムエンジンの活用~
3dsMax+UE4 ~映像制作におけるリアルタイムエンジンの活用~
 

Similar to Unity遊戲程式設計 - 2D移動與碰撞處理II

Unity遊戲程式設計 - 2D移動與碰撞處理II
Unity遊戲程式設計 - 2D移動與碰撞處理IIUnity遊戲程式設計 - 2D移動與碰撞處理II
Unity遊戲程式設計 - 2D移動與碰撞處理II吳錫修 (ShyiShiou Wu)
 
Unity遊戲程式設計(04) 2D運動與碰撞處理I
Unity遊戲程式設計(04) 2D運動與碰撞處理IUnity遊戲程式設計(04) 2D運動與碰撞處理I
Unity遊戲程式設計(04) 2D運動與碰撞處理I吳錫修 (ShyiShiou Wu)
 
Unity遊戲程式設計(05) 2D移動與碰撞處理II
Unity遊戲程式設計(05) 2D移動與碰撞處理IIUnity遊戲程式設計(05) 2D移動與碰撞處理II
Unity遊戲程式設計(05) 2D移動與碰撞處理II吳錫修 (ShyiShiou Wu)
 
Unity遊戲程式設計 - 2D運動與碰撞處理I
Unity遊戲程式設計 - 2D運動與碰撞處理IUnity遊戲程式設計 - 2D運動與碰撞處理I
Unity遊戲程式設計 - 2D運動與碰撞處理I吳錫修 (ShyiShiou Wu)
 
Unity遊戲程式設計 - 2D粒子特效應用
Unity遊戲程式設計 - 2D粒子特效應用Unity遊戲程式設計 - 2D粒子特效應用
Unity遊戲程式設計 - 2D粒子特效應用吳錫修 (ShyiShiou Wu)
 
component based html5 game engine
component based html5 game enginecomponent based html5 game engine
component based html5 game enginehbbalfred
 
Unity遊戲程式設計 - 3D物件與光源設定
Unity遊戲程式設計 - 3D物件與光源設定 Unity遊戲程式設計 - 3D物件與光源設定
Unity遊戲程式設計 - 3D物件與光源設定 吳錫修 (ShyiShiou Wu)
 
Unity遊戲程式設計 - 2D Game Kit遊戲設計
Unity遊戲程式設計 - 2D Game Kit遊戲設計Unity遊戲程式設計 - 2D Game Kit遊戲設計
Unity遊戲程式設計 - 2D Game Kit遊戲設計吳錫修 (ShyiShiou Wu)
 
Unity遊戲程式設計 - 應用Sprite物件
Unity遊戲程式設計 - 應用Sprite物件Unity遊戲程式設計 - 應用Sprite物件
Unity遊戲程式設計 - 應用Sprite物件吳錫修 (ShyiShiou Wu)
 
Unity遊戲程式設計 - 2D動畫製作及應用
Unity遊戲程式設計 - 2D動畫製作及應用Unity遊戲程式設計 - 2D動畫製作及應用
Unity遊戲程式設計 - 2D動畫製作及應用吳錫修 (ShyiShiou Wu)
 

Similar to Unity遊戲程式設計 - 2D移動與碰撞處理II (13)

Unity遊戲程式設計 - 2D移動與碰撞處理II
Unity遊戲程式設計 - 2D移動與碰撞處理IIUnity遊戲程式設計 - 2D移動與碰撞處理II
Unity遊戲程式設計 - 2D移動與碰撞處理II
 
Unity遊戲程式設計(04) 2D運動與碰撞處理I
Unity遊戲程式設計(04) 2D運動與碰撞處理IUnity遊戲程式設計(04) 2D運動與碰撞處理I
Unity遊戲程式設計(04) 2D運動與碰撞處理I
 
Unity遊戲程式設計(05) 2D移動與碰撞處理II
Unity遊戲程式設計(05) 2D移動與碰撞處理IIUnity遊戲程式設計(05) 2D移動與碰撞處理II
Unity遊戲程式設計(05) 2D移動與碰撞處理II
 
Unity遊戲程式設計 - 2D運動與碰撞處理I
Unity遊戲程式設計 - 2D運動與碰撞處理IUnity遊戲程式設計 - 2D運動與碰撞處理I
Unity遊戲程式設計 - 2D運動與碰撞處理I
 
Unity遊戲程式設計 - 2D粒子特效應用
Unity遊戲程式設計 - 2D粒子特效應用Unity遊戲程式設計 - 2D粒子特效應用
Unity遊戲程式設計 - 2D粒子特效應用
 
component based html5 game engine
component based html5 game enginecomponent based html5 game engine
component based html5 game engine
 
Unity遊戲程式設計 - 3D物件與光源設定
Unity遊戲程式設計 - 3D物件與光源設定 Unity遊戲程式設計 - 3D物件與光源設定
Unity遊戲程式設計 - 3D物件與光源設定
 
Unity遊戲程式設計 - Roll a ball遊戲
Unity遊戲程式設計 - Roll a ball遊戲Unity遊戲程式設計 - Roll a ball遊戲
Unity遊戲程式設計 - Roll a ball遊戲
 
Unity遊戲程式設計 - 2D Game Kit遊戲設計
Unity遊戲程式設計 - 2D Game Kit遊戲設計Unity遊戲程式設計 - 2D Game Kit遊戲設計
Unity遊戲程式設計 - 2D Game Kit遊戲設計
 
I os 14
I os 14I os 14
I os 14
 
Unity遊戲程式設計 - 應用Sprite物件
Unity遊戲程式設計 - 應用Sprite物件Unity遊戲程式設計 - 應用Sprite物件
Unity遊戲程式設計 - 應用Sprite物件
 
Roll a ball遊戲專案
Roll a ball遊戲專案Roll a ball遊戲專案
Roll a ball遊戲專案
 
Unity遊戲程式設計 - 2D動畫製作及應用
Unity遊戲程式設計 - 2D動畫製作及應用Unity遊戲程式設計 - 2D動畫製作及應用
Unity遊戲程式設計 - 2D動畫製作及應用
 

More from 吳錫修 (ShyiShiou Wu)

Unity遊戲程式設計 - 2D Platformer遊戲
Unity遊戲程式設計 - 2D Platformer遊戲Unity遊戲程式設計 - 2D Platformer遊戲
Unity遊戲程式設計 - 2D Platformer遊戲吳錫修 (ShyiShiou Wu)
 

More from 吳錫修 (ShyiShiou Wu) (20)

Vuforia AR影片程式設計
Vuforia AR影片程式設計Vuforia AR影片程式設計
Vuforia AR影片程式設計
 
micro:bit亮度感測應用
micro:bit亮度感測應用micro:bit亮度感測應用
micro:bit亮度感測應用
 
Vuforia AR 同時追踨多張辨識圖
Vuforia AR同時追踨多張辨識圖Vuforia AR同時追踨多張辨識圖
Vuforia AR 同時追踨多張辨識圖
 
micro:bit開關控制應用
micro:bit開關控制應用micro:bit開關控制應用
micro:bit開關控制應用
 
Vuforia AR 應用程式設計入門
Vuforia AR應用程式設計入門Vuforia AR應用程式設計入門
Vuforia AR 應用程式設計入門
 
Vuforia AR 應用程式準備作業
Vuforia AR應用程式準備作業Vuforia AR應用程式準備作業
Vuforia AR 應用程式準備作業
 
micro:bit LED顯示控制
micro:bit LED顯示控制micro:bit LED顯示控制
micro:bit LED顯示控制
 
IDE for micro:bit
IDE for micro:bitIDE for micro:bit
IDE for micro:bit
 
Microbit 1 introduction
Microbit 1 introductionMicrobit 1 introduction
Microbit 1 introduction
 
Arduino overview
Arduino overviewArduino overview
Arduino overview
 
使用Makeblock App學習mBot程式設計
使用Makeblock App學習mBot程式設計使用Makeblock App學習mBot程式設計
使用Makeblock App學習mBot程式設計
 
使用M部落App學習mBot程式設計
使用M部落App學習mBot程式設計使用M部落App學習mBot程式設計
使用M部落App學習mBot程式設計
 
nodeMCU IOT教學03 - NodeMCU導論
nodeMCU IOT教學03 - NodeMCU導論nodeMCU IOT教學03 - NodeMCU導論
nodeMCU IOT教學03 - NodeMCU導論
 
nodeMCU IOT教學02 - Lua語言
nodeMCU IOT教學02 - Lua語言nodeMCU IOT教學02 - Lua語言
nodeMCU IOT教學02 - Lua語言
 
Unity遊戲程式設計 - 2D Platformer遊戲
Unity遊戲程式設計 - 2D Platformer遊戲Unity遊戲程式設計 - 2D Platformer遊戲
Unity遊戲程式設計 - 2D Platformer遊戲
 
Python與Ardinio整合應用
Python與Ardinio整合應用Python與Ardinio整合應用
Python與Ardinio整合應用
 
mBlock積木式設計程式
mBlock積木式設計程式mBlock積木式設計程式
mBlock積木式設計程式
 
Arduino程式除錯
Arduino程式除錯Arduino程式除錯
Arduino程式除錯
 
Arduino程式開發工具
Arduino程式開發工具Arduino程式開發工具
Arduino程式開發工具
 
Arduino程式快速入門
Arduino程式快速入門Arduino程式快速入門
Arduino程式快速入門
 

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

  • 1. 2D移動與碰撞處理II Revised on October 10, 2019  使用剛體、碰撞器與觸發器  遊戲圖層及碰撞管理  探險遊戲關卡設計
  • 2.  剛體是具物理性質的元件,可使物件在物理引擎控制下擬真運動  由選單命令Component> Physics 2D> Rigidbody 2D為物件套用2D 剛體元件  物理性質:質量(Mass)、移動阻力( Linear Drag)、旋轉阻力(Angular Drag)、重力(Gravity Scale)  運動剛體(Kinematic)不受重力及外力影響  埸景中的活動物件可使用剛體來實現  真實世界兩個物體撞在⼀起會發⽣碰撞,遊戲世界裡要透過碰撞器來 模擬現實世界的碰撞情形  碰撞器像是包覆在物件上的透明防護罩,代表物件實體邊界  加了碰撞器之剛體物件會被其它碰撞器阻隔 剛體、碰撞器與觸發器 1/5 2
  • 3.  我們可依物件外觀,由選單命令Component> Physics 2D中選用合適 的碰撞器  Box Collider 2D(方框碰撞器)  適用於矩形物體  Circle Collider 2D(圓形碰撞器)  適用於圓形物體  Edge Collider 2D(邊緣碰撞器)  適用於邊界、地板或天花板  可編輯/調整線段節點,即使編輯成封閉迴路,也只有在線段上才會碰 撞,其內部不會產⽣碰撞 剛體、碰撞器與觸發器 2/5 3 Circle Collider Box Collider
  • 4.  Polygon Collider 2D(多邊形碰撞器)  能較精準貼近不規則物體,但耗用較多運算資源  Capsule Collider 2D(膠囊碰撞器)  適用於膠囊形狀物體  Composite Collider 2D(複合碰撞器)  用來將子物件的碰撞器(Box Collider 2D及Polygon Collider 2D) 合併成⼀個碰撞器  子物件勾選Used By Composite  會自動附加Rigidbody 2D元件 剛體、碰撞器與觸發器 2/5 4 Polygon Collider Capsule Collider Composite Collider 2D Polygon Collider Box Collider
  • 5.  兩個具有碰撞器之物件相互碰觸時,程式腳本可以實作 OnCollisionXXX2D函式來處理碰撞作業 void OnCollisionEnter2D (Collision2D other) { //進入碰撞時 } void OnCollisionStay2D(Collision2D other) { //在碰撞物上時 } void OnCollisionExit2D(Collision2D other) { //結束碰撞時 } 剛體、碰撞器與觸發器 4/5 5
  • 6.  觸發器  當碰撞器被設定Is Trigger屬性,即成為觸發器;其它碰撞器物件可以穿 過觸發器物件  通常道具元件會加上觸發器  在物件之程式腳本可使用下列函式來處理碰撞事件 void OnTriggerEnter2D(Collider2D other) { //進入碰撞範圍時 } void OnTriggerStay2D(Collider2D other) { //在碰撞物上時 } void OnTriggerExit2D(Collider2D other) { //脫離碰撞範圍時 } 剛體、碰撞器與觸發器 5/5 6
  • 7.  更新座標方式 (自行計算位移,物體移動⽣硬不自然) 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); 遊戲物件移動控制 7
  • 8. 遊戲圖層及碰撞管理 1/4 8  預設場景上的物件都是放置在Default圖層  Layer用來做遊戲物件碰撞管理  Sorting Layer用來管理場景物件前後層次  同Sorting Layer之物件,Order in Layer 數值較大者在上層;若Order in Layer值也 相同,則由Position Z值(與Main Camera 遠近)決定  Layer屬性與Sorting Layer屬性二者並不相關
  • 9.  管理圖層  選單命令Edit> Project Settings> Tags and Layers管理圖層  在Sorting Layers增加Background、Interactive、Player圖層 遊戲圖層及碰撞管理 2/4 9 下層 上層新增圖層
  • 11.  碰撞管理  選單命令Edit> Project Settings> Physics 2D進行碰撞管理  設定Layer Collision Matrix  預設全部圖層間都會進行碰撞檢測處理  依據遊戲設計需求,設定圖層間的碰撞檢核 遊戲圖層及碰撞管理 4/4 11
  • 12.  忍者可左、右移動、跳躍及射飛標  忍者必須先射飛標消滅飛龍,才能躍過山溝  忍者接觸到毒霧會受傷  忍者靠近寶箱時會顯示提示箭頭,此時按空白鍵可開啟寶箱 探險遊戲關卡設計 12
  • 13.  新增2D遊戲專案,將預設場景以main名稱存檔  在Assets下建立以下資料夾  Animations  Prefabs  Scripts  Sprites  SpritesNinja 建立遊戲專案 1/2 13
  • 15.  選單命令Edit> Project Settings> Tags and Layers  在Sorting Layers增加Background、Interactive、Player圖層  在Layers加入Background、Interactive、Player圖層 建立遊戲圖層 1/2 15
  • 16.  設定圖層碰撞關係  選單命令Edit> Project Settings> Physics 2D進行碰撞管理  設定Layer Collision Matrix,啟用以下碰撞檢核  Player與Backgound  Player與Interactive 建立遊戲圖層 2/2 16
  • 17.  將background.png拖曳到場景,命名為Background  Position(X,Y,Z) = (48.5, 0, 0)  Scale(X,Y,Z) = (8, 8, 1)  Layer = Background  Sorting Layer = Background  設定地面邊界  選單命令Component> Physics 2D> Edge Collider 2D加入邊緣碰 撞器  點擊Edit Collider編輯邊緣碰撞器,使其貼齊山谷左側地面  選單命令Component> Physics 2D> Edge Collider 2D加入邊緣碰 撞器  點擊Edit Collider編輯邊緣碰撞器,使其貼近貼齊山谷右側地面 建造背景及地面邊界 17
  • 18.  點選AssetsSpritesdragon  Sprite Mode = Multiple  點擊Sprite Editor  套用自動分割,並調整每個分鏡圖片座標基準點(Pivot)到胸口位置 建立飛龍 1/4 18 Pivot
  • 19.  將dragon_0.png拖曳到場景,命名為Dragon  Position(X,Y,Z) = (-3.5, -4, 0)  Rotation(X,Y,Z) = (0, 180, 0)  Scale(X,Y,Z) = (3, 3, 1)  Layer = Interactive  Sorting Layer = Interactive  設定碰撞器  選單命令Component> Physics 2D> Circle Collider 2D加入圓形 碰撞器 建立飛龍 2/4 19
  • 20.  製作飛龍動畫  選單命令Window> Animation> Animation開啟動畫編輯器,使用 dragon分鏡素材建立編輯飛龍動畫 建立飛龍 3/4 20
  • 21.  加入Dragon程式腳本,飛龍被飛標擊中會損血,⽣命值歸零時消失 public class Dragon : MonoBehaviour { [SerializeField] private int life = 3; // Use this for initialization void Start () { } // Update is called once per frame void Update () { } void OnTriggerEnter2D(Collider2D c) { if (c.tag == "dart") life--; if (life == 0) Destroy(this.gameObject); } } 建立飛龍 4/4 21
  • 22.  點選AssetsSpritesNinja忍者動作分鏡圖片  Texture Type = Sprite(2D and UI)  透過Sprite Editor將所有忍者動作分鏡圖片的座標基準點(Pivot) 調整到角色雙腳底部重心位置 建立忍者角色 1/3 22 Pivot
  • 23.  將AssetsSpritesNinjaidle_000拖曳到場景,命名為Ninja  Position(X,Y,Z) = (-26, -9, 0)  Sorting Layer = Player  Layer = Player  選單命令Component> Physics 2D> Rigidbody 2D加入剛體元件  勾選Use Auto Mass  Gravity Scale = 1.5  勾選Freeze Rotation Z  選單命令Component> Physics 2D> Capsule Collider 2D加入膠囊碰 撞器  適當調整Offset(X, Y)及Size(X, Y) 建立忍者角色 2/3 23
  • 24.  製作角色動畫 選單命令Window> Animation> Animation開啟動畫編輯器,使用Ninja 分鏡素材建立以下動畫  建立ninja_idle動畫 (1秒)  建立ninja_run動畫 (0.5秒)  建立ninja_jump動畫 (1秒)  建立ninja_throw動畫 (1秒) 建立忍者角色 3/3 24
  • 25.  拖曳Kunai到場景中,命名為Dart  Rotation(X,Y,Z) = (0, 0, -90)  Layer = Player  Sorting Layer = Player  Tag = dart  選單命令Component> Physics 2D> Rigirbody 2D加入剛體  Gravity Scale=0  選單命令Component> Physics 2D> Box Collider 2D加入矩形碰撞器  勾選Is Trigger 製作飛鏢預製物件 1/3 25
  • 26.  在Dart物件加上Dart程式腳本 public class Dart : MonoBehaviour{ //Use this for initialization public float speed; void Start(){ GetComponent<Rigidbody2D>().velocity = new Vector2(speed, 0.0f); } //Update is called once per frame void Update(){ } private void OnBecameInvisible(){ //飛出畫面 Destroy(this.gameObject); } void OnTriggerEnter2D(Collider2D c) { //射到其它物件 Destroy(this.gameObject); } } 製作飛鏢預製物件 2/3 26
  • 27.  將Dart之Speed欄位設為10  執行測試,飛標會向右射出,飛出場景時會 自動消失  測試無誤後,由Hierarchy面板將Dart物件 拖曳到Prefabs資料夾,做成預製物件  刪除場景上Dart物件 製作飛鏢預製物件 3/3 27
  • 28.  選單命令GameObject> Create Empty,更名為Dart Spawn  Position(X,Y,Z) = (0, 0, 0)  Rotation(X,Y,Z) = (0, 0, -90)  Scale(X,Y,Z) = (1, 1, 1)  Layer = Player  拖曳Dart Spawn成為Ninja子物件  調整Dart Spawn位置到Ninja之前端,Position(X,Y,Z) = (2.1, 2.15, 0) 設定飛鏢發射點 28
  • 29.  在Ninja物件加上NinjaController程式腳本 public class NinjaController : MonoBehaviour{ [SerializeField] private GameObject dart; [SerializeField] private Transform dartSpawn; private bool facingRight = true; //主角面向右旗號 ... public void ThrowDart(){ float speed; speed = System.Math.Abs(dart.gameObject.GetComponent<Dart>().speed); if (facingRight) dart.gameObject.GetComponent<Dart>().speed = speed; else dart.gameObject.GetComponent<Dart>().speed = -speed; Instantiate(dart, dartSpawn.position, dartSpawn.rotation); } } 飛鏢發射控制 1/3 29
  • 30.  拖曳AssetsPrefabsDart預製物件到Ninja Controller之Dart欄  拖曳Dart Spawn物件到Ninja Controller之Dart Spawn欄 飛鏢發射控制 2/3 30
  • 32.  選取Ninja物件  選單命令Window> Animator,開啟Animator編輯器  建立動畫狀態之間轉換 忍者狀態控制 1/7 32
  • 33.  建立⼀個名為action的Int參數  設定ninja_idle ninja_run狀態切換條件  取消Has Exit Time  Settings/Transtion Duration = 0  在Consitions中新增action Equals 1  設定ninja_idle ninja_jump狀態切換條件  取消Has Exit Time  Settings/Transtion Duration = 0  在Consitions中新增action Equals 2 忍者狀態控制 2/7 33
  • 34.  設定ninja_idle ninja_throw狀態切換條件  取消Has Exit Time  Settings/Transtion Duration設為0  在Consitions中新增Action Equals 3  設定ninja_run ninja_idle狀態切換條件  取消Has Exit Time  Settings/Transtion Duration = 0  在Consitions中新增action Equals 0 忍者狀態控制 3/7 34
  • 35.  設定ninja_jump ninja_idle狀態切換條件  取消Has Exit Time  Settings/Transtion Duration = 0  在Consitions中新增action Equals 0  設定ninja_throw ninja_idle狀態切換條件  勾選Has Exit Time  Settings/Exit Time = 1  Settings/Transtion Duration設為0  在Consitions中新增action Equals 0 忍者狀態控制 4/7 35
  • 36.  編輯NinjaController程式腳本 public class NinjaController : MonoBehaviour{ ... private bool facingRight = true; //主角面向右旗號 [SerializeField] private int speed = 10; //移動速度 private Animator animator; private Rigidbody2D rigid; private Vector3 startPos; private bool isJump = false; //主角跳躍旗號 // Use this for initialization void Start(){ animator = this.GetComponent<Animator>(); startPos = transform.position; rigid = this.GetComponent<Rigidbody2D> (); } 忍者狀態控制 5/7 36
  • 37. void Update() { if (Input.GetKey (KeyCode.RightArrow)) { facingRight = true; this.transform.eulerAngles = Vector3.zero; //使主角面向右 this.transform.Translate (speed*Time.deltaTime, 0, 0); //主角向右移動 if (!isJump) PlayAnimation (1); //跑步動畫 } else if (Input.GetKey (KeyCode.LeftArrow)) { facingRight = false; this.transform.eulerAngles = new Vector3 (0, 180, 0); //使主角面向左 this.transform.Translate (speed*Time.deltaTime, 0, 0); //主角向左移動 if (!isJump) PlayAnimation (1); //跑步動畫 } else if (Input.GetKeyDown (KeyCode.UpArrow)) { if (!isJump) { rigid.velocity = new Vector2(rigid.velocity.x, rigid.velocity.y+speed); isJump = true; //主角進入跳躍狀態 PlayAnimation (2); //跳躍動畫 } } else if (Input.GetKeyDown (KeyCode.X)) PlayAnimation (3); //射飛鏢動畫 else if (!isJump) PlayAnimation (0); //閒置動畫 } 忍者狀態控制 6/7 37
  • 38. private void PlayAnimation(int action){ animator.SetInteger("action", action); } private void OnBecameInvisible(){ transform.position = startPos; } void OnCollisionEnter2D(Collision2D c) { if (c.gameObject.name == "Background") { //主角接觸地板 isJump = false; } } ... }  測試遊戲專案 忍者狀態控制 7/7 38
  • 39.  將AssetsSpritestrap0拖曳到場景  命名為Trap  Position(X,Y,Z) = (10, -11, 0)  Rotation(X,Y,Z) = (0, 0, -3)  Scale(X,Y,Z) = (0.6, 0.6, 1)  Layer = Interactive  Sorting Layer = Interactive  Tag = trap 建立陷阱道具 1/2 39
  • 40.  選單命令Component> Physics 2D> Circle Collider 2D加入圓形碰 撞器  勾選「Is Trigger」屬性 (會偵測物體碰接,但允許剛體物件穿過)  Offset Y = -2.25,讓碰撞邊界貼近陷阱外緣 建立陷阱道具 2/2 40
  • 41.  選取Trap物件  選單命令Window> Animation> Animation開啟動畫編輯器,使用trap 分鏡素材建立trap動畫 製作陷阱道具動畫 41
  • 42.  將AssetsSpritestreasures0拖曳到場景  命名為Treasure  Position(X,Y,Z) = (24.5, -8, 0)  Scale(X,Y,Z) = (0.6, 0.6, 1)  Layer = Interactive  Sorting Layer = Interactive  Tag = treasure 建立寶箱道具 1/2 42
  • 43.  選單命令Component> Physics 2D> Box Collider 2D加入矩形碰撞器  勾選「Is Trigger」屬性  將up素材拖曳到treasure物件上,做為treasure的子物件  命名為up  Position(X,Y,Z) = (0, 5, 0)  Size(X,Y,Z) = (0.6, 0.6, 1)  Sorting Layer = Interactive  Layer = Interactive 建立寶箱道具 2/2 43
  • 44.  在Treasure物件加入TreasureControl程式腳本 public class TreasureControl : MonoBehaviour { [SerializeField] private 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> (); } 設計寶箱程式腳本 1/4 44
  • 45. 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; } } 設計寶箱程式腳本 2/4 45
  • 46. void OnTriggerEnter2D (Collider2D c) { //玩家到達寶箱位置 if (c.gameObject.name == "Ninja") { isShow = true; prompt.gameObject.SetActive (isShow); //顯示指示箭頭 } } void OnTriggerExit2D (Collider2D c) { //玩家離開寶箱位置 if (c.gameObject.name == "Ninja") { isShow = false; prompt.gameObject.SetActive (isShow); //隱藏指示箭頭 alpha = 0.0f; } } } 設計寶箱程式腳本 3/4 46
  • 48.  編輯NinjaController程式腳本,加入與陷阱及寶箱道具互動 public class NinjaController : MonoBehaviour{ ... private bool isJump = false; //主角跳躍旗號 private float alpha = 0.0f; private float da = -0.1f; private SpriteRenderer playerSprite; private bool isInjure = false; //主角受傷旗號 // Use this for initialization void Start(){ ... rigid = this.GetComponent<Rigidbody2D> (); playerSprite = this.GetComponent<SpriteRenderer> (); } 更新忍者程式腳本 1/3 48
  • 49. // Update is called once per frame void Update () { ... 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; } } 更新忍者程式腳本 2/3 49
  • 50. void OnTriggerEnter2D(Collider2D c) { if (c.gameObject.tag == "trap") { //主角碰到陷阱 isInjure = true; //主角為受傷狀態 } } void OnTriggerExit2D(Collider2D c) { if (c.gameObject.tag == "trap") { //主角脫離陷阱 isInjure = false; playerSprite.material.color = new Color(1f, 1f, 1f, 1f); //復原主角狀態 } } void OnTriggerStay2D (Collider2D c) { if (c.gameObject.tag == "treasure") //主角在寶箱處 if (Input.GetKeyDown (KeyCode.Space)) //按下空白鍵取得寶藏 c.gameObject.GetComponent<TreasureControl>().isOpen = true; } } 更新忍者程式腳本 3/3 50
  • 51.  PlayerPrefs可以在應用程式內做資料存取的動作,可存取的資料型 態包括int、float、string三種類型  儲存資料  PlayerPrefs.SetInt ("儲存名稱I", 整數變數);  PlayerPrefs.SetFloat ("儲存名稱F", 浮點數變數);  PlayerPrefs.SetString ("儲存名稱S", 字串變數);  讀取資料  整數變數 = PlayerPrefs.GetInt ("儲存名稱I");  浮點數變數 = PlayerPrefs.GetFloat ("儲存名稱F");  字串變數 = PlayerPrefs.GetString ("儲存名稱S"); 設計儲存點 1/2 51
  • 52.  清除全部資料  PlayerPrefs.DeleteAll();  清除個別變數資料  PlayerPrefs.DeleteKey("儲存名稱I"); 設計儲存點 2/2 52