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