这一篇主要是总结游戏管理类,既然是游戏管理,逻辑必然和核心玩法息息相关,也必然需要用到游戏的关键数据(如关卡数等),在这里需要先创建一个数据管理类存储数据。这个类不用继承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;
}
}
//当游戏返回主菜单时执行的函数,绑定在Button上
public void OnReturn()
{
playerstatemanager.m_state = PlayerState.ENERGY;
Destroy(m_player);
Destroy(m_camera);
datamanager.ReturnMenu();
SceneManager.LoadScene(0);
}
}
下一篇是对于追踪机器人的设计:https://blog.csdn.net/qq_37553152/article/details/82156357