iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0
Software Development

初心者限定!設計師帶你學 Unity 3D 遊戲程式設計系列 第 22

Day22 / Unity 可愛的 NewJeans 2D 遊戲 - 遊戲主流程控制

  • 分享至 

  • xImage
  •  

Day22

場景切換與地形變化

STEP 1

將開始畫面獨立成一個新的場景


複製一個 SuperNewJeans 場景,並重新命名為 SuperNewJeans-Home

開啟 SuperNewJeans-Home 場景,並刪除 Block 物件

將 Player 物件上的 Player Controller 腳本關閉

開啟 step1 UI 畫面,將 Player 移至畫面中間並放大,完成開始畫面的設計

01
02
03
04

STEP 2

將場景匯入 Build Settings 中


於視窗頂端工具列中 點擊 File 選擇 Build Settings 開啟 Build Settings 視窗

將 SuperNewJeans-Home 及 SuperNewJeans 兩場景拖曳至 Scenes In Build 欄位中

05
06

💡古古的小提醒:
在 Scenes In Build 欄位中,編號為 0 的場景,代表是遊戲開始時預設開啟的場景。
因此在匯入場景時,要記得確保 SuperNewJeans-Home 的編號為 0 喔!

STEP 3

設定遊戲進行的場景切換


開啟 GameManager 腳本,將原本的程式碼修改為以下版本並存檔

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; // 新增場景管理的Library

public class GameManager : MonoBehaviour
{
		public GameObject player;
		public int score = 0;
		public int hp = 3;
		public int cookiePower = 0;
		public int highScore = 0;
		public int rabbitPoint = 0;
		public List<GameObject> steps = new List<GameObject>();

		void Start()
		{
				score = 0;
				hp = 3;
				cookiePower = 0;
		}
		
		void Update()
		{
				if(Input.GetKeyDown(KeyCode.Z))
				{
						GameOver();
				}
		}
		
		public void updateHP(int amount)
		{
				hp = hp + amount;
		
				if(hp >= 3)
				{
						hp = 3;
				}
		
				if(hp <= 0)
				{
						Debug.Log("遊戲結束");
				}
		}
		
		public void updateCookiePower()
		{
				cookiePower = cookiePower + 10;
		}
		
		public void updateRabbitPoint()
		{
				rabbitPoint = rabbitPoint + 1;
		}
		
		
		public void ChangeStepUI(int step)
		{
				for (int i = 0; i < 3; i++)
				{
						steps[i].SetActive(false);
				}
		
				steps[step].SetActive(true);
		}
		
		public void GameStart()
		{
				// 開始遊戲,切換到主遊戲場景
				SceneManager.LoadScene("SuperNewJeans");
		}
		
		public void Exit()
		{
				// 離開遊戲,切換到遊戲首頁場景
				SceneManager.LoadScene("SuperNewJeans-Home");
		}
		
		public void GameOver()
		{
				ChangeStepUI(2);
		}
		
		public void Restart()
		{
				// 重新開始,切換到遊戲首頁場景
				SceneManager.LoadScene("SuperNewJeans-Home");
		}
}

07

示意圖為 GameManager 腳本上半部修改後之程式碼

08

示意圖為 GameManager 腳本下半部修改後之程式碼

STEP 4

設定 UI 畫面中遊戲數值的變化


回到 SuperNewJeans 場景 開啟 step2 UI 畫面

開啟 GameManager 腳本,將原本的程式碼修改為以下版本並存檔

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI; // 新增UI的Library
using TMPro; // 新增TextMeshPro的Library

public class GameManager : MonoBehaviour
{
		public GameObject player;
		public int score = 0;
		public float score_f = 0;
		public int hp = 3;
		public int cookiePower = 0;
		public int highScore = 0;
		public int rabbitPoint = 0;
		public List<GameObject> steps = new List<GameObject>();
		
		// UI
		public TextMeshProUGUI hpUI;
		public TextMeshProUGUI rabbitUI;
		public TextMeshProUGUI scoreUI;
		public TextMeshProUGUI cookieUI;

		void Start()
		{
				score = 0;
				hp = 3;
				cookiePower = 0;
		}
		
		void Update()
		{
				// 設定Score的計算方式
				score_f = score_f + Time.deltaTime;
				score = Mathf.RoundToInt(score_f);
				
				// 設定UI畫面中各項數值與文字的變化
				hpUI.text = " HP: " + hp;
				rabbitUI.text = " rabbits: " + rabbitPoint;
				scoreUI.text = " Score: " + score;
				cookieUI.text = " cookie power: " + cookiePower;

				if(Input.GetKeyDown(KeyCode.Z))
				{
						GameOver();
				}
		}
		
		public void updateHP(int amount)
		{
				hp = hp + amount;

				if(hp >= 3)
				{
						hp = 3;
				}
		
				if(hp <= 0)
				{
						Debug.Log("遊戲結束");
				}
		}
		
		public void updateCookiePower()
		{
				cookiePower = cookiePower + 10;
		}
		
		public void updateRabbitPoint()
		{
				rabbitPoint = rabbitPoint + 1;
		}
		
		
		public void ChangeStepUI(int step)
		{
				for (int i = 0; i < 3; i++)
				{
						steps[i].SetActive(false);
				}
		
				steps[step].SetActive(true);
		}
		
		public void GameStart()
		{
				SceneManager.LoadScene("SuperNewJeans");
		}
		
		public void Exit()
		{
				SceneManager.LoadScene("SuperNewJeans-Home");
		}
		
		public void GameOver()
		{
				ChangeStepUI(2);
		}
		
		public void Restart()
		{
				SceneManager.LoadScene("SuperNewJeans-Home");
		}
}

回到 Unity 介面,在 Game Manager 物件 中會發現剛剛新增的 UI 變數欄位

將 HP、rabbits、Score、CookiePower 等物件依序拖曳至相對應的欄位中

09
10

示意圖為 GameManager 腳本修改後之程式碼( 圖片僅顯示有進行修改的部分)

11
12

STEP 5

設定 Player 撞擊障礙物時的變形效果


開啟 PlayerController 腳本,將原本的程式碼修改為以下版本並存檔

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening; // 新增DOTween的Library

public class PlayerController : MonoBehaviour
{
		public GameManager gm;
		public float currentPosY = 0;
		public float speed = 0;
		
		void Start()
		{
				gm = GameObject.Find("GameManager").GetComponent<GameManager>();
				currentPosY = 0.75f;
				speed = 0.1f;
		}
		
		void Update()
		{
			
		}
		
		private void FixedUpdate()
		{
				if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W))
				{
						currentPosY = currentPosY + speed;
		
						if (currentPosY >= 5.3f)
						{
								currentPosY = 5.3f;
						}
				}
	
		    if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S))
		    {
						currentPosY = currentPosY - speed;
		
						if (currentPosY <= -3.3f)
						{
								currentPosY = -3.3f;
						}
		    }
		        gameObject.transform.position = new Vector3(-5.5f, currentPosY, 0f);
		}
		
		private void OnTriggerEnter(Collider collision)
		{
				string type = collision.gameObject.tag;
				GameObject targetObject = collision.gameObject;
		
				if (type == "rabbit")
		    {
				    Debug.Log("hit rabbit");
						gm.updateRabbitPoint();
						Destroy(targetObject);
		    }
		
				if (type == "cookie")
		    {
				    Debug.Log("hit cookie");
						gm.updateCookiePower();
						Destroy(targetObject);
		    }
		
				if (type == "big-rabbit")
		    {
				    Debug.Log("hit big-rabbit");
		    }
		
		
				// 會扣HP的種類
				
				if (type == "floor")
		    {
				    Debug.Log("hit floor");
						gm.updateHP(-1);
						damageEffect();
		    }
		
				if (type == "enemy")
		    {
				    Debug.Log("hit enemy");
						gm.updateHP(-1);
						damageEffect();
		    }
		}
		
		void damageEffect()
		{
				transform.DOShakeScale(0.5f, 2, 3);
				Invoke("initSize", 0.5f);
		}

		void initSize()
		{
				transform.DOScale(1f, 0);
		}
}

13

示意圖為 PlayerController 腳本上半部修改後之程式碼

14

示意圖為 PlayerController 腳本下半部修改後之程式碼

STEP 6

製作 Block 發射器


建立一個名為 Block 的腳本 建立一個 空物件,並命名為 Block Manager

將 Block 腳本 拖曳至 Block Manager 物件 中

在 Block Manager 物件底下新增一個 Sphere 用來示意發射器位置

15
16
17
18

STEP 7

設計多個不同組合與造型的 Block 並製成預載物件


將 Block 重新命名為 Block-1,並複製貼上兩個相同的 Block,分別命名為 Block-2 及 Block-3

修改 Block-2 及 Block-3 的物件組合與造型 將 Sphere 改為 Inactive 狀態

建立一個名為 Prefab 的資料夾,並將 Block-1 、 Block-2、 Block-3 拖曳至此資料夾中

將 Block-1、Block-2、Block-3 改為 Inactive 狀態

19
20

示意圖為 Block-2 修改後之造型,同學可依自身喜好進行修改與設計。

21

示意圖為 Block-3 修改後之造型,同學可依自身喜好進行修改與設計。

22
23
24
25

STEP 8

設定 Block 的隨機發射樣式


開啟 Block 腳本,輸入以下程式碼並存檔

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Block : MonoBehaviour
{

    public List<GameObject> blockList = new List<GameObject>();

    void Start()
    {
        InvokeRepeating("generateBlock", 0, 2f);
    }

    void Update()
    {

    }

    void generateBlock()
    {
        int blockIndex = Random.Range(0, blockList.Count);
        Debug.Log(blockIndex);
        Instantiate(blockList[blockIndex]);
    }
}

回到 Unity 介面,在 Block Manager 物件 中會發現剛剛新增的 Block List

將 Prefab 資料夾中的 Block-1、Block-2、Block-3 等物件拖曳至 Block List 中

26
27
28
29

示意圖為隨機發射 Block 區塊的遊戲畫面


上一篇
Day21 / Unity 簡單動畫簡單做-程式寫動畫 DOTween 入門
下一篇
Day23 / Unity 可愛的 NewJeans 2D 遊戲 - 計分與結算分數
系列文
初心者限定!設計師帶你學 Unity 3D 遊戲程式設計31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言