題記 不敢立FLAG,因?yàn)橐呀?jīng)有人栽了。我打算隨心所欲寫(xiě)哪是哪。
[GameFramewrok] https://gameframework.cn/
GF的官方網(wǎng)站給出了文檔和API框架結(jié)構(gòu)圖,更多細(xì)節(jié),你還是自己去官網(wǎng)看吧!
想稍微深入了解一點(diǎn)的話(huà)還是去GITHUB上看看,下面給出截圖。
[GameFramewrok] https://github.com/EllanJiang/GameFramework.git
[UnityGameFramewrok] https://github.com/EllanJiang/UnityGameFramework.git
[StarForce] https://github.com/EllanJiang/StarForce.git
為什么會(huì)是這三個(gè)東西,其實(shí)在官方文檔里已經(jīng)說(shuō)明了他們之間的關(guān)系。大概如下圖
StarForce就是那個(gè)Game了,換句話(huà)說(shuō),如果新建工程的話(huà)其余三個(gè)方塊基本不怎么動(dòng),把Game里整理一下一個(gè)新的項(xiàng)目就出來(lái)。
聽(tīng)說(shuō)集齊這四顆龍珠就可以召喚飛機(jī)出場(chǎng)...于是...
因?yàn)閁nity3d有很多不同版本,GF也最大限度的做了支持(太古老的版本...你就自己想辦法吧^ ^;),我這邊使用的是2019-4.2LTS版本的Unity3d。打開(kāi)Unity3d,添加,選擇StarForce,然后雙擊StarForce 看著進(jìn)度條一頓走...
彈出一個(gè)對(duì)話(huà)框
選擇[Yes],然后就是第二個(gè)對(duì)話(huà)框...
選項(xiàng) [Contine]...一頓進(jìn)度條之后就看到了熟悉的Unity3d的工作臺(tái)界面了,這個(gè)時(shí)候選擇Assets/StarForce場(chǎng)景...然后點(diǎn)擊執(zhí)行...第一沒(méi)有飛機(jī),只有一個(gè)報(bào)錯(cuò)...
莫慌問(wèn)題不大,一切盡在控制之中,導(dǎo)入U(xiǎn)nityGameFramewrok...
這個(gè)時(shí)候有一個(gè)很神奇的報(bào)錯(cuò)...
如果,你跟我一樣也看到了這個(gè)錯(cuò)...好吧!沒(méi)什么道理可以講了,跟我一起去
StarForce/Packages/manifest.json 這個(gè)文件里,把[ "com.jiangyin.gameframework": "https://github.com/EllanJiang/UnityGameFramework.git",] 這一行刪除掉,
然后世界一下子就和平了...就這么簡(jiǎn)單。等等,那個(gè)結(jié)構(gòu)圖里不是還有GameFramework的嗎?怎么沒(méi)看到它出場(chǎng)?問(wèn)題不大,可以去UnityGameFramework/Libraries/ 找到一個(gè)GameFramework.dll和GameFramework.xml;這個(gè)動(dòng)態(tài)庫(kù)呢就是這么玩兒的...
[注]以下操作的前提是建立在你安裝了Visual Studio 及 c#模塊的前提下,沒(méi)有的話(huà)去下載安裝。
第一步先點(diǎn)開(kāi)GameFramework文件夾(我之前下載完成的)
第二步選擇GameFramework.sln點(diǎn)擊打開(kāi)
第三步選擇 Release模式點(diǎn)擊生成.
因?yàn)檫@些是動(dòng)態(tài)鏈接庫(kù)(DLL),所以不能直接運(yùn)行,然后在GameFramework/bin/Release目錄下就可以看到這三個(gè)東西。
如果,有什么需求需要改動(dòng)/升級(jí)它們的話(huà),改完之后測(cè)試無(wú)誤,然后生成這三個(gè)東西。然后把生成出來(lái)的GameFramework.dll和GameFramework.xml拷貝到工程目錄下的UnityGameFramework/Libraries 目錄下,替換里面的那兩個(gè)就可以了。當(dāng)然,QQ群里E老大表示,【我的代碼沒(méi)有一行多余的】所以,改動(dòng)的話(huà)一定要小心。
下面繼續(xù)StarForce,點(diǎn)擊Unity3d的運(yùn)行,這個(gè)時(shí)候就可以看到
隨便點(diǎn)擊一下,還可以去玩一玩這個(gè)Demo游戲。
但是,這個(gè)看似簡(jiǎn)單的游戲到底是怎么跑起來(lái)的呢?
下面,我們來(lái)一起走一走這個(gè)啟動(dòng)游戲的小流程。
這個(gè)工程的目錄結(jié)構(gòu),其實(shí)官方文檔跟很多博客都提到了,我在猶豫要不要再科普一遍。
算了,扯幾句吧!
從StarForce目錄往里.
Assets/GameMain 星際力量Demo的東西
Assets/GameMain/Configs 工程的配置信息 游戲構(gòu)建 發(fā)布之類(lèi)的信息與業(yè)務(wù)邏輯關(guān)系不是很大
Assets/GameMain/DataTables 星際力量的配置信息 游戲里的數(shù)據(jù)
Assets/GameMain/Entities 游戲里的預(yù)制體
Assets/GameMain/Fonts 游戲里用到的字體文件
Assets/GameMain/Libraries 游戲里用到的第三方庫(kù)(所以這也有一份庫(kù)文件夾是要區(qū)別這是跟項(xiàng)目走的,UGF里的是跟Framework走的)
Assets/GameMain/Localization 多國(guó)語(yǔ)言的配置 我看到里面有 簡(jiǎn)體中文 繁體中文 英語(yǔ)和 朝鮮語(yǔ),如果有需求可以繼續(xù)添加類(lèi)似法語(yǔ) 西班牙語(yǔ) 俄語(yǔ) 意大利語(yǔ)這樣的。
Assets/GameMain/Materials 存放材質(zhì)球
Assets/GameMain/Meshes 存放Mesh 我也不知道這個(gè)單詞該怎么翻譯才會(huì)比較合適 姑且叫Mesh吧
Assets/GameMain/Music 存放音樂(lè)文件的
Assets/GameMain/Scenes 存放場(chǎng)景文件的
Assets/GameMain/Scripts 存放腳本文件的
Assets/GameMain/Sounds 存放聲音文件的
Assets/GameMain/Textures 存放紋理貼圖的
Assets/GameMain/UI 存放UI相關(guān)的(這個(gè)目錄有細(xì)分,我就不細(xì)說(shuō)了,里面放了UI的預(yù)制體 音效文件 貼圖文件)
Assets/StreamingAssets 這個(gè)是Unity3d的預(yù)留目錄,用來(lái)存放安裝包的資源,不同平臺(tái)情況還不太一樣(unity官方文檔的話(huà)我不想貼了= =!)。
Assets/UnityGameFramework 這個(gè)是UGF目錄
Assets/UnityGameFramework/Libraries 這是是存放庫(kù)的地方 比如之前的GameFramework.dll 和一個(gè)(zip壓縮和解壓縮的庫(kù)) ICSharpCode.SharpZipLib.dll 如果開(kāi)發(fā)的過(guò)程中有需要的話(huà)可以繼續(xù)添加別的DLL文件進(jìn)去.
Assets/UnityGameFramework/Prefabs 存放預(yù)制體的文件夾(注意這個(gè)可不是項(xiàng)目里用的預(yù)制體,而是UnityGameFramework里的,開(kāi)發(fā)的時(shí)候別亂放)
Assets/UnityGameFramework/Scripts/ 這個(gè)目錄是存放腳本的地方,這里的腳本分兩大塊。
Assets/UnityGameFramework/Editor 是針對(duì)于編輯器的(編輯器的拓展 資源管理 打包發(fā)布資源啥的東西)
Assets/UnityGameFramework/Runtime 是針對(duì)于運(yùn)行時(shí)(也就是俗稱(chēng)的業(yè)務(wù)邏輯 GF里有大量的抽象接口,這里挨個(gè)去實(shí)現(xiàn)它們)
目錄這一塊兒,先簡(jiǎn)單說(shuō)這么多。剩下的來(lái)談?wù)勥@個(gè)StarForce的啟動(dòng)過(guò)程
點(diǎn)擊Unity3d的File菜單 選擇Build Settings... 或者 Ctrl shift + B [ 我這是windows系統(tǒng) 其他系統(tǒng)的按鍵可能不一樣,別沖動(dòng)啊!]
也就是說(shuō)StarForce的啟動(dòng)場(chǎng)景是StarForce Launcher
啟動(dòng)這個(gè)場(chǎng)景的時(shí)候 會(huì)把這個(gè)場(chǎng)景里有的節(jié)點(diǎn)(GameObject)全加上去,就比如Game Framework.
然后,點(diǎn)擊這個(gè)叫Game Framework的GameObject就看到了一個(gè)腳本 GameEntry
打開(kāi)這個(gè)腳本...
注釋欄赫然寫(xiě)著游戲入口...我注意到以下幾個(gè)細(xì)節(jié)點(diǎn):
這個(gè)類(lèi)繼承自MonoBehaviour
在Start方法里 調(diào)用了兩個(gè)方法 字面意思 初始化內(nèi)置組件 初始化定制組件
雖然不是很懂,不過(guò)等我跟進(jìn)去的時(shí)候,就看到了這些...
和這些...
上面寫(xiě)了一堆的set get方法直接就無(wú)視了,partial關(guān)鍵字什么意思之類(lèi)的就自己百度去吧!我就不廢話(huà)了。
這兩個(gè)方法的意思也就是說(shuō),GF/UGF里存在的組件算內(nèi)置組件,StarForce(工程)里存在的組件叫定制組件。
這里提及到了一個(gè)叫GameEntry的類(lèi),跟進(jìn)去看看。
類(lèi)太長(zhǎng),我沒(méi)截全了,大概是一個(gè)管理器,用鏈表管理GameFrameworkComponent的派生類(lèi)。在GameFrameworkComponent抽象類(lèi)里有調(diào)用注冊(cè)方法
它們都繼承自MonoBehaviour,然后看一眼外面的那個(gè)GameFramework
每一個(gè)節(jié)點(diǎn)(Transform)都掛載了一個(gè)腳本,對(duì)應(yīng)一個(gè)系統(tǒng)。
而每一個(gè)掛載的腳本都保留了一個(gè)GameFramework的接口.
在 Awake方法里調(diào)用GameFramewok里的GameFrameworkEntry(模塊管理類(lèi))去獲取對(duì)應(yīng)的模塊。然后初始化設(shè)定,比如類(lèi)似有沒(méi)有help類(lèi),有沒(méi)有委托需要實(shí)現(xiàn)啥的。最后走一波初始化方法,這些模塊基本就是這個(gè)樣子了。
這篇沒(méi)什么技術(shù)含量的文章看起來(lái)扯不完了,先扯扯那個(gè)啟動(dòng)流程吧。
當(dāng)所有的系統(tǒng)都這樣被喚醒了之后,有一個(gè)叫Procedure的系統(tǒng)開(kāi)始發(fā)揮它應(yīng)有的作用了。這個(gè)系統(tǒng)腳本名字叫ProcedureComponent
首先,在Awake方法里獲取GF里的流程管理器接口。
然后,在Start()方法里獲取當(dāng)前C#系統(tǒng)下的所有ProcedureBase的派生類(lèi),這個(gè)時(shí)候全部用反射構(gòu)建出來(lái)放進(jìn)一個(gè)數(shù)組里。
找到編輯器模式下指定的啟動(dòng)Procedure,調(diào)用流程管理器的接口,執(zhí)行初始化方法,把有限狀態(tài)機(jī)管理器和Procedure數(shù)組一起設(shè)置進(jìn)去。
然后,啟動(dòng)協(xié)程,延遲一幀,調(diào)用流程管理器接口,開(kāi)始游戲流程,參數(shù)是啟動(dòng)流程的類(lèi)型。
這里似乎一切都這么簡(jiǎn)單的搞定了?不不不,GF和UGF還有Unity幫我們做了很多你沒(méi)注意到的事情。下面我們來(lái)一點(diǎn)點(diǎn)的掰扯一下具體做了哪些事情?
當(dāng)我們選中Procedure 這個(gè)Transform的時(shí)候,在Inspector里顯示了很多備選方案。我是指除了Transform之外的東西。比如Procedure里的 ProcedureBase的所有派生類(lèi),還有那個(gè)默認(rèn)的啟動(dòng)Procedure。這些都是Unity3d提供的編輯器拓展,它們不是憑空出現(xiàn)的。首先我們找到了傳說(shuō)中的Assets/UnityGameFramework/Scripts/Editor/Inspector/ProcedureComponentInspector.cs這個(gè)腳本。
首先,在 RefreshTypeNames方法里獲取所有的ProcedureBase的派生類(lèi),并且記錄下來(lái),找到選中的那個(gè)啟動(dòng)Procedure。這個(gè)刷新方法會(huì)在OnCompileComplete 和 OnEnable方法里調(diào)用。
其次,在OnInspectorGUI這個(gè)方法里 先做了一些防止意外情況發(fā)生的過(guò)濾處理。然后就是把獲取到的Procedurel類(lèi)型名字挨個(gè)顯示在編輯器上。
最后,這里涉及了幾個(gè)關(guān)于unity3d和c#語(yǔ)法特性的東西,我不做科普了。沒(méi)搞明白的朋友自己找度娘去。
走到了這一步,也就是說(shuō)啟動(dòng)流程的編輯器和數(shù)據(jù)來(lái)源都已經(jīng)明白了,下面我們一起來(lái)掰扯一下有限狀態(tài)機(jī)。
在GF的管理器GameFrameworkEntry這個(gè)類(lèi)里,調(diào)用GetModule方法,如果存在就直接返回,不存在則掛載一個(gè)流程管理器接口。聽(tīng)起來(lái)有點(diǎn)拗口,但它真的是干這事兒了,我以后會(huì)好好掰扯這個(gè)的,現(xiàn)在重點(diǎn)屢一下整體流程。
在流程管理器里有一個(gè)有流程管理器接口的狀態(tài)機(jī)接口和一個(gè)狀態(tài)機(jī)管理器接口,聽(tīng)起來(lái)也有點(diǎn)奇怪。畢竟,這是框架嘛,里面都是接口也不奇怪,見(jiàn)怪不怪就好。
然后就是我們的有限狀態(tài)機(jī)模塊了。這個(gè)模塊分有限狀態(tài)機(jī)的持有者,有限狀態(tài)機(jī)的基類(lèi)(其實(shí)是個(gè)抽象類(lèi)),有限狀態(tài)機(jī)狀態(tài)基類(lèi),有限狀態(tài)機(jī)接口和有限狀態(tài)管理接口。除了有限狀態(tài)機(jī)的基類(lèi)其余都用到了模板。這樣子這個(gè)有限狀態(tài)機(jī)就變得非常靈活好用。狀態(tài)機(jī)我見(jiàn)過(guò)很多不同版本的,這個(gè)是我見(jiàn)過(guò)的復(fù)用性最好的一版。
回到流程管理器,這個(gè)時(shí)候流程啟動(dòng)(狀態(tài)機(jī)也啟動(dòng)了)OnEnter OnInit OnDestory OnLeave OnUpdate 直接照著填空就可以了。當(dāng)然,我稍微走馬觀(guān)花的看了一眼有限狀態(tài)機(jī)的實(shí)現(xiàn)、數(shù)據(jù)來(lái)源和編輯器的支持。
啟動(dòng)這個(gè)星際力量還需要加載UI 顯示游戲的界面,作為一個(gè)游戲項(xiàng)目這個(gè)很重要,也就是所謂的資源模塊和UI模塊。畢竟這個(gè)是單機(jī)的示例游戲,網(wǎng)絡(luò)啥的扯不上。
有了前面流程模塊的大致工作流程,這個(gè)資源模塊其實(shí)也是按照差不多思路去做的。三位一體的路數(shù)。
有可以配置的Transform
有編輯器拓展的支持(Unity3d)
有接口(GF的)和實(shí)現(xiàn)部分(UGF的)
在Inspector里有資源模式 資源讀取路徑的選擇 卸載資源延遲 資源輔助器 資源代理輔助器...一堆設(shè)置。有些我都沒(méi)用過(guò),有些在之前開(kāi)發(fā)的時(shí)候有用過(guò),不過(guò)不得不承認(rèn),我沒(méi)想過(guò)讓這些東西走配置或者說(shuō)編輯器。
值得一提的是資源輔助器和加載資源代理輔助器可以繼承它的父類(lèi)新增一個(gè),然后如果業(yè)務(wù)需要的話(huà),可以拓展這個(gè)模塊。套路跟之前的流程管理的那個(gè)編輯器支持差不多。也是根據(jù)基類(lèi)找到所有的派生類(lèi)提供可以編輯選項(xiàng)。
UI模塊跟資源模塊相似度就來(lái)了。
同樣的也是三位一體,UI是依賴(lài)于資源模塊的,畢竟UI是資源的一部分。
也提供了對(duì)應(yīng)的編輯模塊
需要注意到是 這里有界面輔助器和界面組輔助器可以繼承它們的父類(lèi)進(jìn)行拓展。跟上面提及的流程管理和資源的拓展是差不多的。
扯到這兒,星際力量就可以啟動(dòng)起來(lái)了。
資源模塊加載本地資源(這里其實(shí)是有分類(lèi)處理和不同路徑的管理,我以后再細(xì)說(shuō))
UI模塊基于資源模塊加載UI 貼圖 音效 就可以看到我們之前啟動(dòng)的那個(gè)星際力量界面
工作流程整體是 啟動(dòng)Unity->加載初始場(chǎng)景 ->掛載transform ->掛載組件->啟動(dòng)UGF->調(diào)用GF->走流程管理器->加載資源->加載界面。