1. 程式人生 > >unity應用例項——從頭擼一個全新的FPS遊戲(3)

unity應用例項——從頭擼一個全新的FPS遊戲(3)

這一篇主要是總結遊戲管理類,既然是遊戲管理,邏輯必然和核心玩法息息相關,也必然需要用到遊戲的關鍵資料(如關卡數等),在這裡需要先建立一個數據管理類儲存資料。這個類不用繼承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);
    }
}