1. 程式人生 > 其它 >Unity 熱更新XLua

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();
    }
}