一、IGameModule
框架不建議使用繼承Singleton的單例,當你需要新增一個模塊或者叫管理器的時候,建議繼承IGameModule並在Game腳本中添加靜態引用。
/// <summary>
/// 模塊接口
/// </summary>
public interface IGameModule
{
/// <summary>
/// 模塊優先級
/// </summary>
/// <remarks>優先級較高的模塊會優先輪詢</remarks>
int Priority{ get; }
/// <summary>
/// 遊戲框架模塊輪詢
/// </summary>
/// <param name="elapseSeconds">邏輯運行時間,以秒爲單位</param>
/// <param name="realElapseSeconds">真實運行時間,以秒爲單位</param>
void Update(float elapseSeconds, float realElapseSeconds);
/// <summary>
/// 關閉模塊
/// </summary>
void Shutdown();
}
二、入口
1.GameEntry
這是一個靜態類,在框架層面對所有的模塊進行管理,在遊戲運行時每幀都會遍歷當前已開啓的模塊,雖然類名叫遊戲入口,但其不繼承Mono,還不是真正的遊戲入口
/// <summary>
/// 每幀運行
/// </summary>
/// <param name="elapseSeconds">邏輯運行時間</param>
/// <param name="realElapseSeconds">真實運行時間</param>
public static void ModuleUpdate(float elapseSeconds, float realElapseSeconds)
/// <summary>
/// 獲取一個模塊
/// </summary>
/// <typeparam name="T">模塊類型</typeparam>
/// <returns>模塊</returns>
public static T GetModule<T>() where T : class, IGameModule
/// <summary>
/// 開啓一個模塊
/// </summary>
/// <typeparam name="T">模塊類型</typeparam>
/// <param name="args">對應模塊構造函數需要用到的參數</param>
/// <returns>模塊</returns>
public static T AddModule<T>(params object[] args) where T : IGameModule
/// <summary>
/// 關閉一個模塊
/// </summary>
/// <typeparam name="T">模塊類型</typeparam>
public static void ShutdownModule<T>() where T : IGameModule
/// <summary>
/// 卸載當前已加載的所有模塊
/// </summary>
public static void CleraAllModule()
2.Game
這個腳本需要掛遊戲的初始場景中的一個空物體上,在切換場景時不會被銷燬,在程序開始運行的時候,這個腳本會初始化一些必要的模塊,除非你明確的知道自己要幹什麼,否則不要卸載這些模塊,其餘模塊在合適的地方自行加載和卸載。之後在Update中會調用GameEntry的ModuleUpdate。Game中還保存了對所有模塊的引用,程序中要使用某個模塊的方法統一使用
Game.xxxModule.xxxFunction。
public static EntityManager EntityModule { get; private set; }
public static FsmManager FsmModule { get; private set; }
public static GraphicsManager GraphicsModule { get; private set; }
public static MessageManager MessengerModule { get; private set; }
public static DataSubjectManager ObserverModule { get; private set; }
public static ProcedureManager ProcedureModule { get; private set; }
public static TaskManager TaskModule { get; private set; }
public static ObjectPoolManager ObjectPool { get; private set; }
public static ResourceManager ResModule { get; private set; }
在運行遊戲之前,要選擇進入遊戲的初始流程,腳本會遍歷所有繼承了ProcedureBase的類放在Inspector面板上供選擇。所以在面板上選擇的初始流程的Init()和OnEnter函數是真正的遊戲入口。模塊的卸載和加載也需要在流程的進入和退出中處理。
ProcedureBase的概念會在後面具體介紹,進入一個流程應該儘量不依賴於它之前的流程,這樣的話我們在的測試的時候可以從任何一個關鍵點進入遊戲。
爲了開發方便,使用者可以在所有的場景中都掛載一個Game腳本,Game類在Awake中做了判斷,如果已經有一個Game了,會銷燬自身。