Unity 熱更新XLua
什麼是冷更新
開發者將測試好的程式碼,釋出到應用商店的稽核平臺,平臺方會進行穩定性及效能
測試。測試成功後,使用者即可在AppStore看到應用的更新資訊,使用者點選應用更
新後,需要先關閉應用,再進行更新。
什麼是熱更新
廣義:無需關閉應用,不停機狀態下修復漏洞,更新資源等,重點是更新邏輯程式碼。
狹義定義( iOS熱更新):無需將程式碼重新打包提交至AppStore,即可更新客戶端
的執行程式碼,即不用下載app而自動更新程式。
現狀:蘋果禁止了C#的部分反射操作,禁止JIT(即時編譯,程式執行時建立並運
行新程式碼),不允許邏輯熱更新,只允許使用AssetBundle進行資源熱更新。
注意:2017年,蘋果更新了熱更新政策說明,上線後的專案,一旦發現使用熱更
新,一樣會以下架處理
為何要熱更新
縮短使用者獲取新版應用的客戶端的流程,改善使用者體驗
具體到iOS平臺的應用上,有以下幾個原因
AppStore的稽核週期難控制
手機應用更新頻繁
對於大型應用,更新成本太大
終極目標
不重新下載、不停機狀態下完全變換一個應用的內容
每個平臺如何做熱更新
Android,PC(C#)
將執行程式碼預編譯為AssemblyDLL
將程式碼作為TextAsset打包進AssetBundle
執行時呼叫AssemblyDLL程式碼
更新相應的AssetBundle即可實現熱更新
iOS(Lua)
蘋果官方禁止iOS下的程式熱更新;JIT在iOS下無效
熱更新方案:Unity + Lua外掛
常見的Unity熱更新外掛
sLua:最快的Lua外掛
toLua:由uLua發展而來的,第三代Lua熱更新方案
xLua:特性最先進的Lua外掛
ILRuntime:純C#實現的熱更新外掛
xLua的安裝
官網:https://github.com/Tencent/xLua
將Assets目錄下所有檔案拷貝到專案中
xLua解析器的獲得
DoString函式執行Lua程式碼
Lua程式碼呼叫C#程式碼
C#載入Lua檔案
根據載入提示,發現可以將Lua檔案放在StreamingAssets目錄下
StreamingAssets被拋棄,所以移動到Resources下(以txt為結尾)
自定義載入器LuaEnv.AddLoader()
接觸一個新的Lua專案時,先要弄懂Lua的載入器規則,只有這樣,才能弄懂專案的Lua執行流程
xLua的單例執行環境
xLua解析器建立銷燬
xLua載入器編寫
xLua中Lua呼叫C#程式碼
為什麼?
C#實現的系統,因為Lua可以呼叫,所以完全可以換成Lua實現,因為Lua可
以即時更改,即時執行,所以遊戲的程式碼邏輯就可以隨時修改。
實現和C#相同效果的系統,如何實現?
Lua呼叫Unity的各種API,從而實現C#開發系統同樣的效果
xLua中C#呼叫Lua程式碼
為什麼?
Unity是基於C#語言開發的,所有生命週期函式都是基於C#實現,xLua本身
是不存在Unity的相關生命週期函式的。如果希望xLua能夠擁有生命週期函
數,那麼我們可以實現C#作為Unity原始呼叫,再使用C#呼叫Lua對應的方法。
xLua擴充套件學習(沈軍老師部落格)
https://shenjun-coder.github.io/LuaBook/%E7%AC%AC%E4%B8%89%E7%AB%A0%20XLua%E6%95%99%E7%A8%8B/
有兩年多沒用過Lua 了,今天覆習下
在使用Lua的時候需要在Lua編寫完成後字尾改為.txt
C# 呼叫Lua:
1.Lua程式碼放在Resoucrs資料夾下
luaEnv = new LuaEnv(); TextAsset luaText = Resources.Load<TextAsset("Lua/"+"Test.lua"); luaEnv.DoString(luaText.ToString());
2.放在任意資料夾下
string absPath = Application.streamingAssetsPath + "/" + filePath + ".lua.txt"; return (File.ReadAllText(absPath));
例如:用C#呼叫Lua程式碼實現物體的移動旋轉
Lua
function move( ... ) H = CS.UnityEngine.Input.GetAxis("Horizontal") V = CS.UnityEngine.Input.GetAxis("Vertical") CS.UnityEngine.GameObject.Find("Cube").transform:Rotate(CS.UnityEngine.Vector3(0,H,0)) CS.UnityEngine.GameObject.Find("Cube").transform:Translate(CS.UnityEngine.Vector3(0,0,V)) end
C#
public class Test2 : MonoBehaviour { LuaEnv luaenv = null; Action move; private void Start() { luaenv = new LuaEnv(); TextAsset luaText = Resources.Load<TextAsset>("Lua/" + "GameObjectMove.lua"); luaenv.DoString(luaText.ToString()); move = luaenv.Global.Get<Action>("move"); } private void Update() { move(); } }