Unity遊戲程式設計 - 2D Platformer遊戲
- 2. 建立2D專案,my2DPlatformer
選單命令File> Save As…,將預設場景另存新檔
Exercise.unity
調整Main Camera
Position(X, Y, Z) = (-4.43, -0.15, -10)
Background(R, G, B, A) = (163, 187, 196, 5)
Size = 11
Free Aspect
滙入遊戲資源
選單命令Assets> Import Package> Custom Package…,滙入
platformer2d.unitypackage
建立專案 1/3
2
- 6. 選取Prefabs/Props/swan.prefab
Sorting Layer = Background
選取Prefabs/Environment/Cab.prefab
Sorting Layer = Background
Wheels子物件
Sorting Layer = Background
選取Prefabs/Environment/Bus.prefab
Sorting Layer = Background
Wheels子物件
Sorting Layer = Background
設定背景動畫預製物件
6
- 7. 在_Scripts目錄下新增BackgroundPropSpawner.cs程式腳本
using UnityEngine;
using System.Collections;
public class BackgroundPropSpawner : MonoBehaviour {
public Rigidbody2D backgroundProp; //待生成的背景預製物件
public float leftSpawnPosX; //左側生成位置x座標
public float rightSpawnPosX; //右側生成位置x座標
public float minSpawnPosY; //生成位置y座標區間最小值
public float maxSpawnPosY; //生成位置y座標區間最大值
public float minTimeBetweenSpawns; //生成間隔時間最小值
public float maxTimeBetweenSpawns; //生成間隔時間最大值
public float minSpeed; //最小移動速度
public float maxSpeed; //移動速度最大值
void Start () {
Random.InitState(System.DateTime.Today.Millisecond);
StartCoroutine("Spawn"); //起始Spawn程序
}
隨機產生背景動畫物件 1/6
7
- 8. IEnumerator Spawn () {
float waitTime = Random.Range(minTimeBetweenSpawns, maxTimeBetweenSpawns);
yield return new WaitForSeconds(waitTime); //隨機等待一段時間
bool facingLeft = Random.Range(0,2) == 0; //隨機設定預製物件方向
float posX = facingLeft ? rightSpawnPosX : leftSpawnPosX;
float posY = Random.Range(minSpawnPosY, maxSpawnPosY);
Vector3 spawnPos = new Vector3(posX, posY, transform.position.z);
Rigidbody2D propInstance =
Instantiate(backgroundProp, spawnPos, Quaternion.identity) as Rigidbody2D;
if (!facingLeft) {
Vector3 scale = propInstance.transform.localScale;
scale.x *= -1;
propInstance.transform.localScale = scale;
}
float speed = Random.Range(minSpeed, maxSpeed); //隨機設定速度
speed *= facingLeft ? -1f : 1f;
propInstance.velocity = new Vector2(speed, 0);
StartCoroutine(Spawn());
隨機產生背景動畫物件 2/6
8
- 9. while (propInstance != null) {
if (facingLeft) {
if (propInstance.transform.position.x < leftSpawnPosX - 0.5f)
Destroy(propInstance.gameObject);
}
else {
if (propInstance.transform.position.x > rightSpawnPosX + 0.5f)
Destroy(propInstance.gameObject);
}
yield return null;
}
}
}
隨機產生背景動畫物件 3/6
9
- 10. 新增空物件,命名為swanCreator
重置Transform
加入BackgroundPropSpawner.cs程式腳本
拖曳Prefabs/Props/swan.prefab到Prop欄
Left Spawn Pos X = -24
Right Spawn Pos X = 24
Min Spawn Pos Y = 4
Max Spawn Pos Y = 8
Min Time Between Spawns = 2
Max Time Between Spawns = 8
Min Speed = 5
Max Speed = 8
測試遊戲,天空會隨機有天鵝飛過
隨機產生背景動畫物件 4/6
10
- 11. 新增空物件,命名為busCreator
重置Transform
加入BackgroundPropSpawner.cs程式腳本
拖曳Prefabs/Environment/Bus.prefab到Prop欄
Left Spawn Pos X = -24
Right Spawn Pos X = 24
Min Spawn Pos Y = -5.5
Max Spawn Pos Y = -5.5
Min Time Between Spawns = 8
Max Time Between Spawns = 18
Min Speed = 5
Max Speed = 8
測試遊戲,街道會隨機有巴士通過
隨機產生背景動畫物件 5/6
11
- 12. 新增空物件,命名為cabCreator
重置Transform
加入BackgroundPropSpawner.cs程式腳本
拖曳Prefabs/Environment/Cab.prefab到Prop欄
Left Spawn Pos X = -24
Right Spawn Pos X = 24
Min Spawn Pos Y = -6.4
Max Spawn Pos Y = -6.4
Min Time Between Spawns = 10
Max Time Between Spawns = 15
Min Speed = 5
Max Speed = 8
測試遊戲,街道會隨機有計程車通過
隨機產生背景動畫物件 6/6
12
- 13. 新增空物件,命名為music
重置Transform
加入AudioSource元件
AudioClip = MainTheme
勾選Play On Awake
勾選Loop
Volume = 0.1
Reverb Zone Mix = 0
測試專案,遊戲執行時會持續撥放背景音樂
加入背景音樂
13
- 16. 在Mr.Bean物件加入PlayerControl.cs程式腳本
using UnityEngine;
using System.Collections;
public class PlayerControl : MonoBehaviour {
[HideInInspector]
public bool facingRight = true; //方向旗號,不顯示在屬性窗格,但可提其它程式腳本存取
[HideInInspector]
public bool jump = false; //跳躍旗號,不顯示在屬性窗格,但可提其它程式腳本存取
public float moveForce = 365f; //行進力道
public float maxSpeed = 5f; //移動速度上限
public AudioClip[] jumpClips; //跳躍動作音效庫
public float jumpForce = 1000f; //跳躍力道
private Transform groundCheck; //用來檢查玩家角色是否站在地面
private bool grounded = false; //落地旗號
private Animator anim; //玩家角色動作控制器參照
玩家角色控制 2/5
16
- 17. void Awake() {
groundCheck = transform.Find("groundCheck");
anim = GetComponent<Animator>();
}
void Update() {
grounded = Physics2D.Linecast(transform.position,
groundCheck.position, 1 << LayerMask.NameToLayer("Ground"));
//玩家角色位於在地面,並按下Jump鍵
if (Input.GetButtonDown("Jump") && grounded)
jump = true; //執行跳躍動作
}
玩家角色控制 3/5
17
- 18. void FixedUpdate () {
float h = Input.GetAxis("Horizontal");
anim.SetFloat("Speed", Mathf.Abs(h));
if (h * GetComponent<Rigidbody2D>().velocity.x < maxSpeed)
GetComponent<Rigidbody2D>().AddForce(Vector2.right * h * moveForce); //加速
if (Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x) > maxSpeed)
GetComponent<Rigidbody2D>().velocity =
new Vector2(Mathf.Sign(GetComponent<Rigidbody2D>().velocity.x) * maxSpeed,
GetComponent<Rigidbody2D>().velocity.y);
if (h > 0 && !facingRight) Flip(); //反轉方向
else if (h < 0 && facingRight) Flip(); //反轉方向
if (jump) {
anim.SetTrigger("Jump");
int i = Random.Range(0, jumpClips.Length); //隨機撥放跳躍音效
AudioSource.PlayClipAtPoint(jumpClips[i], transform.position);
GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, jumpForce)); //跳躍
jump = false; //防止重複跳躍
}
}
玩家角色控制 4/5
18
- 19. void Flip () {
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
拖曳Audio/Player/Jumps/Player-
jump[1-3].wav到Jump Clips欄
測試遊戲,可操控主角移動
適度調整移動速度及跳躍力道
玩家角色控制 5/5
19
- 20. 新增空物件,命名為healthUI
Tag = HealthBar
Position(X, Y, Z) = (0, 100, 0)
在healthUI下新增Sprite物件,命名為HealthBar
Position(X, Y, Z) = (-0.83, 0, 0)
拖曳Assets/Sprites/_UI/Health.png到Sprite Renderer之Sprite欄
拖曳Assets/Materials/Health.mat到Sprite Renderer之Material欄
Sorting Layer = Foreground
建立玩家生命條 1/4
20
- 22. 在healthUI加入FollowPlayer.cs程式腳本
using UnityEngine;
using System.Collections;
public class FollowPlayer : MonoBehaviour {
public Vector3 offset; //顯示位置偏移值
private Transform player;
void Awake () {
player = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update () {
transform.position = player.position + offset;
}
}
建立玩家生命條 3/4
22
- 24. 在Mr.Bean物件加入PlayerHealth.cs程式腳本
using UnityEngine;
using System.Collections;
public class PlayerHealth : MonoBehaviour {
public float health = 100f; //玩家生命值
public float repeatDamagePeriod = 1f; //玩家連續受傷之時時間隔
public AudioClip[] ouchClips; //玩家受傷音效
public float hurtForce = 100f; //玩家受傷時受到之推力
public float damageAmount = 10f; //每次受傷之損血值
private SpriteRenderer healthBar; //玩家生命條之sprite renderer參照
private float lastHitTime; //前次受傷時間戳記
private Vector3 healthScale; //生命條滿格時之大小
private PlayerControl playerControl; //玩家PlayerControl程式腳本參照
private Animator anim; //玩家動作控制器參照
玩家生命值管理 1/4
24
- 25. void Awake () {
playerControl = GetComponent<PlayerControl>(); //玩家PlayerControl參照
healthBar = GameObject.Find("HealthBar").GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>(); //玩家動作控制器參照
healthScale = healthBar.transform.localScale; //記錄生命條滿格之大小
}
void OnCollisionEnter2D (Collision2D col) {
if (col.gameObject.tag == "Enemy") { //敵人撞到玩家
if (Time.time > lastHitTime + repeatDamagePeriod) { //已達連續受傷之時間間隔
if (health > 0f) {
TakeDamage(col.transform); //使玩家損血
lastHitTime = Time.time; //記錄受傷時間
}
else { //玩家死��,使玩家摔落河裡
Collider2D[] cols = GetComponents<Collider2D>();
foreach (Collider2D c in cols) { //將所有Collider2D調整為觸發器
c.isTrigger = true;
}
SpriteRenderer[] spr = GetComponentsInChildren<SpriteRenderer>();
玩家生命值管理 2/4
25
- 26. foreach(SpriteRenderer s in spr) { //將玩家角色移到UI圖層
s.sortingLayerName = "UI";
}
GetComponent<PlayerControl>().enabled = false; //停止PlayerControl程式腳本
GetComponentInChildren<Gun>().enabled = false; //停止Gun程式腳本
anim.SetTrigger("Die"); //觸發Die動畫
}
}
}
}
void TakeDamage (Transform enemy) {
playerControl.jump = false; //停止跳躍
Vector3 hurtVector = transform.position - enemy.position + Vector3.up * 5f;
GetComponent<Rigidbody2D>().AddForce(hurtVector * hurtForce);//向玩家施加衝撞力
health -= damageAmount; //扣減玩家血量
UpdateHealthBar(); //更新顯示生命條
int i = Random.Range (0, ouchClips.Length); //隨機撥放玩家受傷音效
AudioSource.PlayClipAtPoint(ouchClips[i], transform.position);
}
玩家生命值管理 3/4
26
- 27. public void UpdateHealthBar () {
//根據玩家的生命值,將生命條的顏色設置為綠色和紅色之間的比例
healthBar.material.color = Color.Lerp(Color.green, Color.red, 1 - health * 0.01f);
//根據玩家的生命值,調整生命條的寬度
healthBar.transform.localScale = new Vector3(healthScale.x * health * 0.01f, 1, 1);
}
}
拖曳Assets/Audio/Player/Ouch/Player-ouch[1-4].wav到Ouch
Clips欄
玩家生命值管理 4/4
27
- 29. 在Main Camera加入CameraFollow.cs程式腳本
using UnityEngine;
using System.Collections;
public class CameraFollow : MonoBehaviour {
public float xMargin = 1f; //攝影機啟動跟隨前允許玩家移動的水平位移
public float yMargin = 1f; //攝影機啟動跟隨前允許玩家移動的垂直位移
public float xSmooth = 8f; //使相機平穩地捕捉目標運動之X軸修正值
public float ySmooth = 8f; //使相機平穩地捕捉目標運動之Y軸修正值
public Vector2 maxXAndY; //攝影機位置X與Y座標最大值
public Vector2 minXAndY; //攝影機位置X與Y座標最小值
private Transform player; //玩家角色transform屬性
void Awake () {
player = GameObject.FindGameObjectWithTag("Player").transform;
}
bool CheckXMargin() {
return Mathf.Abs(transform.position.x - player.position.x) > xMargin;
}
攝影機跟隨玩家移動 2/4
29
- 30. bool CheckYMargin() {
return Mathf.Abs(transform.position.y - player.position.y) > yMargin;
}
void FixedUpdate () {
TrackPlayer();
}
void TrackPlayer () {
float targetX = transform.position.x;
float targetY = transform.position.y;
if (CheckXMargin())
targetX = Mathf.Lerp(transform.position.x,
player.position.x, xSmooth * Time.deltaTime);
if (CheckYMargin())
targetY = Mathf.Lerp(transform.position.y,
player.position.y, ySmooth * Time.deltaTime);
targetX = Mathf.Clamp(targetX, minXAndY.x, maxXAndY.x);
targetY = Mathf.Clamp(targetY, minXAndY.y, maxXAndY.y);
transform.position = new Vector3(targetX, targetY, transform.position.z);
}
}
攝影機跟隨玩家移動 3/4
30
- 31. 設定Camera Follow參數
X Margin = 2,Y Margin = 2
X Smooth = 2,Y Smooth = 2
Max(X, Y) = (5, 5)
Min(X, Y) = (-5, -5)
測試遊戲,玩家水平或垂直位移超過2時,攝影機就會自動跟隨
攝影機跟隨玩家移動 4/4
31
- 32. 選取Assets/Prefabs/Props/rocket.prefab
子物件Sorting Layer = Character
在Mr.Bean的Gun子物件加入Gun.cs腳本
using UnityEngine;
using System.Collections;
public class Gun : MonoBehaviour {
public Rigidbody2D rocket; //rocket預製物件
public float speed = 25f; //rocket速度
private PlayerControl playerCtrl; //PlayerControl程式腳本參照
private Animator anim; //角色動畫控制器參照
void Awake() {
anim = transform.root.gameObject.GetComponent<Animator>();
playerCtrl = transform.root.GetComponent<PlayerControl>();
}
Mr.Bean射擊控制 1/3
32
- 33. void Update () {
if (Input.GetButtonDown("Fire1")) { //按下發射鍵
anim.SetTrigger("Shoot");
GetComponent<AudioSource>().Play();
if (playerCtrl.facingRight) { //向右發射
Rigidbody2D bulletInstance = Instantiate(rocket, transform.position,
Quaternion.Euler(new Vector3(0, 0, 0))) as Rigidbody2D;
bulletInstance.velocity = new Vector2(speed, 0);
}
else { //向左發射
Rigidbody2D bulletInstance = Instantiate(rocket, transform.position,
Quaternion.Euler(new Vector3(0, 0, 180f))) as Rigidbody2D;
bulletInstance.velocity = new Vector2(-speed, 0);
}
}
}
}
Mr.Bean射擊控制 2/3
33
- 35. 選單命令GameObject> UI> Text,命名為Score
Anchor Presets = top, center
Pos(X, Y, Z) = (0, -10, 0)
Width = 500, Height = 100
Pivot(X, Y) = (0.5, 1)
Text = Score
Font = BradBunR
Font Size = 80
Alignment = Center
Color = white
加入計分板 1/5
35
- 36. 在Score加入Score.cs程式腳本
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class Score : MonoBehaviour {
public int score = 0; //玩家分數值
void Update () {
GetComponent<Text>().text = "Score: " + score; //更新顯示分數
}
}
加入計分板 2/5
36
- 37. 選單命令GameObject> UI> Text,命名為Score-shadow
Anchor Presets = top, center
Pos(X, Y, Z) = (0, -14, 0)
Width = 500, Height = 100
Pivot(X, Y) = (0.5, 1)
Text = Score
Font = BradBunR
Font Size = 80
Alignment = Center
Color = black
加入計分板 3/5
37
- 38. 在Score-shadow加入ScoreShadow.cs程式腳本
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class ScoreShadow : MonoBehaviour {
public GameObject guiCopy; // Score物件參照
void Awake () {
Vector3 behindPos = transform.position;
behindPos = new Vector3(guiCopy.transform.position.x,
guiCopy.transform.position.y - 4f,
guiCopy.transform.position.z);
transform.position = behindPos;
}
void Update () {
GetComponent<Text>().text = guiCopy.GetComponent<Text>().text; //同步更新資料
}
}
加入計分板 4/5
38
- 41. 選單命令GameObject> Create Empty建立空物件,命名為
EnemySpawners
重置Transform
Position(X,Y,Z) = (0, 15, 0)
選單命令GameObject> Create Empty Child,在EnemySpawners
建立⼀個空子物件,命名為MidSpawner
重置Transform
Position(X,Y,Z) = (0.27, 0, 0)
在MidSpawner加入EnemySpawner.cs腳本
隨機生成敵人 2/5
41
- 42. using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawner : MonoBehaviour {
public float spawnTime = 5f; //敵人生成間隔時間
public float spawnDelay = 3f; //延遲時間後才開始生成
public GameObject[] enemies; //敵人預製物件庫
void Start () {
InvokeRepeating("Spawn", spawnDelay, spawnTime);
}
void Spawn () {
int enemyIndex = Random.Range(0, enemies.Length);
Instantiate(enemies[enemyIndex], transform.position, transform.rotation);
}
}
隨機生成敵人 3/5
42
- 45. 選單命令GameObject> Create Empty建立空物件,命名Destroyer
Position(X, Y, Z) = (0.54, -13.5, 0)
Scale(X, Y, Z) = (1.9, 1, 1)
加入Box Collider 2D
勾選Is Trigger
Size(X, Y) = (23, 1.9)
角色溺水作業 1/4
45
- 46. 在Destroyer物件加入Remover.cs程式腳本
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
public class Remover : MonoBehaviour {
public GameObject splash; //水花噴濺特效預製物件
void OnTriggerEnter2D(Collider2D col) {
if (col.gameObject.tag == "Player") { //玩家掉落河裡
GameObject.FindGameObjectWithTag("MainCamera").GetComponent<CameraFollow>()
.enabled = false;
GameObject.FindGameObjectWithTag("HealthBar").GetComponent<FollowPlayer>().
enabled = false;
Instantiate(splash, col.transform.position, transform.rotation);
Destroy (col.gameObject);
StartCoroutine("ReloadGame"); //執行重新載入關卡程序
}
角色溺水作業 2/4
46
- 47. else { //其它角色掉落河裡
Instantiate(splash, col.transform.position, transform.rotation);
Destroy (col.gameObject);
}
}
IEnumerator ReloadGame() {
yield return new WaitForSeconds(2); //等待2秒
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex,
LoadSceneMode.Single);
}
}
角色溺水作業 3/4
47
- 50. using UnityEngine;
using System.Collections;
public class HealthPickup : MonoBehaviour {
public float healthBonus; //補充生命值
public AudioClip collect; //收集道具時之音效
private PickupSpawner pickupSpawner; //PickupSpawner程式腳本參照
private Animator anim; //動畫控制器參照
private bool landed; //道具箱落地旗號
void Awake () {
pickupSpawner = GameObject.Find("pickupManager").GetComponent<PickupSpawner>();
anim = transform.root.GetComponent<Animator>();
}
void OnTriggerEnter2D (Collider2D other) {
if (other.tag == "Player") { //玩家碰到道具箱
PlayerHealth playerHealth = other.GetComponent<PlayerHealth>();
playerHealth.health += healthBonus; //補充玩家生命值
playerHealth.health = Mathf.Clamp(playerHealth.health, 0f, 100f); //上限值100
製作空投道具箱 2/5
50
- 52. 在Assets/Prefabs/Props/bombCrate.prefab之crate子物件加入
BombPickup.cs程式腳本
using UnityEngine;
using System.Collections;
public class BombPickup : MonoBehaviour {
public AudioClip pickupClip; //收集道具時之音效
private Animator anim; //動畫控制器參照
private bool landed = false; //道具箱落地旗號
void Awake() {
anim = transform.root.GetComponent<Animator>();
}
void OnTriggerEnter2D (Collider2D other) {
if (other.tag == "Player") { //玩家碰到道具箱
AudioSource.PlayClipAtPoint(pickupClip, transform.position);
other.GetComponent<LayBombs>().bombCount++; //增加玩家炸彈數量
Destroy(transform.root.gameObject); //銷毀道具箱
}
製作空投道具箱 4/5
52
- 53. else if (other.tag == "ground" && !landed) { //道具箱落地
anim.SetTrigger("Land"); //觸發道具箱落地動畫
transform.parent = null;
gameObject.AddComponent<Rigidbody2D>();
landed = true;
}
}
}
拖曳Assets/Audio/Player/Taunts/Player-IDefyYou.wav到
Pickup Clip欄
製作空投道具箱 5/5
53
- 55. using UnityEngine;
using System.Collections;
public class PickupSpawner : MonoBehaviour {
public GameObject[] pickups; //道具預製物件陣列
public float pickupDeliveryTime = 5f; //傳送道具等待時間
public float dropRangeLeft; //道具空投範圍左邊界坐標
public float dropRangeRight; //道具空投範圍右邊界坐標
public float highHealthThreshold = 75f; //玩家生命值超過此設定值時,只空投炸彈道具
public float lowHealthThreshold = 25f; //玩家生命值低於此設定值時,只空投傷藥道具
private PlayerHealth playerHealth; //PlayerHealth程式腳本參照
void Awake () {
playerHealth = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerHea
lth>();
}
空投道具 2/4
55
- 56. void Start () {
StartCoroutine(DeliverPickup()); //啟動DeliverPickup程序
}
public IEnumerator DeliverPickup() {
yield return new WaitForSeconds(pickupDeliveryTime); //等待一段指定時間
float dropPosX = Random.Range(dropRangeLeft, dropRangeRight);//隨機空投X坐標
Vector3 dropPos = new Vector3(dropPosX, 15f, 1f); //空投位置
if (playerHealth.health >= highHealthThreshold) //空投炸彈
Instantiate(pickups[0], dropPos, Quaternion.identity);
else if (playerHealth.health <= lowHealthThreshold) //空投傷藥
Instantiate(pickups[1], dropPos, Quaternion.identity);
else { //隨機空投道具
int pickupIndex = Random.Range(0, pickups.Length);
Instantiate(pickups[pickupIndex], dropPos, Quaternion.identity);
}
}
}
空投道具 3/4
56
- 57. 設定Pickups Spawner
拖曳Assets/Prefabs/Props/bombCrate.prefab到Pickups欄
拖曳Assets/Prefabs/Props/healthCrate.prefab到Pickups欄
Pickup Delivery Time = 5
Drop Range Left = -15
Drop Range Right = 15
High Health Threshold = 75
Low Health Threshold = 25
測試遊戲,會隨機飄下道具
玩家Player Health之Health值小於25時,⼀定飄下急救箱
玩家Player Health之Health值大於75時,⼀定飄下炸彈
空投道具 4/4
57
- 58. 選單命令GameObject> UI> Raw Image,命名為ui_bombHUD
Anchor Presets = bottom, left
Pos(X, Y, Z) = (10, 10, 0)
Width = 84, Height = 70
Pivot(X, Y) = (0, 0)
拖曳Assets/Sprites/_Props/
prop_crate_ammo.png到Texture欄
製作炸彈圖示
58
- 59. 將Assets/Prefabs/Props/explosionParticle.prefab加到場景
選取Assets/Prefabs/Props/bomb.prefab
Sorting Layer = Character
在Mr.Bean加入LayBombs.cs程式腳本
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class LayBombs : MonoBehaviour {
[HideInInspector]
public bool bombLaid = false; //玩家是否已放置炸彈
public int bombCount = 0; //玩家擁有的炸彈道具個數
public AudioClip bombsAway; //玩家放置炸彈時的語音
public GameObject bomb; //炸彈預製物件
private RawImage bombHUD; //炸彈道具圖示參照,當玩家擁有後就會開啟圖示
玩家放置炸彈 1/3
59
- 60. void Awake () {
bombHUD = GameObject.Find("ui_bombHUD").GetComponent<RawImage>();
}
void Update () {
if (Input.GetButtonDown("Fire2") && !bombLaid && bombCount > 0) { //放置炸彈
bombCount--;
bombLaid = true;
AudioSource.PlayClipAtPoint(bombsAway,transform.position);
Instantiate(bomb, transform.position, transform.rotation);
}
bombHUD.enabled = bombCount > 0; //更新炸彈圖示狀態
}
}
玩家放置炸彈 2/3
60
- 62. 選單命令GameObject> Create Empty建立空物件,命名GameManager
在GameManager加入Pauser.cs程式腳本
using UnityEngine;
using System.Collections;
public class Pauser : MonoBehaviour {
private bool paused = false;
void Update () {
if (Input.GetKeyUp(KeyCode.P)) { //按了P鍵
paused = !paused; //切換暫停狀態
}
if (paused)
Time.timeScale = 0;
else
Time.timeScale = 1;
}
}
測試遊戲,按P鍵可暫停遊戲
遊戲控制 1/2
62
- 63. 編輯GameManager.cs程式腳本,按Esc鍵可結束遊戲
using UnityEngine;
using System.Collections;
public class Pauser : MonoBehaviour {
private bool paused = false;
void Update () {
if (Input.GetKey (KeyCode.Escape)) { //按了Esc鍵
Application.Quit (); //結束遊戲
}
if (Input.GetKeyUp(KeyCode.P)) { //按了P鍵
...
}
}
註:需建立執行檔測試
遊戲控制 2/2
63