unity應用例項——從頭擼一個全新的FPS遊戲(3)
阿新 • • 發佈:2018-12-10
這一篇主要是總結遊戲管理類,既然是遊戲管理,邏輯必然和核心玩法息息相關,也必然需要用到遊戲的關鍵資料(如關卡數等),在這裡需要先建立一個數據管理類儲存資料。這個類不用繼承Monobehaviour。
using UnityEngine; public class datamanager { public static float m_volume = 0.5f; public static float m_mosen = 0.5f; private static int m_gamelevel = 1; public static int M_gamelevel { get { return m_gamelevel; } } public static readonly int m_maxlevel = 4; private static int m_gamescore = 0; public static int M_gamescore { get { return m_gamescore; } } private static float m_playtime; public static float M_playtime { get { return m_playtime; } } public static bool m_isnewlevel = false; public static void AddGameScore() { m_gamescore++; } public static void AddGameLevel() { m_gamelevel++; } public static void CalcuTime()//計時 { m_playtime += Time.deltaTime; } public static void ReturnMenu() { m_playtime = 0; m_gamescore = 0; m_gamelevel = 1; } }
除此之外,還需要先新增一些和玩法有關的指令碼。
為了給玩家加入一個“戰鬥節奏”的概念,再給玩家新增一個狀態控制指令碼,玩家在剛開始戰鬥時是體力充沛的正常狀態,過一段時間進入休息狀態(移動速度大大降低),片刻後再恢復正常。
using UnityEngine; //玩家的兩種狀態,休息狀態和體力充沛狀態 public enum PlayerState { RELAXE, ENERGY } public class playerstatemanager : MonoBehaviour { public static PlayerState m_state = PlayerState.ENERGY; [SerializeField] private float m_relaxtime = 4f; [SerializeField] private float m_energetictime = 20f; private float m_timer = 0;//用來計算時間 private player m_player;//角色控制指令碼的引用 void Start() { m_player = gameObject.GetComponent<player>(); } void Update() { m_timer += Time.deltaTime; if (m_state == PlayerState.ENERGY) { if (m_timer > m_energetictime) { m_player.Relax(); m_state = PlayerState.RELAXE; m_timer = 0; } } if (m_state == PlayerState.RELAXE) { if (m_timer > m_relaxtime) { m_player.Resume(); m_state = PlayerState.ENERGY; m_timer = 0; } } } }
因為每一關的設計都是一個地牢,這裡用碰撞器的觸發器功能來檢測玩家從地牢的門中逃出,此外還可以用觸發器檢測玩家撿到地上的子彈。需要給玩家再新增一個觸發物體的指令碼。
using UnityEngine; public class playertrigger : MonoBehaviour { void OnTriggerStay(Collider collider) { if (collider.gameObject.CompareTag("Exit")) { Destroy(collider.gameObject); datamanager.AddGameLevel(); datamanager.m_isnewlevel = true; } if (collider.gameObject.CompareTag("bullet")) { Destroy(collider.gameObject); gun one = FindObjectOfType<gun>(); one.AddBullets(); } } }
現在我們可以寫遊戲管理類了,建立好以後掛在命名為gamemanager 的空物體上。這裡的m_secondcamera後面會進行說明。
using UnityEngine;
using UnityEngine.SceneManagement;
public class gamemanager : MonoBehaviour
{
[SerializeField]
private float m_WaitTime = 50;
public float M_WaitTime
{
get { return m_WaitTime; }
}
private GameObject m_player;
private GameObject m_camera;
private GameObject m_door;
public GameObject m_secondcamera;//機器人血條所望向的相機
public Transform bornpos;
void Start()
{
m_door = GameObject.FindGameObjectWithTag("door");
m_camera = GameObject.FindGameObjectWithTag("MainCamera");
m_player = GameObject.FindGameObjectWithTag("Player");
//攝像頭(含武器系統)和角色都不會隨場景切換而更改
DontDestroyOnLoad(m_camera);
DontDestroyOnLoad(m_player);
m_door.SetActive(true);
}
void Update()
{
if (m_door.activeInHierarchy)
m_WaitTime -= Time.deltaTime;
if (m_WaitTime <= 0)
{
m_door.SetActive(false);
m_WaitTime = 0;
}
datamanager.CalcuTime();//計時
if (datamanager.m_isnewlevel)
{
//將委託清空
m_player.GetComponent<playerhp>().diedelegate = null;
m_player.transform.position = bornpos.position;
int i = datamanager.M_gamelevel;
if (i == datamanager.m_maxlevel)
{
datamanager.m_isnewlevel = false;
return;
}
else
{
SceneManager.LoadScene(i);
datamanager.m_isnewlevel = false;
}
}
//將兩個相機同步
if (m_secondcamera)
{
m_secondcamera.transform.position = m_camera.transform.position;
m_secondcamera.transform.rotation = m_camera.transform.rotation;
m_secondcamera.GetComponent<Camera>().fieldOfView = m_camera.GetComponent<Camera>().fieldOfView;
}
}
//當遊戲返回主選單時執行的函式
public void OnReturn()
{
playerstatemanager.m_state = PlayerState.ENERGY;
Destroy(m_player);
Destroy(m_camera);
datamanager.ReturnMenu();
SceneManager.LoadScene(0);
}
}