Unity热更新方案探索与讨论
熱更新必要性
App Store審核周期長
應(yīng)用更新頻繁
更新版本對(duì)留存數(shù)據(jù)有很大影響
Lua相關(guān)
Lua:腳本,解釋性語言
LuaJit:擴(kuò)展高效版本,支持編譯成二進(jìn)制代碼。
Tolua++:C/C++函數(shù)對(duì)象轉(zhuǎn)化為lua能調(diào)用形式。
Cstolua:C#函數(shù)對(duì)象轉(zhuǎn)化為lua能調(diào)用形式。
ulua、slua、unilua以及鵝廠johnche大神的xlua,ulua、slua是比較成型的解決方案,xlua現(xiàn)在起步不久,功能性以及周邊不足夠完善成熟,但tdr支持很好。性能方面ulua和slua各種較勁,unity官方給了個(gè)測試有ulua與其它lua方案的性能比較。
系統(tǒng)架構(gòu)
我選取一種外面很多游戲已經(jīng)采用的解決方案ulua,并參考了ulua簡單框架,針對(duì)一般游戲的更新需求,做出UI模塊的熱更新設(shè)計(jì)。對(duì)于游戲主邏輯,變化很少,主要針對(duì)UI系統(tǒng)的熱更新。與UI模塊相關(guān)的有網(wǎng)絡(luò)、UI資源以及各UI系統(tǒng)邏輯。如圖:紅色模塊使用Lua文件編碼,其它使用C#編碼。
?
資源:UIPrefab打包成Assetbundle,Lua文件也可以打包成Assetbundle
資源更新:可用IIPS組件。
Lua組件:C#與Lua的交互支持系統(tǒng),詳見后面。
網(wǎng)絡(luò):數(shù)據(jù)進(jìn)入Model,對(duì)于協(xié)議的解析在Lua文件中完成,使得可以支持網(wǎng)絡(luò)協(xié)議數(shù)據(jù)變更。
UI管理器沒有使用Lua,因?yàn)樗渌蚣苄缘南到y(tǒng)一樣,負(fù)責(zé)管理UI資源的加載、釋放、界面層級(jí)等,邏輯比較固定。
熱更新流程
資源更新可使用iips。下面是目前demo的實(shí)現(xiàn)。
資源準(zhǔn)備
UI Prefab資源的各平臺(tái)打包
?
Lua文件
?
更新流程
?
ULUA技術(shù)實(shí)現(xiàn)
將luajit生成各平臺(tái)的庫文件,放到Plugins目錄,在Unity啟動(dòng)時(shí)加載庫使用。
下面是C#和Lua的交互過程。
CSToLua
Ulua新的名字叫tolua,核心思想是利用C#的反射,將C#類代碼進(jìn)行包裝,并注冊到Lua里。C#和Lua的函數(shù)調(diào)用是標(biāo)準(zhǔn)C調(diào)用(stdcall),使用Lua?API把參數(shù)壓棧,并調(diào)用函數(shù)。
這樣Lua代碼里能方便的訪問C#代碼。
如C#類PanelManager
?
PanelManager類的包裝,將成員變量和函數(shù)注冊到Lua。但并不包括基類的,所以基類需要另外的Wrap。
?
Lua中使用PanelManager?=?LuaHelper.GetPanelManager();
?
C#訪問Lua
框架圖中Model是Lua代碼編寫,在C#中經(jīng)常會(huì)訪問Model中的數(shù)據(jù)。C#訪問lua文件的全局變量比較容易,對(duì)類對(duì)象的訪問需要注意。這是因?yàn)長ua在面向?qū)ο缶幊谭矫?#xff0c;比較難以理解買手游平臺(tái),它是通過Lua元表(MetaTable)實(shí)現(xiàn)。
示例:
UI模塊設(shè)計(jì)
代碼框架設(shè)計(jì)與部分類圖:
?
1、ModelManager、UIManager、LuaBehaviour、ControllerBase加入到Wrap中,使得C#和Lua可以交互調(diào)用。
2、ModelMediater作為ModelManager與GameModel的中間層,在Lua代碼中注冊所需要Model、維護(hù)生命周期、網(wǎng)絡(luò)數(shù)據(jù)傳輸、消息事件機(jī)制等。隔離了Model的Lua代碼與C#代碼,以支持GameModel的動(dòng)態(tài)修改。
3、UIMananger負(fù)責(zé)UI的生命周期、顯示層級(jí)、UI消息分發(fā)等。調(diào)用LoadUI,加載Prefab資源,然后在gameObject上添加ControllerBase組件。
4、ControllerBase在Awake時(shí)加載對(duì)應(yīng)的Lua文件,初始化與Mono對(duì)應(yīng)的Lua函數(shù),使得Lua代碼與Mono的?Awake、Start、Update等統(tǒng)一。把ControllerBase設(shè)計(jì)成固定的框架文件,隔離了UI系統(tǒng)與C#代碼,以支持動(dòng)態(tài)修改。
5、Controller可以包含多個(gè)UIView,在Start時(shí)調(diào)用UIView的OnInit初始化界面。還可以設(shè)計(jì)Controller和UIView的消息機(jī)制(待定)。
在ModelMediater和ControllerBase隔離后,UI模塊的MVC獨(dú)立于C#代碼,可以實(shí)現(xiàn)任意修改。UIPrefab打包成AssetBundle實(shí)現(xiàn)更新,如此即可完成UI系統(tǒng)的熱更新。
Demo實(shí)現(xiàn)(ULua+NGUI)
Demo還沒有完全按設(shè)計(jì)完成,主要是Model沒有實(shí)現(xiàn)。
1、Assetbundle打包文件以及Lua文件放在StreamingAssets,在Unity導(dǎo)出時(shí)包含到應(yīng)用程序中一起發(fā)布。
2、將AppConst的DebugMode設(shè)置為false。程序啟動(dòng)時(shí)檢查C:?simpleframework的資源,模擬從網(wǎng)絡(luò)下載;若沒有,則從本地的StreamingAssets解壓;若有,則檢查更新,更新完成后初始化Lua。
NGUI消息機(jī)制:由于可以將C#代碼Wrap并注冊到Lua,所以Lua代碼可以方便的訪問NGUI的消息接口。
?
運(yùn)行結(jié)果:
?
Call?CSharp按鈕點(diǎn)擊后,再調(diào)用C#代碼,驗(yàn)證Lua與C#的相互調(diào)用。
點(diǎn)擊Open按鈕,調(diào)用UIManager打開新的UI對(duì)話框MessageBoxPanel。
?
運(yùn)行結(jié)果:
?
修改MessageBoxPanel.lua,拷貝到C:?simpleframework?lua?View目錄下,模擬更新過程。
?
客戶端啟動(dòng)后比較MD5碼更新。運(yùn)行結(jié)果:
?
Lua調(diào)試工具
BabeLua-vs2012-and-vs2013插件
這個(gè)是集成到visualstudio中的,應(yīng)該更為方便,但我還沒成功試用。。。,請知道的大神不吝賜教。
Unity的Lua熱更新方案很早就有人做了,成熟起來還是自去年開始,現(xiàn)在也越來越多游戲采用了lua。
說幾點(diǎn)Lua缺點(diǎn)來討論:
1、團(tuán)隊(duì)能力要求對(duì)lua有比較深的理解,避免采坑,需要編碼規(guī)范文檔以及注意事項(xiàng)等,對(duì)于沒有積累的團(tuán)隊(duì),這些知識(shí)建檔需要從零開始。
2、編碼效率不高,智能提示不完善。如LuaStudio,對(duì)于c#運(yùn)行時(shí)注冊到lua的類對(duì)象以及函數(shù)是沒有智能提示的,但如果在代碼文件中寫過了這個(gè)接口,LuaStudio是可以掃描到的。
3、調(diào)試堆棧ok的,但這種機(jī)制決定了Unity的Profile不能到內(nèi)部。
總結(jié)
以上是生活随笔為你收集整理的Unity热更新方案探索与讨论的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 游戏服务器端引擎——DogSE的设计
- 下一篇: 浅谈游戏单位属性模块设计:属性组成、分级