unity遊戲程式設計(04) 2d移動與碰撞處理i
TRANSCRIPT
電子工程系應 用 電 子 組電 腦 遊 戲 設 計 組
Unity遊戲程式設計(04) 2D移動與碰撞處理I
吳錫修
Nov 14, 2016
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
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
shap
e th
e fu
ture
Is Trigger屬性
通常道具元件會勾選Is Trigger,具碰撞檢測功能並發送碰撞通知
主角可穿透被設定為Is Trigger之道具
剛體元件程式腳本可使用下列函式來處理碰撞事件
void OnTriggerEnter2D(Collider2D other) {//進入碰撞時
}
void OnTriggerExit2D(Collider2D other) {//結束碰撞時
}
碰撞器 3/3
4 Wu, ShyiShiou Dept. of E.E., NKUT
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
shap
e th
e fu
ture
新增2D專案
將預設場景以ufo名稱存檔
將ufo.png、background.png、gold.png素材滙入到專案Assets\Sprite資料夾
UFO遊戲設計
6 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
將background拖曳到ufo場景
Position設定為 (x, y, z) = (0, 0, 0)
Main Camera元件
將Camera Background設定為黑色
將Camera Size設定為16.5
設定場景背景
7 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
將ufo拖曳到ufo場景
Position設定為 (x, y, z) = (0, 0, 0)
加入UFO物件
8 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
為ufo元件加入UFOController程式腳本
讓UFO動起來 1/3
9 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
編輯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
10 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
Inspector面板將ufo之speed設定為10,執行測試看看
讓UFO動起來 3/3
11 Wu, ShyiShiou Dept. of E.E., NKUT
可以用W、A、S、D鍵移動飛碟
飛碟移動起並不自然
飛碟可以飛出邊界
shap
e th
e fu
ture
選取ufo元件
Component選單Physics 2D\Rigidbody 2D,加入剛體性質
執行測試發現ufo會自動往下掉;
把Gravity Scale改成0,模擬太空無重力狀態
改用物理加速度方式移動 1/3
12 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
修改UFOController程式如下:
public float forceValue;private Rigidbody2D _rigidbody2D = null;void Start () {
_rigidbody2D = this.GetComponent<Rigidbody2D> ();}void Update () {
Vector2 force2D = Vector2.zero;if (Input.GetKey(KeyCode.W)){
force2D.y += forceValue;}if (Input.GetKey (KeyCode.S)) {
force2D.y -= forceValue;}
改用物理加速度方式移動 2/3
13 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
if (Input.GetKey(KeyCode.A)) {force2D.x -= forceValue;
}if (Input.GetKey(KeyCode.D)){
force2D.x += forceValue;}_rigidbody2D.AddForce(force2D);
}
Force Value設定為3,執行測試看看 飛碟會以加速度移動了 飛碟還是會飛出邊界
改用物理加速度方式移動 3/3
14 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
選取ufo元件
Component選單Physics 2D\Circle Collider 2D,加入圓形碰撞器
把Radius調成2.12,讓Collider2D大小與ufo圖片重合
設定UFO飛行邊界 1/2
15 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
選取background元件
Component選單Physics 2D\Edge Collider 2D,加入邊緣碰撞器
點擊「Edit Collider」按鈕
讓edit collider環繞背景內緣四週
執行測試,飛碟不會穿牆出去了
設定UFO飛行邊界 2/2
16 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
在Hierarchy面板中,將 Main Camera拖到ufo元件底下
執行測試
遊戲鏡頭會以飛碟為中心
飛碟撞到邊界,飛碟會旋轉;由於Camera鏡頭是跟附在飛碟上,飛碟時旋轉遊戲鏡頭也會跟著旋轉,背景圖就會旋轉
讓Camera鏡頭跟著飛碟移動 1/2
17 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
為Main Camera元件加入CameraController程式腳本,關閉鏡頭旋轉,程式如下
public class CameraController : MonoBehaviour {// Use this for initializationvoid Start () {
}// Update is called once per framevoid Update () {
this.transform.eulerAngles = Vector3.zero;}
}
執行測試
飛碟可以在邊界內飛行,背景圖也不會旋轉了
讓Camera鏡頭跟著飛碟移動 2/2
18 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
拖曳gold.png到場景
命名為pickup
Component選單Physics 2D\Rigidbody 2D,加入剛體性質
勾選Is Kinematic
佈置金塊道具 1/5
19 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
Component選單Physics 2D\Circle Collider 2D,加入圓形碰撞器
勾選Is Trigger
佈置金塊道具 2/5
20 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
為pickup元件加入PickupController程式腳本,讓金塊自主旋轉
public class PickupController : MonoBehaviour {
public float RotateSpeed;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {
this.transform.Rotate (new Vector3(0,0,RotateSpeed*Time.deltaTime));}
}
佈置金塊道具 3/5
21 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
Inspector面板,Rotate Speed設定為45
佈置金塊道具 4/5
22 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
從Hierarchy面板將pickup拖曳到Assets/Prefab資料夾,建立pickup預製元件
從Assets/Prefab資料夾拖曳pickup預製元件到場景,擺設如下
測試看看
飛碟會穿過金塊
佈置金塊道具 5/5
23 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
當飛碟碰到金塊,讓金塊消失
開啟UFOController.cs,加入以下程式碼
void OnTriggerEnter2D(Collider2D other) {other.gameObject.SetActive (false);
}void OnTriggerExit2D(Collider2D other) {}
執行測試 飛碟碰到金塊時,金塊會自動消失了
讓UFO收集金塊
24 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
GameObject->UI->Text命令加入⼀個Text元件,命名為Score
Anchor設為左上角
Pos X設為40,Pos Y設為-25 (依實際情形調整)
Width設為200,Height設為48
Text設為Score: 0
Font Size設為32
Color設為白色
顯示分數 1/6
25 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
新增UI元件時,會自動建立Canvas元件,而如果場景中已經有畫布,新增的 UI 元素將會自動成為此畫布的子物件
遊戲執行時,Canvas會依據Render Mode自動調整Canvas大小及位置
Render Mode預設為Screen Space - Overlay
顯示分數 2/6
26 Wu, ShyiShiou Dept. of E.E., NKUT
Canvas
Game resolution
shap
e th
e fu
ture
Score元件加入ScoreManager程式腳本,程式如下
using UnityEngine;using System.Collections;using UnityEngine.UI;
public class ScoreManager : MonoBehaviour {private Text _text;private float _currentScore = 0;const string ScorePrefix = "Score : ";
// Use this for initializationvoid Start () {
_text = this.GetComponent<Text> ();_text.text = ScorePrefix + _currentScore;
}
顯示分數 3/6
27 Wu, ShyiShiou Dept. of E.E., NKUT
注意Text是定義在Unity.Engine.UI底下
shap
e th
e fu
ture
// 分數更新副程式public void AddScore(int score) {
_currentScore += score;_text.text = ScorePrefix + _currentScore;
}
// Update is called once per framevoid Update () {
}}
顯示分數 4/6
28 Wu, ShyiShiou Dept. of E.E., NKUT
shap
e th
e fu
ture
修改UFOController.cs,當飛碟收集到金塊時增加分數
using UnityEngine;using System.Collections;
public class UFOController : MonoBehaviour {public float forceValue;private Rigidbody2D _rigidbody2D = null;public ScoreManager scoremanager;...void OnTriggerEnter2D(Collider2D other){
other.gameObject.SetActive (false);scoremanager.AddScore (100);
}}
顯示分數 5/6
29 Wu, ShyiShiou Dept. of E.E., NKUT
宣告ScoreManager
更新分數
shap
e th
e fu
ture
選取ufo物件,然後把Score拖進ScoreManager的欄位
顯示分數 6/6
30 Wu, ShyiShiou Dept. of E.E., NKUT