GF框架分兩部分,GameFramework(GF)和UnityGameFramework(UGF);
通過介面的形式對Unity引擎進行了解耦;
GF獨立於Unity,具體業務邏輯實現都在GF中;
UGF是繼承了MonoBehaviour的元件,通過介面呼叫GF中Module的方法;
左邊GF層,由GameFrameworkEntry管理所有GameFrameworkModule;(使用GF自己實現的連結串列非list)
Update階段根據每個Module的Priority順序輪詢執行所有Module的Update;
GameFrameworkEntry對外提供獲取單個Module的方法;
右邊UGF層,UGF中所有Component都繼承GameFrameworkComponent;
GameFrameworkComponent做兩件事:
UGF中的BaseComponent,Awake階段做Text,Log,版本,json輔助器的初始化;
Update階段呼叫GF層的GameFrameworkEntry的Update方法,輪詢實行所有GF層Module的Update;
BaseComponent還提供推出程式,重啟暫停遊戲的方法;
UGF層的GameEntry:
上文提到,所有的UGF元件都繼承GameFrameworkComponent;
GameFrameworkComponent的Awake階段呼叫GameEntry的RegisterComponent方法,儲存UGF元件;
E大官方檔案建議,在實際遊戲開發階段,對UGF的GameEntry再做一層封裝——業務層的GameEntry;
將所有用到的UGF元件建立靜態只可get的屬性,只有業務邏輯中只需要通過業務層GameEntry中的靜態屬性來獲取UGF元件;(官方Starforce名稱空間下的GameEntry)
GFModule繼承對應Module的介面,實現具體方法;
UGF組合對應元件介面,Awake階段對介面初始化,通過介面呼叫GF方法;
以ConfigComponent為例:
ConfigManager實現IConfigManager介面方法;
ConfigComponent組合IConfigManager變數,在Awake階段用GF層的ConfigManagerModule初始化;
GF框架的資源管理非常強大,整合了VFS系統效率高,編輯器拓展管理打包資源清晰明瞭;
Package單機模式:無法熱更;
Updatable可更新模式:遊戲開始前更新完進入遊戲;
Updatable while playing可更新分包載入:遊戲執行時需要使用資源時即時下載;
Config下ResourceBuilder.xml儲存了打包介面的設定資訊;
ResourceEditor.xml設定了ResourceEditor介面中可被打包的資源格式,過濾所有指令碼,同時設定了資源編輯介面的搜尋路徑;
ResourceCollection.xml記錄了所有ab包,以及資源依賴;
介面操作GF的官方檔案寫的非常詳細,這裡介紹一下資源熱更流程;
Resource節點選擇Updatable,GameFramework節點關閉EditorResourceMode;
ResourceBuilder打包勾選OutputFullPath;
修改GameMian/Configs/BuildInfo.txt中CheckVersionUrl;
打包輸出路徑找到對應打包版本的BuildLog.txt,找出加密hash;
打包輸出路徑/Full/1_0_0(對應版本)下,建立version.txt,本地伺服器也搭建在這個位置;
{
"ForceUpdateGame": false,
"LatestGameVersion": "1",
"InternalGameVersion": 0,
"InternalResourceVersion": 1,
"UpdatePrefixUri": "http://localhost:8888/Windows", //資源伺服器地址
"VersionListLength": 3280, //BuildLog中的加密hash
"VersionListHashCode": -553090012,
"VersionListCompressedLength": 1326,
"VersionListCompressedHashCode": 1159160375,
"END_OF_JSON": ""
}
更新時比對LatestGameVersion和InternalGameVersion,確定是否更新;
一定要刪除本地快取的persistantData路徑下的檔案;
GF的DataTable預設excel複製下來的結構,像CSV但分隔符是/t;
直接用DataTable元件根據行數載入單條資料;
支援bytes和json格式;
Configs中DataTableCodeTemplate,用於生成C#類別範本;
怎麼說呢,簡單遊戲夠了,複雜點的還是加個導表工具或者魔改一下;
DataTable也可以新增自定義資料解析;
另外直接在txt中新增資料條總是莫名奇妙的格式錯誤,畢竟空格肉眼也區分不了;
我改成,
分隔後,註釋列又顯得很多餘;
所以我根據GF的原理自己誰先了直接讀Excel的DataTable,支援json和bytes;
一鍵匯出,且自動生成c#類,支援陣列和列舉,支援excel公式;
GF的事件系統是基於參照池的,每次回收前需要Clear資料,防止髒資料;
GameEntry.Event.Subscribe(TestArgs.EventId, OnTest);
GameEntry.Event.Unsubscribe(TestArgs.EventId, OnTest);
public class TestArgs:GameEventArgs
{
public static readonly int EventId = typeof(ResourceVerifyStartEventArgs).GetHashCode();
public override int Id
{
get
{
return EventId;
}
}
public override void Clear()
{
}
//以上部分是必須有的部分,以下屬於自定義,事件需要傳遞的引數都可以寫在下面,相應的Clear中需要清空
}
GameEntry.Event.Fire(object sender,new TestArgs());
sender傳送人,一般填this;
第二引數,具體事件類,如果有引數,需要先賦值,個人喜歡寫帶參構造,也可以單獨寫Init函數;
public void OnTest(object sender, GameEventArgs e)
{
TestArgs en = (TestArgs)e;
//執行邏輯
}
GF框架使用流程控制來控制遊戲階段;
流程控制元件是一個被固定了擁有者(ProcedureOwner)的狀態機(FSM);
通過狀態機來控制更新,載入,初始化等;
這裡的流程不指遊戲中具體業務邏輯流程;
StarForce中的流程控制;有問題打個斷點總能看清楚的;
切換場景GF時切換到changeScene流程解除安裝資源後載入新場景流程;
GF的UI分為UIGroup和UIForm;
UIGroup中包含多個UIForm,由UIGroup管理其中的UIForm;
UIForm的層級等於所屬UIGroup層級自身層級(SortOrder);
UIGroup概念有點想UI中的預設層,Pop層,前景層,背景層,可自定義;
在場景UI節點新增UIGroup;
所有UI指令碼必須繼UGuiForm,UGuiForm繼承UIFormLogic,UGuiForm中對所有Text做了在地化處理;
UI生命週期:
UI的層級問題:
每個UIGroup要求設定order層級;
每個UIForm的層級最終是自身sortorder+所屬group的order;
在建立預製體時可設定好;
Entity個人理解相當於自己封裝了一個MonoBehaviour類,但是還整合了Mono;
同時有GF的生命週期+Mono的生命週期;
Enity包括了GameObject的功能,由GF的EntityModule來控制Active;
Entity也是基於物件池的,從框架層管理記憶體問題;
邏輯控制類繼承EntityLogic,重寫其中生命週期的方法(別忘記base.);
顯示Entity呼叫GameEntry.Entity.ShowEntity
id在datatable中設定;
path為datatable中設定的預設路徑+AssetName;(ResourceEditor介面的path)
Entity中提供了Attach方法;
通過GameEntry.Entity.AttachEntity()呼叫,此時會呼叫父物體EntityLogic中OnAttached週期,和子物體OnAttachTo週期;
解綁時呼叫OnDetached,OnDetachFrom;
預製體不需要綁EntityLogic指令碼,ShowEntity時會自動綁上EntityLogic+Entiy指令碼;
這倆指令碼相互參照,Entity的週期中都在呼叫EntiyLogic對應的周期函數;
Entity繼承自IEntity,被EntityComponent管理;
小聲比比:所以,這兩個有一個就行,或者Entity其實不用繼承Mono;
具體操作時,只寫EntityLogic指令碼,不用管Entity;
GF的狀態機都由FsmComponent管理(GameFrameworkComponent);
建立狀態機時,需要狀態機的Owner(泛型T),和FsmState陣列;
eg:Hero繼承EntityLogic
ActBase<Hero>[] array = new ActBase<Hero>[] { new IdleAct<Hero>(), new RunAct<Hero>() };
mFsm = GameEntry.Fsm.CreateFsm<Hero>(this, array);
public class IdleAct<T>:ActBase<T> where T : Hero
{
protected override void OnInit(IFsm<T> fsm)
{
base.OnInit(fsm);
}
protected override void OnEnter(IFsm<T> fsm)
{
base.OnEnter(fsm);
fsm.Owner.PlayCurAnima();
}
protected override void OnUpdate(IFsm<T> fsm, float elapseSeconds, float realElapseSeconds)
{
base.OnUpdate(fsm, elapseSeconds, realElapseSeconds);
if (fsm.Owner.curState == ActState.Run)
{
ChangeState<RunAct<T>>(fsm);
}
}
}
GF的Localization儲存的xml;
UI的Init階段遍歷所有元件,獲得所有Text元件,根據Text元件中的text載入在地化語言,同時設定對應字型;
該語言=重新載入遊戲;
這個元件簡單但不夠智慧;
個人新增了兩個功能:
根據TextMeshProGUI元件的Name和text內容自動新增簡體中文多語言xml的key;
呼叫谷歌介面自動翻譯,生成其他語言xml;