SlideShare a Scribd company logo
1 of 92
Download to read offline
Space shooter遊戲
Revised on March 28, 2019
⼀款俯視⾓太空射擊遊戲,學習場景光
照設定、戰機移動控制、射擊控制、隕
石群生成、敵動迴避移動、爆炸效果、
背景音樂
 滙入時取消勾選ProjectSettings項目
Space Shooter tutorial套件
2
 https://unity3d.com/learn/tutorials/projects/space-shooter-
tutorial
線上教學影片
3
 新增3D專案
 選單命令File> New Project…
 專案名稱Space shooter
 儲存預設場景
 Main.unity
 滙入Space Shooter tutorial.unitypackage
 選單命令Assets> Import Package> Custom Package…
專案設定 1/2
4
 設定場景大小
 選單命令File> Build Settings…
 點擊Player Settings...按鈕
 Fullscreen Mode = Windowed
 Default Screen Width: 600
 Default Screen Height: 900
專案設定 2/2
5
 拖曳Modelsvehicle_playerShip到Hiearchy面板
 重新命名:Player
 重置Transform參數值
 設定Player戰機為剛體物件
 選單命令Component> Physics> Rigidbody
 取消勾選Use Gravity以符合外太空無重力環境
建立玩家戰機物件 1/2
6
 在Player戰機上加上網格碰撞器
 選單命令Component> Physics> Mesh Collider
 勾選Convex
 勾選Is Trigger
 簡化網格,拖曳Modelsplayer_ship_collider到Mesh欄
 設定Player戰機引擎噴射效果
 拖曳PrefabsVFXEnginesengines_player預製物件成為Player子物件
建立玩家戰機物件 2/2
7
 重置Main Camera之Transform參數值
 使Main Camera朝下
 Rotation(X, Y, Z) = (90, 0, 0)
 使Main Camera移動到Player戰機上方
 Position(X, Y, Z) = (0, 10, 0)
 將Main Camera投影方式設定為正交投影
 Projection = Orthographic
 Size = 10
攝影機設定 1/2
8
 調整Main Camera之Z軸位置來變更Player戰機初始顯示位置
 Position(X, Y, Z) = (0, 10, 5)
 設定Main Camera鏡頭底色
 Clear Flags = Solid Color
 Background = black
攝影機設定 2/2
9
 刪除Directional Light
 取消環境光
 選單命令Window> Rendering> Lighting Settings開啟Lighting面板
 Skybox Material = none
 Ambient Color = black
光照設定 1/3
10
 建立主光源
 選單命令GameObject> Light> Directional Light,更名為Main
Light
 重置Transform
 調整光線⾓度,Rotation(X, Y, Z) = (20, -115, 0)
 建立補光
 選取Main Light,Ctrl-D複製,更名為Fill Light
 重置Transform
 調整補光強度,Intensity = 0.5
 調整補光⾓度,Rotation(X, Y, Z) = (5, 125, 0)
 調整補光顏色,Color(R, G, B) = (128, 192, 192)
光照設定 2/3
11
 建立邊緣反射光
 複製Fill Light,更名為Rim Light
 重置Transform
 調整邊緣反射光顏色,Color = white
 調整邊緣反射光⾓度,Rotation(X, Y, Z) = (-15, 65, 0)
 調整邊緣反射光強度,Intensity = 0.25
 管理光源物件
 選單命令GameObject> Create Empty,更名為Lighting
 重置Transform
 Position(X, Y, Z) = (0, 100, 0)
 將Main Light、Fill Light及Rim Light拖曳到Lighting下做為子物件
光照設定 3/3
12
 選單命令GameObject> 3D Object> Quad,新增Quad做為背景物件,
更名為Background
 重置Transform屬性值
 使Background物件面向Main Camera
 Rotation(X, Y, Z) = (90, 0, 0)
 調整Background物件大小,使其可以填滿整個遊戲畫面
 Scale(X, Y, Z) = (15, 30, 0)
 設定背景材質
 拖曳Texturestile_nebula_green_diff到Background上
設定遊戲背景 1/2
13
 移除Mesh Collider
 將材質Shader欄變更為Unlit/Texture
 調整Background物件位置到Player戰機下方
 Position(X, Y, Z) = (0, -10, 0)
設定遊戲背景 2/2
14
 在Player物件加上PlayerController程式腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
void FixedUpdate () {
Rigidbody rigidBody = GetComponent<Rigidbody> ();
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
rigidBody.velocity = movement;
}
}
玩家戰機移動控制 1/5
15
 執行測試,可使用方向鍵移動Player戰機,但是…
 移動速度很慢
 在PlayerController程式腳本加入速度參數
public class PlayerController : MonoBehaviour {
public float speed;
void FixedUpdate () {
Rigidbody rigidBody = GetComponent<Rigidbody> ();
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
rigidBody.velocity = movement * speed;
}
}
玩家戰機移動控制 2/5
16
 將PlayerController之Speed欄設定為10
 執行測試,Player戰機移動速度變快了,但是…
 Player戰機會跑出螢幕
 修改PlayerController程式腳本,限制Player戰機移動範圍
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Boundary {
public float xMin, xMax, zMin, zMax;
}
玩家戰機移動控制 3/5
17
public class PlayerController : MonoBehaviour {
public float speed;
public float tilt;
public Boundary boundary;
void FixedUpdate () {
Rigidbody rigidBody = GetComponent<Rigidbody> ();
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
rigidBody.velocity = movement * speed;
rigidBody.position = new Vector3 (
Mathf.Clamp (rigidBody.position.x, boundary.xMin, boundary.xMax),
0.0f,
Mathf.Clamp (rigidBody.position.z, boundary.zMin, boundary.zMax));
rigidBody.rotation = Quaternion.Euler (
0.0f, 0.0f, rigidBody.velocity.x * -tilt);
}
}
玩家戰機移動控制 4/5
18
 設定Player戰機之Boundry值
 調整Player戰機Position之X值,測試最左及最右位置值
 調整Player戰機Position之Z值,測試上方及下方位置值
 執行測試,Player戰機不會跑出場景範圍了
玩家戰機移動控制 5/5
19
 選單命令GameObject> Create Empty,更名為Bolt
 重置Transform屬性值
 選單命令GameObject> 3D Object> Quad,更名為VFX
 重置Transform屬性值
 使VFX面向Main Camera
 Rotation(X, Y, Z) = (90, 0, 0)
 移除Mesh Collider元件
 拖曳VFX成為Bolt子物件
建立玩家戰機子彈 1/5
20
 選單命令Assets> Create> Material新增材質球,更名為
fx_bolt_orange
 Shader = Mobile/Particles/Additive
 Particle Texture = fx_lazer_orange_dff
 拖曳fx_bolt_orange材質到VFX物件上
建立玩家戰機子彈 2/5
21
 Bolt物件加上Rigidbody元件
 取消勾選Use Gravity
 Bolt物件加上Capsule Collider元件
 Direction = Z-Axis
 Radius = 0.03,Height = 0.5
 勾選Is Trigger
建立玩家戰機子彈 3/5
22
 Bolt物件加上Mover程式腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mover : MonoBehaviour {
[SerializeField]
private float speed;
// Use this for initialization
void Start () {
GetComponent<Rigidbody>().velocity = transform.forward * speed;
}
}
建立玩家戰機子彈 4/5
23
 將Bolt物件拖到Prefabs資料夾做為預製物件
 Speed = 20
 刪除場景中的Bolt物件
 執行測試,將Bolt預製物件拖曳到Hierarchy面板,檢視Game視窗,
子彈是否向前飛去
建立玩家戰機子彈 5/5
24
 選單命令GameObject> Create Empty,更名為Shot Spawn
 重置Transform
 拖曳Shot Spawn成為Player子物件
 調整Shot Spawn位置到戰機之前端,Position(X, Y, Z) = (0, 0, 1)
玩家戰機子彈發射控制 1/3
25
 編輯Player物件之PlayerController程式腳本
public class PlayerController : MonoBehaviour {
public float speed;
public float tilt;
public Player_Boundary boundary;
public GameObject shot;
public Transform shotSpawn;
public float fireRate;
private float nextFire;
void Update () {
if (Input.GetButton("Fire1") && Time.time > nextFire) {
nextFire = Time.time + fireRate;
Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
}
}
...
}
玩家戰機子彈發射控制 2/3
26
 拖曳Bolt預製物件到Player Controller之Shot欄
 拖曳Shot Spawn物件到Player Controller之Shot Spawn欄
 將Player Controller之Fire Rate欄值設為0.25
 執行測試,按下滑鼠左鍵可發射子彈,但是...
 檢視Hierarchy面板,子彈物件會不斷生成,但不會自動銷毀
玩家戰機子彈發射控制 3/3
27
 選單命令GameObject> 3D Object> Cube,更名為Boundary
 重置Transform屬性值
 勾選Box Collider之Is Trigger
 使Boundary物件置中顯示
 Position (X, Y, Z) = (0, 0, 5) 參照Main Camera之Z座標設定
 使Boundary物件涵蓋整個遊戲場景
 Scale (X, Y, Z) = (15, 1, 20)
 移除Mesh Renderer元件
 移除Mesh Filter元件
設定玩家戰機子彈邊界 1/3
28
設定玩家戰機子彈邊界 2/3
29
 Boundary物件加上DestroyByBoundry程式腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DestroyByBoundary : MonoBehaviour {
void OnTriggerExit(Collider other) {
Destroy(other.gameObject);
}
}
 測試程式,檢視Hirarchy面板,子彈物件碰到Bundary後會自動銷毀
設定玩家戰機子彈邊界 3/3
30
 選單命令GameObject> Create Empty,更名為Asteroid
 Position(X, Y, Z) = (0, 0, 8)
 拖曳Models/prop_asteroid_01成為Asteroid子物件
 重置prop_asteroid_01物件Transform設定
 在Asteroid物件加上Rigidbody元件
 取消勾選Use Gravity
 在Asteroid物件加上Capsule Collider元件
 調整Radius及Height使其符合物件大小
 Direction = Y-Axis
 Radius = 0.486
 Height = 1.524
建立隕石 1/4
31
 Asteroid物件加上RandomRotator程式腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RandomRotator : MonoBehaviour {
[SerializeField]
private float tumble;
void Start () {
GetComponent<Rigidbody>().angularVelocity = Random.insideUnitSphere*tumble;
}
}
 Asteroid物件之Tumble設定為5
 執行測試,隕石會自主轉動,但是...
 子彈會直接穿過隕石
建立隕石 2/4
32
 Asteroid物件加上DestroyByContact程式腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DestroyByContact : MonoBehaviour {
void OnTriggerEnter(Collider other) {
if (other.CompareTag ("Boundary")) {
return;
}
Destroy(other.gameObject);
Destroy(gameObject);
}
}
建立隕石 3/4
33
 將Boundary物件之Tag設定為Boundary
 執行測試
 子彈碰到隕石時,子彈與隕石都會自動銷毀
建立隕石 4/4
34
 編輯DestroyByContact程式腳本
public class DestroyByContact : MonoBehaviour {
[SerializeField]
private GameObject explosion;
void OnTriggerEnter(Collider other) {
if (other.CompareTag ("Boundary")) {
return;
}
Instantiate(explosion, transform.position, transform.rotation);
Destroy(other.gameObject);
Destroy(gameObject);
}
}
 拖曳PrefabsVFXExplosionsexplosion_asteroid預製物件到
Explosion欄
爆破效果 1/4
35
 執行測試,子彈碰到隕石時隕石會有爆破效果,但是...
 戰機撞到隕石時,隕石會爆破效果而戰機則是直接銷毀
 將Player物件之Tag設定為Player
爆破效果 2/4
36
 編輯DestroyByContact程式腳本
public class DestroyByContact : MonoBehaviour {
[SerializeField]
private GameObject explosion;
[SerializeField]
private GameObject playerExplosion;
void OnTriggerEnter(Collider other) {
...
Instantiate(explosion, transform.position, transform.rotation);
if (other.CompareTag ("Player")) {
Instantiate(playerExplosion,
other.transform.position, other.transform.rotation);
}
Destroy(other.gameObject);
Destroy(gameObject);
}
 拖曳PrefabsVFXExplosionsexplosion_player預製物件到
Player Explosion欄
爆破效果 3/4
37
 執行測試,戰機撞到隕石時,隕石與戰機都會產生爆破效果後銷毀
 Asteroid物件加上Mover程式腳本
 設定Speed為-5
 執行測試,隕石會自動向下墜落
爆破效果 4/4
38
 將Asteroid物件拖曳到Prefabs資料夾做
成預製物件
 刪除場景上的Asteroid物件
 選單命令GameObject> Create Empty,更名為Game Controller
 重置Transform
 設定Tag為GameController
遊戲控制 1/3
39
 Game Controller物件加上GameController程式腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour {
[SerializeField]
private GameObject hazard;
[SerializeField]
private Vector3 spawnValues;
void Start () {
SpawnWaves ();
}
void SpawnWaves () {
Vector3 spawnPosition = new Vector3 (
Random.Range (-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate (hazard, spawnPosition, spawnRotation);
}
}
遊戲控制 2/3
40
 拖曳Asteroid預製物件到Hazard欄
 設定SpawnValues(X, Y, Z) = (6, 0, 16)
 執行測試,每次執行隕石會由不同位置墜落
遊戲控制 3/3
41
 編輯GameController程式腳本
public class GameController : MonoBehaviour {
[SerializeField]
private GameObject hazard;
[SerializeField]
private Vector3 spawnValues;
[SerializeField]
private int hazardCount;
[SerializeField]
private float spawnWait;
[SerializeField]
private float startWait;
[SerializeField]
private float waveWait;
void Start () {
StartCoroutine (SpawnWaves ());
}
設定隕石群 1/4
42
IEnumerator SpawnWaves () {
yield return new WaitForSeconds (startWait);
while (true) {
for (int i = 0; i < hazardCount; i++) {
Vector3 spawnPosition = new Vector3 (
Random.Range (-spawnValues.x, spawnValues.x),
spawnValues.y,
spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate (hazard, spawnPosition, spawnRotation);
yield return new WaitForSeconds (spawnWait);
}
yield return new WaitForSeconds (waveWait);
}
}
}
設定隕石群 2/4
43
 Game Controller參數
 Hazard Count = 10
 Spawn Wait = 0.4
 Start Wait = 1
 Wave Wait = 4
 執行測試,隕石會定時自動生成,但是...
 擊破隕石時生成的爆破效果物件不會自動銷毀
設定隕石群 3/4
44
 建立DestroyByTime程式腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DestroyByTime : MonoBehaviour {
[SerializeField]
private float lifetime;
void Start () {
Destroy (gameObject, lifetime);
}
}
設定隕石群 3/4
45
 在explosion_asteroid預製物件及explosion_player預製物件加
入DestroyByTime程式腳本
 Lifetime設定為2
 執行測試,隕石會定時自動生成,爆破特效物件也會在2秒後自動銷毀
設定隕石群 4/4
46
 在explosion_asteroid預製物件加上Audio Source元件
 拖曳Audioexplosion_asteroid到explosion_asteroid預製物件之
AudioClip欄
 勾選Play On Awake
加入音效 1/4
47
 在explosion_player預製物件加上Audio Source元件
 拖曳Audioexplosion_player到AudioClip欄
 勾選Play On Awake
加入音效 2/4
48
 在Player物件加上Audio Source元件
 拖曳Audioweapon_player到AudioClip欄
 取消勾選Play On Awake
 Volume設為0.5
加入音效 3/4
49
 編輯Player物件之Player Controller程式腳本
void Update () {
if (Input.GetButton("Fire1") && Time.time > nextFire) {
nextFire = Time.time + fireRate;
Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
GetComponent<AudioSource>().Play();
}
}
加入音效 4/4
50
 在GameController物件加上Audio Source元件
 拖曳Audiomusic_background到GameController物件之AudioClip欄
 勾選Play On Awake
 勾選Loop
 Volume設為0.5
加入背景音樂
51
 選單命令GameObject> UI> Text,更名為Score Text
 重置Rect Transform
 Color = white
 Anchor Presets = left, top (同時按Shift + Alt)
計算及顯示分數 1/6
52
 編輯GameController程式腳本
using UnityEngine.UI;
public class GameController : MonoBehaviour {
...
public float waveWait;
[SerializeField]
private Text scoreText;
private int score;
void Start () {
score = 0;
UpdateScore ();
StartCoroutine (SpawnWaves ());
}
計算及顯示分數 2/6
53
public void AddScore (int newScoreValue) {
score += newScoreValue;
UpdateScore ();
}
void UpdateScore () {
scoreText.text = "Score: " + score;
}
...
}
計算及顯示分數 3/6
54
 拖曳Score Text物件到Game Controller物件之Score Text欄
計算及顯示分數 4/6
55
 編輯DestroyByContact程式腳本
public class DestroyByContact : MonoBehaviour {
...
private GameObject playerExplosion;
[SerializeField]
private int scoreValue;
private GameObject gameController;
void Start () {
gameController = GameObject.Find ("Game Controller");
}
void OnTriggerEnter(Collider other) {
...
Destroy(other.gameObject);
Destroy(gameObject);
gameController.GetComponent<GameController> ().AddScore (scoreValue);
}
}
計算及顯示分數 2/6
56
 將Asteroid預製物件之Score Value設定為10
 執行測試,每擊破⼀個隕石增加10分
計算及顯示分數 3/6
57
 選單命令GameObject> UI> Text,更名為Restart Text
 重置Rect Transform
 Width = 200
 Anchor Presets = right, top (同時按Shift + Alt)
 Color = white
 Paragraph Alignment = left
結束遊戲作業 1/7
58
 選單命令GameObject> UI> Text,更名為Gameover Text
 重置Rect Transform
 Anchor Presets = middle, center
 Font Size = 18
 Paragraph Alignment = center
 Color = yellow
結束遊戲作業 2/7
59
 編輯GameController程式腳本
using UnityEngine.SceneManagement;
public class GameController : MonoBehaviour {
...
private int score;
[SerializeField]
private Text restartText;
[SerializeField]
private Text gameOverText;
private bool gameOver;
private bool restart;
void Start () {
gameOver = false;
restart = false;
restartText.text = "";
gameOverText.text = "";
score = 0;
...
}
結束遊戲作業 3/7
60
IEnumerator SpawnWaves () {
...
yield return new WaitForSeconds (waveWait);
if (gameOver) {
restartText.text = "Press 'R' for Restart";
restart = true;
break;
}
}
}
結束遊戲作業 4/7
61
void Update () {
if (restart) {
if (Input.GetKeyDown (KeyCode.R)) {
SceneManager.LoadScene ("Main");
}
}
}
public void GameOver () {
gameOverText.text = "Game Over!";
gameOver = true;
}
}
結束遊戲作業 5/7
62
 編輯DestroyByContact程式腳本
public class DestroyByContact : MonoBehaviour {
...
void OnTriggerEnter(Collider other) {
...
if (other.tag == "Player") {
Instantiate(playerExplosion,
other.transform.position,
other.transform.rotation);
gameController.GetComponent<GameController> ().GameOver();
}
...
}
}
結束遊戲作業 6/7
63
 拖曳Restart Text物件到Game Controller物件之Restart Text欄
 拖曳Gameover Text物件到Game Controller物件之Game Over
Text欄
 執行測試,玩家戰機會顯示Game over!,等下⼀波隕石群時顯示
Press 'R' for Restart,按下R鍵即可重玩
結束遊戲作業 7/7
64
 將PrefabsAsteroid預製物件更名為Asteroid01
 設定Asteroid01之Tag屬性值為"Enemy"
 拖曳PrefabsAsteroid01預製物件到場景上
 Ctrl-D複製2份,分別更名為Asteroid02及Asteroid03
 拖曳Asteroid02及Asteroid03到Prefabs資料夾做成預製物件
 刪除場景上的Asteroid01、Asteroid02及Asteroid03
建立不同隕石 1/5
65
 開啟Asteroid02預製物件
 拖曳Modelsprop_asteroid_02成為Asteroid02子物件
 刪除Asteroid02prop_asteroid_01子物件
 Capsule Collider
 Radius = 0.45
 Height = 1.37
 Direction = X-Axis
建立不同隕石 2/5
66
 開啟Asteroid03預製物件
 拖曳Modelsprop_asteroid_03成為Asteroid03子物件
 刪除Asteroid03prop_asteroid_01子物件
 Capsule Collider
 Radius = 0.55
 Height = 1.5
 Direction = X-Axis
建立不同隕石 3/5
67
 更新GameController程式腳本
public class GameController : MonoBehaviour {
[SerializeField]
private GameObject hazard;
private GameObject[] hazards;
...
IEnumerator SpawnWaves () {
yield return new WaitForSeconds (startWait);
while (true) {
for (int i = 0; i < hazardCount; i++) {
GameObject hazard = hazards[Random.Range (0, hazards.Length)];
...
}
}
}
...
}
建立不同隕石 4/5
68
 拖曳Asteroid01、Asteroid02及Asteroid03預製物件到Game
Controller之到Hazards欄
 測試遊戲,會隨機出現不同的隕石
建立不同隕石 5/5
69
 拖曳PrefabsVFXStarFieldStarField預製物件到場景上
加上星空粒子特效
70
 Ctrl-D複製Background
 拖曳Background (1)成為Background子物件
 調整Background (1)位置使它與Background串接
 Position(X, Y, Z) = (0, -1, 0)
 Rotation(X, Y, Z) = (0, 0, 0)
 Scale(X, Y, Z) = (1, 1, 1)
捲動背景 1/4
71
捲動背景 2/4
72
Background
Background (1)
 在Background加入BGScroller程式腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BGScroller : MonoBehaviour {
[SerializeField]
private float scrollSpeed;
[SerializeField]
private float tileSizeZ;
private Vector3 startPosition;
void Start() {
startPosition = transform.position;
}
void Update() {
float newPosition = Mathf.Repeat (Time.time * scrollSpeed, tileSizeZ);
transform.position = startPosition + Vector3.forward * newPosition;
}
}
捲動背景 3/4
73
 設定BG Scroller屬性值
 Scroll Speed = -0.25
 Tile Size Z = 30
 執行測試,背景會緩慢向下捲動
捲動背景 4/4
74
 在PrefabsVFXExplosionsexplosion_enemy預製物件加入
DestroyByTime程式腳本
 Lifetime設定為2
 在PrefabsVFXExplosionsexplosion_enemy預製物件加上
Audio Source元件
 拖曳Audioexplosion_enemy到AudioClip欄
 勾選Play On Awake
製作敵機爆炸特效
75
 選單命令GameObject> Create Empty,更名為Enemy Ship
 重置Transform屬性值
 Position(X, Y, Z) = (0, 0, 9)
 Tag = Enemy
 拖曳Modelsvehicle_enemyShip成為Enemy Ship子物件
 Rotation(X, Y, Z) = (0, 180, 0)
 拖曳PrefabsVFXEnginesengines_enemy預製物件成為Enemy
Ship子物件
建立敵機 1/4
76
 在Enemy Ship加入Rigidbody元件
 取消勾選Use Gravity
 在Enemy Ship加入Shpere Collider元件
 勾選Is Trigger
 Center(X, Y, Z) = (0, 0, -0.3)
 Radius = 0.85
建立敵機 2/4
77
 在Enemy Ship加入DestroyByContact程式腳本
 拖曳PrefabsVFXExplosionsexplosion_enemy預製物件到
Explosion欄
 拖曳PrefabsVFXExplosionsexplosion_player預製物件到Player
Explosion欄
 Score Value = 20
 執行測試,射擊敵機會爆炸,得20分,但…
 敵機不會移動,也不會主動攻擊
建立敵機 4/4
78
 Ctrl-D複製Materialsfx_bolt_orange,更名為fx_bolt_cyan
 Particle Texture = fx_lazer_cyan_dff
製作敵機雷射武器 1/4
79
 在Enemy Ship下新增空子物件,更名為Shot Spawn
 Position(X, Y, Z) = (0, 0, -0.5)
 Rotation(X, Y, Z) = (0, 180, 0)
 拖曳PrefabsBolt成為Shot Spawn子物件,更名為Bolt Enemy
 重設Bolt EnemyVFX之Materials = fx_bolt_cyan
製作敵機雷射武器 2/4
80
 在Bolt Enemy加入DestroyByContact程式腳本
 修改DestroyByContact程式腳本
void OnTriggerEnter(Collider other) {
if (other.CompareTag ("Boundary") || other.CompareTag ("Enemy")) {
return;
}
if (explosion != null)
Instantiate(explosion, transform.position, transform.rotation);
...
}
製作敵機雷射武器 3/4
81
 拖曳PrefabsVFXExplosionsexplosion_player到Destroy By
Contact之Player Explosion欄
 設定Bolt Enemy之Tag屬性值為"Enemy"
 拖曳Bolt Enemy到Prefabs資料夾做成預製物件
 刪除Hierarchy窗格中Shot Spawn之Bolt Enemy子物件
製作敵機雷射武器 4/4
82
 拖曳Audioweapon_enemy到Enemy Ship
 取消勾選Play on Awake
 在Enemy Ship加入WeaponController程式腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponController : MonoBehaviour {
[SerializeField]
private GameObject shot;
[SerializeField]
private Transform shotSpawn;
[SerializeField]
private float fireRate;
[SerializeField]
private float delay;
private AudioSource audioSource;
敵機雷射發射控制 1/3
83
void Start () {
audioSource = GetComponent<AudioSource> ();
InvokeRepeating ("Fire", delay, fireRate);
}
void Fire () {
Instantiate (shot, shotSpawn.position, shotSpawn.rotation);
audioSource.Play ();
}
}
敵機雷射發射控制 2/3
84
 設定Weapon Controller參數
 拖曳PrefabsBolt Enemy預製物件到Shot欄
 拖曳Enemy Ship之Shot Spawn子物件到Shot Spawn欄
 Fire Rate = 1.5
 執行測試,敵機自動發射雷射
敵機雷射發射控制 3/3
85
 在Enemy Ship加入Mover程式腳本
 Speed = -5
 執行測試,敵機如同隕石向下移動,但...
 敵機移動欠缺機動性
敵機移動
86
 在Enemy Ship新增EvasiveManeuver程式腳本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EvasiveManeuver : MonoBehaviour {
[SerializeField]
private float dodge;
[SerializeField]
private float smoothing;
[SerializeField]
private float tilt;
[SerializeField]
private Vector2 startWait;
[SerializeField]
private Vector2 maneuverTime;
[SerializeField]
private Vector2 maneuverWait;
[SerializeField]
private Boundary boundary;
敵機機動迴避 1/3
87
private float currentSpeed;
private float targetManeuver;
private Rigidbody rb;
void Start () {
rb = GetComponent <Rigidbody> ();
currentSpeed = rb.velocity.z;
StartCoroutine (Evade ());
}
IEnumerator Evade() {
yield return new WaitForSeconds (Random.Range (startWait.x, startWait.y));
while (true) {
targetManeuver =
Random.Range (1, dodge) * -Mathf.Sign (transform.position.x);
yield return new WaitForSeconds (
Random.Range (maneuverTime.x, maneuverTime.y));
targetManeuver = 0;
yield return new WaitForSeconds (
Random.Range (maneuverWait.x, maneuverWait.y));
}
}
敵機機動迴避 2/3
88
void FixedUpdate () {
float newManeuver = Mathf.MoveTowards (
rb.velocity.x,
targetManeuver,
Time.deltaTime * smoothing);
rb.velocity = new Vector3 (newManeuver, 0.0f, currentSpeed);
rb.position = new Vector3 (
Mathf.Clamp (rb.position.x, boundary.xMin, boundary.xMax),
0.0f,
Mathf.Clamp (rb.position.z, boundary.zMin, boundary.zMax));
rb.rotation = Quaternion.Euler (0.0f, 0.0f, rb.velocity.x * -tilt);
}
}
敵機機動迴避 3/3
89
 設定Evasive Maneuver屬性值
 Dodge = 5
 Smoothing = 7.5
 Tilt = 10
 startWait(X, Y) = (0.5, 1)
 Maneuver Time(X, Y) = (1, 2)
 Maneuver Wait(X, Y) = (1, 2)
 Boundary
 X Min = -6, X Max = 6
 Z Min = -20, Z Max = 20
敵機機動迴避 4/3
90
 執行測試,敵機會機動進行迴避移動
 拖曳Enemy Ship到Prefabs資料夾做成預製物件
 刪除Hierarchy窗格中的Enemy Ship
敵機機動迴避 5/3
91
 拖曳Enemy Ship預製物件到Game Controller之Hazards
 執行測試,會隨機產生隕石及敵機
更新遊戲控制
92

More Related Content

What's hot

The Ring programming language version 1.10 book - Part 58 of 212
The Ring programming language version 1.10 book - Part 58 of 212The Ring programming language version 1.10 book - Part 58 of 212
The Ring programming language version 1.10 book - Part 58 of 212Mahmoud Samir Fayed
 
Creating Games for Asha - platform
Creating Games for Asha - platformCreating Games for Asha - platform
Creating Games for Asha - platformJussi Pohjolainen
 
HoloLens Programming Tutorial: AirTap & Spatial Mapping
HoloLens Programming Tutorial: AirTap & Spatial MappingHoloLens Programming Tutorial: AirTap & Spatial Mapping
HoloLens Programming Tutorial: AirTap & Spatial MappingTakashi Yoshinaga
 
Fps tutorial 2
Fps tutorial 2Fps tutorial 2
Fps tutorial 2unityshare
 
Fps tutorial 1
Fps tutorial 1Fps tutorial 1
Fps tutorial 1unityshare
 
Silverlight as a Gaming Platform
Silverlight as a Gaming PlatformSilverlight as a Gaming Platform
Silverlight as a Gaming Platformgoodfriday
 
Game Project / Working with Unity
Game Project / Working with UnityGame Project / Working with Unity
Game Project / Working with UnityPetri Lankoski
 
The Ring programming language version 1.5.4 book - Part 48 of 185
The Ring programming language version 1.5.4 book - Part 48 of 185The Ring programming language version 1.5.4 book - Part 48 of 185
The Ring programming language version 1.5.4 book - Part 48 of 185Mahmoud Samir Fayed
 
libGDX: Simple Frame Animation
libGDX: Simple Frame AnimationlibGDX: Simple Frame Animation
libGDX: Simple Frame AnimationJussi Pohjolainen
 
A split screen-viable UI event system - Unite Copenhagen 2019
A split screen-viable UI event system - Unite Copenhagen 2019A split screen-viable UI event system - Unite Copenhagen 2019
A split screen-viable UI event system - Unite Copenhagen 2019Unity Technologies
 
Unite2015 probelight English version
Unite2015 probelight English versionUnite2015 probelight English version
Unite2015 probelight English versionSangYun Yi
 
Academy PRO: Unity 3D. Environment
Academy PRO: Unity 3D. EnvironmentAcademy PRO: Unity 3D. Environment
Academy PRO: Unity 3D. EnvironmentBinary Studio
 

What's hot (20)

The Ring programming language version 1.10 book - Part 58 of 212
The Ring programming language version 1.10 book - Part 58 of 212The Ring programming language version 1.10 book - Part 58 of 212
The Ring programming language version 1.10 book - Part 58 of 212
 
libGDX: Tiled Maps
libGDX: Tiled MapslibGDX: Tiled Maps
libGDX: Tiled Maps
 
libGDX: User Input
libGDX: User InputlibGDX: User Input
libGDX: User Input
 
Box2D and libGDX
Box2D and libGDXBox2D and libGDX
Box2D and libGDX
 
libGDX: Scene2D
libGDX: Scene2DlibGDX: Scene2D
libGDX: Scene2D
 
Creating Games for Asha - platform
Creating Games for Asha - platformCreating Games for Asha - platform
Creating Games for Asha - platform
 
HoloLens Programming Tutorial: AirTap & Spatial Mapping
HoloLens Programming Tutorial: AirTap & Spatial MappingHoloLens Programming Tutorial: AirTap & Spatial Mapping
HoloLens Programming Tutorial: AirTap & Spatial Mapping
 
Fps tutorial 2
Fps tutorial 2Fps tutorial 2
Fps tutorial 2
 
Fps tutorial 1
Fps tutorial 1Fps tutorial 1
Fps tutorial 1
 
Silverlight as a Gaming Platform
Silverlight as a Gaming PlatformSilverlight as a Gaming Platform
Silverlight as a Gaming Platform
 
unity basics
unity basicsunity basics
unity basics
 
Game Project / Working with Unity
Game Project / Working with UnityGame Project / Working with Unity
Game Project / Working with Unity
 
Programmers guide
Programmers guideProgrammers guide
Programmers guide
 
The Ring programming language version 1.5.4 book - Part 48 of 185
The Ring programming language version 1.5.4 book - Part 48 of 185The Ring programming language version 1.5.4 book - Part 48 of 185
The Ring programming language version 1.5.4 book - Part 48 of 185
 
libGDX: Simple Frame Animation
libGDX: Simple Frame AnimationlibGDX: Simple Frame Animation
libGDX: Simple Frame Animation
 
A split screen-viable UI event system - Unite Copenhagen 2019
A split screen-viable UI event system - Unite Copenhagen 2019A split screen-viable UI event system - Unite Copenhagen 2019
A split screen-viable UI event system - Unite Copenhagen 2019
 
7java Events
7java Events7java Events
7java Events
 
Unite2015 probelight English version
Unite2015 probelight English versionUnite2015 probelight English version
Unite2015 probelight English version
 
Academy PRO: Unity 3D. Environment
Academy PRO: Unity 3D. EnvironmentAcademy PRO: Unity 3D. Environment
Academy PRO: Unity 3D. Environment
 
Gaming Process
Gaming ProcessGaming Process
Gaming Process
 

Similar to Unity 13 space shooter game

Unity遊戲程式設計 - 2D platformer game
Unity遊戲程式設計 - 2D platformer gameUnity遊戲程式設計 - 2D platformer game
Unity遊戲程式設計 - 2D platformer game吳錫修 (ShyiShiou Wu)
 
Building your first game in Unity 3d by Sarah Sexton
Building your first game in Unity 3d  by Sarah SextonBuilding your first game in Unity 3d  by Sarah Sexton
Building your first game in Unity 3d by Sarah SextonBeMyApp
 
Introduction to Unity3D and Building your First Game
Introduction to Unity3D and Building your First GameIntroduction to Unity3D and Building your First Game
Introduction to Unity3D and Building your First GameSarah Sexton
 
Write Java FX code for this pseudocode of the void initilizaHistoryL.pdf
Write Java FX code for this pseudocode of the void initilizaHistoryL.pdfWrite Java FX code for this pseudocode of the void initilizaHistoryL.pdf
Write Java FX code for this pseudocode of the void initilizaHistoryL.pdfsales98
 
Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)Korhan Bircan
 
School For Games 2015 - Unity Engine Basics
School For Games 2015 - Unity Engine BasicsSchool For Games 2015 - Unity Engine Basics
School For Games 2015 - Unity Engine BasicsNick Pruehs
 
Design pattern - part 3
Design pattern - part 3Design pattern - part 3
Design pattern - part 3Jieyi Wu
 
i need a taking turn method for a player vs computer battleship game.pdf
i need a taking turn method for a player vs computer battleship game.pdfi need a taking turn method for a player vs computer battleship game.pdf
i need a taking turn method for a player vs computer battleship game.pdfpetercoiffeur18
 
Get Into Sprite Kit
Get Into Sprite KitGet Into Sprite Kit
Get Into Sprite Kitwaynehartman
 
Game development with Cocos2d
Game development with Cocos2dGame development with Cocos2d
Game development with Cocos2dVinsol
 
Intro to Game Programming
Intro to Game ProgrammingIntro to Game Programming
Intro to Game ProgrammingRichard Jones
 
ARTDM 170, Week 11: User Interaction
ARTDM 170, Week 11: User InteractionARTDM 170, Week 11: User Interaction
ARTDM 170, Week 11: User InteractionGilbert Guerrero
 
Converting Scene Data to DOTS – Unite Copenhagen 2019
Converting Scene Data to DOTS – Unite Copenhagen 2019Converting Scene Data to DOTS – Unite Copenhagen 2019
Converting Scene Data to DOTS – Unite Copenhagen 2019Unity Technologies
 

Similar to Unity 13 space shooter game (20)

Unity遊戲程式設計 - 2D platformer game
Unity遊戲程式設計 - 2D platformer gameUnity遊戲程式設計 - 2D platformer game
Unity遊戲程式設計 - 2D platformer game
 
Building your first game in Unity 3d by Sarah Sexton
Building your first game in Unity 3d  by Sarah SextonBuilding your first game in Unity 3d  by Sarah Sexton
Building your first game in Unity 3d by Sarah Sexton
 
Introduction to Unity3D and Building your First Game
Introduction to Unity3D and Building your First GameIntroduction to Unity3D and Building your First Game
Introduction to Unity3D and Building your First Game
 
Unity programming 1
Unity programming 1Unity programming 1
Unity programming 1
 
Unity workshop
Unity workshopUnity workshop
Unity workshop
 
Write Java FX code for this pseudocode of the void initilizaHistoryL.pdf
Write Java FX code for this pseudocode of the void initilizaHistoryL.pdfWrite Java FX code for this pseudocode of the void initilizaHistoryL.pdf
Write Java FX code for this pseudocode of the void initilizaHistoryL.pdf
 
Tdd in unity
Tdd in unityTdd in unity
Tdd in unity
 
Unity3 d devfest-2014
Unity3 d devfest-2014Unity3 d devfest-2014
Unity3 d devfest-2014
 
Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)
 
School For Games 2015 - Unity Engine Basics
School For Games 2015 - Unity Engine BasicsSchool For Games 2015 - Unity Engine Basics
School For Games 2015 - Unity Engine Basics
 
Design pattern - part 3
Design pattern - part 3Design pattern - part 3
Design pattern - part 3
 
Shootting Game
Shootting GameShootting Game
Shootting Game
 
i need a taking turn method for a player vs computer battleship game.pdf
i need a taking turn method for a player vs computer battleship game.pdfi need a taking turn method for a player vs computer battleship game.pdf
i need a taking turn method for a player vs computer battleship game.pdf
 
Get Into Sprite Kit
Get Into Sprite KitGet Into Sprite Kit
Get Into Sprite Kit
 
Game development with Cocos2d
Game development with Cocos2dGame development with Cocos2d
Game development with Cocos2d
 
Intro to Game Programming
Intro to Game ProgrammingIntro to Game Programming
Intro to Game Programming
 
ARTDM 170, Week 11: User Interaction
ARTDM 170, Week 11: User InteractionARTDM 170, Week 11: User Interaction
ARTDM 170, Week 11: User Interaction
 
Converting Scene Data to DOTS – Unite Copenhagen 2019
Converting Scene Data to DOTS – Unite Copenhagen 2019Converting Scene Data to DOTS – Unite Copenhagen 2019
Converting Scene Data to DOTS – Unite Copenhagen 2019
 
Basics cocos2d
Basics cocos2dBasics cocos2d
Basics cocos2d
 
Game dev 101 part 3
Game dev 101 part 3Game dev 101 part 3
Game dev 101 part 3
 

More from 吳錫修 (ShyiShiou Wu)

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

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移動與碰撞處理II
Unity遊戲程式設計 - 2D移動與碰撞處理IIUnity遊戲程式設計 - 2D移動與碰撞處理II
Unity遊戲程式設計 - 2D移動與碰撞處理II
 
Unity遊戲程式設計 - 2D運動與碰撞處理I
Unity遊戲程式設計 - 2D運動與碰撞處理IUnity遊戲程式設計 - 2D運動與碰撞處理I
Unity遊戲程式設計 - 2D運動與碰撞處理I
 
Python與Ardinio整合應用
Python與Ardinio整合應用Python與Ardinio整合應用
Python與Ardinio整合應用
 
mBlock積木式設計程式
mBlock積木式設計程式mBlock積木式設計程式
mBlock積木式設計程式
 
Arduino程式除錯
Arduino程式除錯Arduino程式除錯
Arduino程式除錯
 
Unity遊戲設計- 2D動畫製作及應用
Unity遊戲設計-  2D動畫製作及應用Unity遊戲設計-  2D動畫製作及應用
Unity遊戲設計- 2D動畫製作及應用
 

Recently uploaded

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 

Recently uploaded (20)

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 

Unity 13 space shooter game

  • 1. Space shooter遊戲 Revised on March 28, 2019 ⼀款俯視⾓太空射擊遊戲,學習場景光 照設定、戰機移動控制、射擊控制、隕 石群生成、敵動迴避移動、爆炸效果、 背景音樂
  • 4.  新增3D專案  選單命令File> New Project…  專案名稱Space shooter  儲存預設場景  Main.unity  滙入Space Shooter tutorial.unitypackage  選單命令Assets> Import Package> Custom Package… 專案設定 1/2 4
  • 5.  設定場景大小  選單命令File> Build Settings…  點擊Player Settings...按鈕  Fullscreen Mode = Windowed  Default Screen Width: 600  Default Screen Height: 900 專案設定 2/2 5
  • 6.  拖曳Modelsvehicle_playerShip到Hiearchy面板  重新命名:Player  重置Transform參數值  設定Player戰機為剛體物件  選單命令Component> Physics> Rigidbody  取消勾選Use Gravity以符合外太空無重力環境 建立玩家戰機物件 1/2 6
  • 7.  在Player戰機上加上網格碰撞器  選單命令Component> Physics> Mesh Collider  勾選Convex  勾選Is Trigger  簡化網格,拖曳Modelsplayer_ship_collider到Mesh欄  設定Player戰機引擎噴射效果  拖曳PrefabsVFXEnginesengines_player預製物件成為Player子物件 建立玩家戰機物件 2/2 7
  • 8.  重置Main Camera之Transform參數值  使Main Camera朝下  Rotation(X, Y, Z) = (90, 0, 0)  使Main Camera移動到Player戰機上方  Position(X, Y, Z) = (0, 10, 0)  將Main Camera投影方式設定為正交投影  Projection = Orthographic  Size = 10 攝影機設定 1/2 8
  • 9.  調整Main Camera之Z軸位置來變更Player戰機初始顯示位置  Position(X, Y, Z) = (0, 10, 5)  設定Main Camera鏡頭底色  Clear Flags = Solid Color  Background = black 攝影機設定 2/2 9
  • 10.  刪除Directional Light  取消環境光  選單命令Window> Rendering> Lighting Settings開啟Lighting面板  Skybox Material = none  Ambient Color = black 光照設定 1/3 10
  • 11.  建立主光源  選單命令GameObject> Light> Directional Light,更名為Main Light  重置Transform  調整光線⾓度,Rotation(X, Y, Z) = (20, -115, 0)  建立補光  選取Main Light,Ctrl-D複製,更名為Fill Light  重置Transform  調整補光強度,Intensity = 0.5  調整補光⾓度,Rotation(X, Y, Z) = (5, 125, 0)  調整補光顏色,Color(R, G, B) = (128, 192, 192) 光照設定 2/3 11
  • 12.  建立邊緣反射光  複製Fill Light,更名為Rim Light  重置Transform  調整邊緣反射光顏色,Color = white  調整邊緣反射光⾓度,Rotation(X, Y, Z) = (-15, 65, 0)  調整邊緣反射光強度,Intensity = 0.25  管理光源物件  選單命令GameObject> Create Empty,更名為Lighting  重置Transform  Position(X, Y, Z) = (0, 100, 0)  將Main Light、Fill Light及Rim Light拖曳到Lighting下做為子物件 光照設定 3/3 12
  • 13.  選單命令GameObject> 3D Object> Quad,新增Quad做為背景物件, 更名為Background  重置Transform屬性值  使Background物件面向Main Camera  Rotation(X, Y, Z) = (90, 0, 0)  調整Background物件大小,使其可以填滿整個遊戲畫面  Scale(X, Y, Z) = (15, 30, 0)  設定背景材質  拖曳Texturestile_nebula_green_diff到Background上 設定遊戲背景 1/2 13
  • 14.  移除Mesh Collider  將材質Shader欄變更為Unlit/Texture  調整Background物件位置到Player戰機下方  Position(X, Y, Z) = (0, -10, 0) 設定遊戲背景 2/2 14
  • 15.  在Player物件加上PlayerController程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { void FixedUpdate () { Rigidbody rigidBody = GetComponent<Rigidbody> (); float moveHorizontal = Input.GetAxis ("Horizontal"); float moveVertical = Input.GetAxis ("Vertical"); Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical); rigidBody.velocity = movement; } } 玩家戰機移動控制 1/5 15
  • 16.  執行測試,可使用方向鍵移動Player戰機,但是…  移動速度很慢  在PlayerController程式腳本加入速度參數 public class PlayerController : MonoBehaviour { public float speed; void FixedUpdate () { Rigidbody rigidBody = GetComponent<Rigidbody> (); float moveHorizontal = Input.GetAxis ("Horizontal"); float moveVertical = Input.GetAxis ("Vertical"); Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical); rigidBody.velocity = movement * speed; } } 玩家戰機移動控制 2/5 16
  • 17.  將PlayerController之Speed欄設定為10  執行測試,Player戰機移動速度變快了,但是…  Player戰機會跑出螢幕  修改PlayerController程式腳本,限制Player戰機移動範圍 using System.Collections; using System.Collections.Generic; using UnityEngine; [System.Serializable] public class Boundary { public float xMin, xMax, zMin, zMax; } 玩家戰機移動控制 3/5 17
  • 18. public class PlayerController : MonoBehaviour { public float speed; public float tilt; public Boundary boundary; void FixedUpdate () { Rigidbody rigidBody = GetComponent<Rigidbody> (); float moveHorizontal = Input.GetAxis ("Horizontal"); float moveVertical = Input.GetAxis ("Vertical"); Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical); rigidBody.velocity = movement * speed; rigidBody.position = new Vector3 ( Mathf.Clamp (rigidBody.position.x, boundary.xMin, boundary.xMax), 0.0f, Mathf.Clamp (rigidBody.position.z, boundary.zMin, boundary.zMax)); rigidBody.rotation = Quaternion.Euler ( 0.0f, 0.0f, rigidBody.velocity.x * -tilt); } } 玩家戰機移動控制 4/5 18
  • 19.  設定Player戰機之Boundry值  調整Player戰機Position之X值,測試最左及最右位置值  調整Player戰機Position之Z值,測試上方及下方位置值  執行測試,Player戰機不會跑出場景範圍了 玩家戰機移動控制 5/5 19
  • 20.  選單命令GameObject> Create Empty,更名為Bolt  重置Transform屬性值  選單命令GameObject> 3D Object> Quad,更名為VFX  重置Transform屬性值  使VFX面向Main Camera  Rotation(X, Y, Z) = (90, 0, 0)  移除Mesh Collider元件  拖曳VFX成為Bolt子物件 建立玩家戰機子彈 1/5 20
  • 21.  選單命令Assets> Create> Material新增材質球,更名為 fx_bolt_orange  Shader = Mobile/Particles/Additive  Particle Texture = fx_lazer_orange_dff  拖曳fx_bolt_orange材質到VFX物件上 建立玩家戰機子彈 2/5 21
  • 22.  Bolt物件加上Rigidbody元件  取消勾選Use Gravity  Bolt物件加上Capsule Collider元件  Direction = Z-Axis  Radius = 0.03,Height = 0.5  勾選Is Trigger 建立玩家戰機子彈 3/5 22
  • 23.  Bolt物件加上Mover程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class Mover : MonoBehaviour { [SerializeField] private float speed; // Use this for initialization void Start () { GetComponent<Rigidbody>().velocity = transform.forward * speed; } } 建立玩家戰機子彈 4/5 23
  • 24.  將Bolt物件拖到Prefabs資料夾做為預製物件  Speed = 20  刪除場景中的Bolt物件  執行測試,將Bolt預製物件拖曳到Hierarchy面板,檢視Game視窗, 子彈是否向前飛去 建立玩家戰機子彈 5/5 24
  • 25.  選單命令GameObject> Create Empty,更名為Shot Spawn  重置Transform  拖曳Shot Spawn成為Player子物件  調整Shot Spawn位置到戰機之前端,Position(X, Y, Z) = (0, 0, 1) 玩家戰機子彈發射控制 1/3 25
  • 26.  編輯Player物件之PlayerController程式腳本 public class PlayerController : MonoBehaviour { public float speed; public float tilt; public Player_Boundary boundary; public GameObject shot; public Transform shotSpawn; public float fireRate; private float nextFire; void Update () { if (Input.GetButton("Fire1") && Time.time > nextFire) { nextFire = Time.time + fireRate; Instantiate(shot, shotSpawn.position, shotSpawn.rotation); } } ... } 玩家戰機子彈發射控制 2/3 26
  • 27.  拖曳Bolt預製物件到Player Controller之Shot欄  拖曳Shot Spawn物件到Player Controller之Shot Spawn欄  將Player Controller之Fire Rate欄值設為0.25  執行測試,按下滑鼠左鍵可發射子彈,但是...  檢視Hierarchy面板,子彈物件會不斷生成,但不會自動銷毀 玩家戰機子彈發射控制 3/3 27
  • 28.  選單命令GameObject> 3D Object> Cube,更名為Boundary  重置Transform屬性值  勾選Box Collider之Is Trigger  使Boundary物件置中顯示  Position (X, Y, Z) = (0, 0, 5) 參照Main Camera之Z座標設定  使Boundary物件涵蓋整個遊戲場景  Scale (X, Y, Z) = (15, 1, 20)  移除Mesh Renderer元件  移除Mesh Filter元件 設定玩家戰機子彈邊界 1/3 28
  • 30.  Boundary物件加上DestroyByBoundry程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class DestroyByBoundary : MonoBehaviour { void OnTriggerExit(Collider other) { Destroy(other.gameObject); } }  測試程式,檢視Hirarchy面板,子彈物件碰到Bundary後會自動銷毀 設定玩家戰機子彈邊界 3/3 30
  • 31.  選單命令GameObject> Create Empty,更名為Asteroid  Position(X, Y, Z) = (0, 0, 8)  拖曳Models/prop_asteroid_01成為Asteroid子物件  重置prop_asteroid_01物件Transform設定  在Asteroid物件加上Rigidbody元件  取消勾選Use Gravity  在Asteroid物件加上Capsule Collider元件  調整Radius及Height使其符合物件大小  Direction = Y-Axis  Radius = 0.486  Height = 1.524 建立隕石 1/4 31
  • 32.  Asteroid物件加上RandomRotator程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class RandomRotator : MonoBehaviour { [SerializeField] private float tumble; void Start () { GetComponent<Rigidbody>().angularVelocity = Random.insideUnitSphere*tumble; } }  Asteroid物件之Tumble設定為5  執行測試,隕石會自主轉動,但是...  子彈會直接穿過隕石 建立隕石 2/4 32
  • 33.  Asteroid物件加上DestroyByContact程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class DestroyByContact : MonoBehaviour { void OnTriggerEnter(Collider other) { if (other.CompareTag ("Boundary")) { return; } Destroy(other.gameObject); Destroy(gameObject); } } 建立隕石 3/4 33
  • 34.  將Boundary物件之Tag設定為Boundary  執行測試  子彈碰到隕石時,子彈與隕石都會自動銷毀 建立隕石 4/4 34
  • 35.  編輯DestroyByContact程式腳本 public class DestroyByContact : MonoBehaviour { [SerializeField] private GameObject explosion; void OnTriggerEnter(Collider other) { if (other.CompareTag ("Boundary")) { return; } Instantiate(explosion, transform.position, transform.rotation); Destroy(other.gameObject); Destroy(gameObject); } }  拖曳PrefabsVFXExplosionsexplosion_asteroid預製物件到 Explosion欄 爆破效果 1/4 35
  • 37.  編輯DestroyByContact程式腳本 public class DestroyByContact : MonoBehaviour { [SerializeField] private GameObject explosion; [SerializeField] private GameObject playerExplosion; void OnTriggerEnter(Collider other) { ... Instantiate(explosion, transform.position, transform.rotation); if (other.CompareTag ("Player")) { Instantiate(playerExplosion, other.transform.position, other.transform.rotation); } Destroy(other.gameObject); Destroy(gameObject); }  拖曳PrefabsVFXExplosionsexplosion_player預製物件到 Player Explosion欄 爆破效果 3/4 37
  • 38.  執行測試,戰機撞到隕石時,隕石與戰機都會產生爆破效果後銷毀  Asteroid物件加上Mover程式腳本  設定Speed為-5  執行測試,隕石會自動向下墜落 爆破效果 4/4 38  將Asteroid物件拖曳到Prefabs資料夾做 成預製物件  刪除場景上的Asteroid物件
  • 39.  選單命令GameObject> Create Empty,更名為Game Controller  重置Transform  設定Tag為GameController 遊戲控制 1/3 39
  • 40.  Game Controller物件加上GameController程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameController : MonoBehaviour { [SerializeField] private GameObject hazard; [SerializeField] private Vector3 spawnValues; void Start () { SpawnWaves (); } void SpawnWaves () { Vector3 spawnPosition = new Vector3 ( Random.Range (-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z); Quaternion spawnRotation = Quaternion.identity; Instantiate (hazard, spawnPosition, spawnRotation); } } 遊戲控制 2/3 40
  • 41.  拖曳Asteroid預製物件到Hazard欄  設定SpawnValues(X, Y, Z) = (6, 0, 16)  執行測試,每次執行隕石會由不同位置墜落 遊戲控制 3/3 41
  • 42.  編輯GameController程式腳本 public class GameController : MonoBehaviour { [SerializeField] private GameObject hazard; [SerializeField] private Vector3 spawnValues; [SerializeField] private int hazardCount; [SerializeField] private float spawnWait; [SerializeField] private float startWait; [SerializeField] private float waveWait; void Start () { StartCoroutine (SpawnWaves ()); } 設定隕石群 1/4 42
  • 43. IEnumerator SpawnWaves () { yield return new WaitForSeconds (startWait); while (true) { for (int i = 0; i < hazardCount; i++) { Vector3 spawnPosition = new Vector3 ( Random.Range (-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z); Quaternion spawnRotation = Quaternion.identity; Instantiate (hazard, spawnPosition, spawnRotation); yield return new WaitForSeconds (spawnWait); } yield return new WaitForSeconds (waveWait); } } } 設定隕石群 2/4 43
  • 44.  Game Controller參數  Hazard Count = 10  Spawn Wait = 0.4  Start Wait = 1  Wave Wait = 4  執行測試,隕石會定時自動生成,但是...  擊破隕石時生成的爆破效果物件不會自動銷毀 設定隕石群 3/4 44
  • 45.  建立DestroyByTime程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class DestroyByTime : MonoBehaviour { [SerializeField] private float lifetime; void Start () { Destroy (gameObject, lifetime); } } 設定隕石群 3/4 45
  • 46.  在explosion_asteroid預製物件及explosion_player預製物件加 入DestroyByTime程式腳本  Lifetime設定為2  執行測試,隕石會定時自動生成,爆破特效物件也會在2秒後自動銷毀 設定隕石群 4/4 46
  • 47.  在explosion_asteroid預製物件加上Audio Source元件  拖曳Audioexplosion_asteroid到explosion_asteroid預製物件之 AudioClip欄  勾選Play On Awake 加入音效 1/4 47
  • 48.  在explosion_player預製物件加上Audio Source元件  拖曳Audioexplosion_player到AudioClip欄  勾選Play On Awake 加入音效 2/4 48
  • 49.  在Player物件加上Audio Source元件  拖曳Audioweapon_player到AudioClip欄  取消勾選Play On Awake  Volume設為0.5 加入音效 3/4 49
  • 50.  編輯Player物件之Player Controller程式腳本 void Update () { if (Input.GetButton("Fire1") && Time.time > nextFire) { nextFire = Time.time + fireRate; Instantiate(shot, shotSpawn.position, shotSpawn.rotation); GetComponent<AudioSource>().Play(); } } 加入音效 4/4 50
  • 51.  在GameController物件加上Audio Source元件  拖曳Audiomusic_background到GameController物件之AudioClip欄  勾選Play On Awake  勾選Loop  Volume設為0.5 加入背景音樂 51
  • 52.  選單命令GameObject> UI> Text,更名為Score Text  重置Rect Transform  Color = white  Anchor Presets = left, top (同時按Shift + Alt) 計算及顯示分數 1/6 52
  • 53.  編輯GameController程式腳本 using UnityEngine.UI; public class GameController : MonoBehaviour { ... public float waveWait; [SerializeField] private Text scoreText; private int score; void Start () { score = 0; UpdateScore (); StartCoroutine (SpawnWaves ()); } 計算及顯示分數 2/6 53
  • 54. public void AddScore (int newScoreValue) { score += newScoreValue; UpdateScore (); } void UpdateScore () { scoreText.text = "Score: " + score; } ... } 計算及顯示分數 3/6 54
  • 55.  拖曳Score Text物件到Game Controller物件之Score Text欄 計算及顯示分數 4/6 55
  • 56.  編輯DestroyByContact程式腳本 public class DestroyByContact : MonoBehaviour { ... private GameObject playerExplosion; [SerializeField] private int scoreValue; private GameObject gameController; void Start () { gameController = GameObject.Find ("Game Controller"); } void OnTriggerEnter(Collider other) { ... Destroy(other.gameObject); Destroy(gameObject); gameController.GetComponent<GameController> ().AddScore (scoreValue); } } 計算及顯示分數 2/6 56
  • 57.  將Asteroid預製物件之Score Value設定為10  執行測試,每擊破⼀個隕石增加10分 計算及顯示分數 3/6 57
  • 58.  選單命令GameObject> UI> Text,更名為Restart Text  重置Rect Transform  Width = 200  Anchor Presets = right, top (同時按Shift + Alt)  Color = white  Paragraph Alignment = left 結束遊戲作業 1/7 58
  • 59.  選單命令GameObject> UI> Text,更名為Gameover Text  重置Rect Transform  Anchor Presets = middle, center  Font Size = 18  Paragraph Alignment = center  Color = yellow 結束遊戲作業 2/7 59
  • 60.  編輯GameController程式腳本 using UnityEngine.SceneManagement; public class GameController : MonoBehaviour { ... private int score; [SerializeField] private Text restartText; [SerializeField] private Text gameOverText; private bool gameOver; private bool restart; void Start () { gameOver = false; restart = false; restartText.text = ""; gameOverText.text = ""; score = 0; ... } 結束遊戲作業 3/7 60
  • 61. IEnumerator SpawnWaves () { ... yield return new WaitForSeconds (waveWait); if (gameOver) { restartText.text = "Press 'R' for Restart"; restart = true; break; } } } 結束遊戲作業 4/7 61
  • 62. void Update () { if (restart) { if (Input.GetKeyDown (KeyCode.R)) { SceneManager.LoadScene ("Main"); } } } public void GameOver () { gameOverText.text = "Game Over!"; gameOver = true; } } 結束遊戲作業 5/7 62
  • 63.  編輯DestroyByContact程式腳本 public class DestroyByContact : MonoBehaviour { ... void OnTriggerEnter(Collider other) { ... if (other.tag == "Player") { Instantiate(playerExplosion, other.transform.position, other.transform.rotation); gameController.GetComponent<GameController> ().GameOver(); } ... } } 結束遊戲作業 6/7 63
  • 64.  拖曳Restart Text物件到Game Controller物件之Restart Text欄  拖曳Gameover Text物件到Game Controller物件之Game Over Text欄  執行測試,玩家戰機會顯示Game over!,等下⼀波隕石群時顯示 Press 'R' for Restart,按下R鍵即可重玩 結束遊戲作業 7/7 64
  • 65.  將PrefabsAsteroid預製物件更名為Asteroid01  設定Asteroid01之Tag屬性值為"Enemy"  拖曳PrefabsAsteroid01預製物件到場景上  Ctrl-D複製2份,分別更名為Asteroid02及Asteroid03  拖曳Asteroid02及Asteroid03到Prefabs資料夾做成預製物件  刪除場景上的Asteroid01、Asteroid02及Asteroid03 建立不同隕石 1/5 65
  • 66.  開啟Asteroid02預製物件  拖曳Modelsprop_asteroid_02成為Asteroid02子物件  刪除Asteroid02prop_asteroid_01子物件  Capsule Collider  Radius = 0.45  Height = 1.37  Direction = X-Axis 建立不同隕石 2/5 66
  • 67.  開啟Asteroid03預製物件  拖曳Modelsprop_asteroid_03成為Asteroid03子物件  刪除Asteroid03prop_asteroid_01子物件  Capsule Collider  Radius = 0.55  Height = 1.5  Direction = X-Axis 建立不同隕石 3/5 67
  • 68.  更新GameController程式腳本 public class GameController : MonoBehaviour { [SerializeField] private GameObject hazard; private GameObject[] hazards; ... IEnumerator SpawnWaves () { yield return new WaitForSeconds (startWait); while (true) { for (int i = 0; i < hazardCount; i++) { GameObject hazard = hazards[Random.Range (0, hazards.Length)]; ... } } } ... } 建立不同隕石 4/5 68
  • 71.  Ctrl-D複製Background  拖曳Background (1)成為Background子物件  調整Background (1)位置使它與Background串接  Position(X, Y, Z) = (0, -1, 0)  Rotation(X, Y, Z) = (0, 0, 0)  Scale(X, Y, Z) = (1, 1, 1) 捲動背景 1/4 71
  • 73.  在Background加入BGScroller程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class BGScroller : MonoBehaviour { [SerializeField] private float scrollSpeed; [SerializeField] private float tileSizeZ; private Vector3 startPosition; void Start() { startPosition = transform.position; } void Update() { float newPosition = Mathf.Repeat (Time.time * scrollSpeed, tileSizeZ); transform.position = startPosition + Vector3.forward * newPosition; } } 捲動背景 3/4 73
  • 74.  設定BG Scroller屬性值  Scroll Speed = -0.25  Tile Size Z = 30  執行測試,背景會緩慢向下捲動 捲動背景 4/4 74
  • 75.  在PrefabsVFXExplosionsexplosion_enemy預製物件加入 DestroyByTime程式腳本  Lifetime設定為2  在PrefabsVFXExplosionsexplosion_enemy預製物件加上 Audio Source元件  拖曳Audioexplosion_enemy到AudioClip欄  勾選Play On Awake 製作敵機爆炸特效 75
  • 76.  選單命令GameObject> Create Empty,更名為Enemy Ship  重置Transform屬性值  Position(X, Y, Z) = (0, 0, 9)  Tag = Enemy  拖曳Modelsvehicle_enemyShip成為Enemy Ship子物件  Rotation(X, Y, Z) = (0, 180, 0)  拖曳PrefabsVFXEnginesengines_enemy預製物件成為Enemy Ship子物件 建立敵機 1/4 76
  • 77.  在Enemy Ship加入Rigidbody元件  取消勾選Use Gravity  在Enemy Ship加入Shpere Collider元件  勾選Is Trigger  Center(X, Y, Z) = (0, 0, -0.3)  Radius = 0.85 建立敵機 2/4 77
  • 78.  在Enemy Ship加入DestroyByContact程式腳本  拖曳PrefabsVFXExplosionsexplosion_enemy預製物件到 Explosion欄  拖曳PrefabsVFXExplosionsexplosion_player預製物件到Player Explosion欄  Score Value = 20  執行測試,射擊敵機會爆炸,得20分,但…  敵機不會移動,也不會主動攻擊 建立敵機 4/4 78
  • 79.  Ctrl-D複製Materialsfx_bolt_orange,更名為fx_bolt_cyan  Particle Texture = fx_lazer_cyan_dff 製作敵機雷射武器 1/4 79
  • 80.  在Enemy Ship下新增空子物件,更名為Shot Spawn  Position(X, Y, Z) = (0, 0, -0.5)  Rotation(X, Y, Z) = (0, 180, 0)  拖曳PrefabsBolt成為Shot Spawn子物件,更名為Bolt Enemy  重設Bolt EnemyVFX之Materials = fx_bolt_cyan 製作敵機雷射武器 2/4 80
  • 81.  在Bolt Enemy加入DestroyByContact程式腳本  修改DestroyByContact程式腳本 void OnTriggerEnter(Collider other) { if (other.CompareTag ("Boundary") || other.CompareTag ("Enemy")) { return; } if (explosion != null) Instantiate(explosion, transform.position, transform.rotation); ... } 製作敵機雷射武器 3/4 81
  • 82.  拖曳PrefabsVFXExplosionsexplosion_player到Destroy By Contact之Player Explosion欄  設定Bolt Enemy之Tag屬性值為"Enemy"  拖曳Bolt Enemy到Prefabs資料夾做成預製物件  刪除Hierarchy窗格中Shot Spawn之Bolt Enemy子物件 製作敵機雷射武器 4/4 82
  • 83.  拖曳Audioweapon_enemy到Enemy Ship  取消勾選Play on Awake  在Enemy Ship加入WeaponController程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class WeaponController : MonoBehaviour { [SerializeField] private GameObject shot; [SerializeField] private Transform shotSpawn; [SerializeField] private float fireRate; [SerializeField] private float delay; private AudioSource audioSource; 敵機雷射發射控制 1/3 83
  • 84. void Start () { audioSource = GetComponent<AudioSource> (); InvokeRepeating ("Fire", delay, fireRate); } void Fire () { Instantiate (shot, shotSpawn.position, shotSpawn.rotation); audioSource.Play (); } } 敵機雷射發射控制 2/3 84
  • 85.  設定Weapon Controller參數  拖曳PrefabsBolt Enemy預製物件到Shot欄  拖曳Enemy Ship之Shot Spawn子物件到Shot Spawn欄  Fire Rate = 1.5  執行測試,敵機自動發射雷射 敵機雷射發射控制 3/3 85
  • 86.  在Enemy Ship加入Mover程式腳本  Speed = -5  執行測試,敵機如同隕石向下移動,但...  敵機移動欠缺機動性 敵機移動 86
  • 87.  在Enemy Ship新增EvasiveManeuver程式腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class EvasiveManeuver : MonoBehaviour { [SerializeField] private float dodge; [SerializeField] private float smoothing; [SerializeField] private float tilt; [SerializeField] private Vector2 startWait; [SerializeField] private Vector2 maneuverTime; [SerializeField] private Vector2 maneuverWait; [SerializeField] private Boundary boundary; 敵機機動迴避 1/3 87
  • 88. private float currentSpeed; private float targetManeuver; private Rigidbody rb; void Start () { rb = GetComponent <Rigidbody> (); currentSpeed = rb.velocity.z; StartCoroutine (Evade ()); } IEnumerator Evade() { yield return new WaitForSeconds (Random.Range (startWait.x, startWait.y)); while (true) { targetManeuver = Random.Range (1, dodge) * -Mathf.Sign (transform.position.x); yield return new WaitForSeconds ( Random.Range (maneuverTime.x, maneuverTime.y)); targetManeuver = 0; yield return new WaitForSeconds ( Random.Range (maneuverWait.x, maneuverWait.y)); } } 敵機機動迴避 2/3 88
  • 89. void FixedUpdate () { float newManeuver = Mathf.MoveTowards ( rb.velocity.x, targetManeuver, Time.deltaTime * smoothing); rb.velocity = new Vector3 (newManeuver, 0.0f, currentSpeed); rb.position = new Vector3 ( Mathf.Clamp (rb.position.x, boundary.xMin, boundary.xMax), 0.0f, Mathf.Clamp (rb.position.z, boundary.zMin, boundary.zMax)); rb.rotation = Quaternion.Euler (0.0f, 0.0f, rb.velocity.x * -tilt); } } 敵機機動迴避 3/3 89
  • 90.  設定Evasive Maneuver屬性值  Dodge = 5  Smoothing = 7.5  Tilt = 10  startWait(X, Y) = (0.5, 1)  Maneuver Time(X, Y) = (1, 2)  Maneuver Wait(X, Y) = (1, 2)  Boundary  X Min = -6, X Max = 6  Z Min = -20, Z Max = 20 敵機機動迴避 4/3 90
  • 91.  執行測試,敵機會機動進行迴避移動  拖曳Enemy Ship到Prefabs資料夾做成預製物件  刪除Hierarchy窗格中的Enemy Ship 敵機機動迴避 5/3 91
  • 92.  拖曳Enemy Ship預製物件到Game Controller之Hazards  執行測試,會隨機產生隕石及敵機 更新遊戲控制 92