Unity XLua熱更新
持續更新
相關連結
基礎案例
0基礎的先看 xlua遷入專案
/*
* Author : Jk_Chen
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
/// <summary>
/// 熱更新類,進行程式碼的修復
/// </summary>
public class XLuaFix : MonoBehaviour
{
static LuaEnv lua;
static int tmp = 2;
void Awake()
{
lua = new LuaEnv();
// 簡單執行Lua語句
lua.DoString("print 'lua print'");
// 呼叫C#類的公有靜態方法
lua.DoString("CS.UnityEngine.Debug.Log('cs debug')");
lua.DoString("CS.XLuaFix.Print()");
// 先讓某個類的私有成員可訪問,再呼叫私有靜態方法
lua.DoString("xlua.private_accessible(CS.XLuaFix)");
lua.DoString("CS.XLuaFix.PrivatePrint()");
// 修改靜態變數
lua.DoString("CS.XLuaFix.tmp=3");
lua.DoString("print('修改後的靜態變數為:' .. CS.XLuaFix.tmp)");
}
public static void Print()
{
Debug.Log("public static");
}
private static void PrivatePrint()
{
Debug.Log("private static");
}
private void OnDestroy()
{
lua.Dispose();
}
}
關於XLua的生成程式碼和程式碼注入
程式碼需要進行熱更新的時候,需要進行生成程式碼和程式碼注入。
請在每次修改程式碼後(執行前)都執行一遍該操作。
程式碼注入後Debug會比較麻煩,因為Log內尋找不到是哪行程式碼的執行結果。
看得到,但是不能通過點選直接找到哪行
原來是這樣的
如果不需要熱更新可以把生成的程式碼Clear掉
簡單熱更新
必要步驟
- 需要熱更新的類前加[Hotfix]
- 執行前生成程式碼和程式碼注入
/*
* Author : Jk_Chen
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
/// <summary>
/// 熱更新類,進行程式碼的修復
/// </summary>
[Hotfix]
public class XLuaFix : MonoBehaviour
{
static LuaEnv lua;
public static int tmp = 2;
void Awake()
{
lua = new LuaEnv();
// 呼叫帶參函式
lua.DoString("CS.XLuaFix.Print(CS.XLuaFix.tmp)");
// 修改函式
lua.DoString(
@"xlua.hotfix(CS.XLuaFix,'Print',function(value)
CS.UnityEngine.Debug.Log('After ' .. value*value)
end)"
);
// 呼叫修改後的函式
lua.DoString("CS.XLuaFix.Print(CS.XLuaFix.tmp)");
}
public static void Print(int value)
{
Debug.Log("Defore " + value);
}
private void OnDestroy()
{
lua.Dispose();
}
}
程式碼修復成功,但是報錯了。這個錯誤官方有回答:
這是由於C#還存在指向lua虛擬機器裡頭某個函式的delegate,為了防止業務在虛擬機器釋放後呼叫這些無效(因為其引用的lua函式所在虛擬機器都釋放了)delegate導致的異常甚至崩潰,做了這個檢查。
怎麼解決?釋放這些delegate即可,所謂釋放,在C#中,就是沒有引用:
你是在C#通過LuaTable.Get獲取並儲存到物件成員,賦值該成員為null;
你是在lua那把lua函式註冊到一些事件事件回撥,反註冊這些回撥;
如果你是通過xlua.hotfix(class, method, func)注入到C#,則通過xlua.hotfix(class, method, nil)刪除;
要注意以上操作在Dispose之前完成。
所以我們在釋放虛擬機器之前釋放這些委託即可:
private void OnDestroy()
{
// 釋放委託
lua.DoString(
@"xlua.hotfix(CS.XLuaFix,'Print',nil)"
);
lua.Dispose();
}
使用Lua指令碼檔案
之前使用到的都是在C#程式碼內使用DoString來呼叫Lua,這樣有一個很麻煩的地方就是,由於每次都會修改程式碼,所以都需要生成和注入。而且和我們的熱更新也不搭嘎。
所以我們現在使用指令碼檔案的方式。require函式可以載入一個lua指令碼,但如果lua指令碼不在Resources路徑下,或者不在預設的目錄下,此時是載入不到對應的lua指令碼的。
我們需要自己寫一個loader來適配lua指令碼的位置:
c#程式碼:
/*
* Author : Jk_Chen
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
/// <summary>
/// 熱更新類,進行程式碼的修復
/// </summary>
[Hotfix]
public class XLuaFix : MonoBehaviour
{
static LuaEnv lua;
public static int tmp = 2;
void Awake()
{
lua = new LuaEnv();
// 定義loader,從Assets/Lua目錄下讀取,已自帶.lua.txt
// 例如讀取Assets/Lua/xx.lua.txt只需要 lua.DoString("require('xx')");
lua.AddLoader((ref string file) => {
string path = System.IO.Path.Combine("Assets/Lua", file + ".lua.txt");
if (System.IO.File.Exists(path))
{
return System.IO.File.ReadAllBytes(path);
}
else
{
return null;
}
});
lua.DoString("require('XLuaFix')");
}
public static void Print(int value)
{
Debug.Log("Defore " + value);
}
private void OnDestroy()
{
// 釋放委託
lua.DoString("require('XLuaFixDispose')");
// 釋放虛擬機器
lua.Dispose();
}
}
lua指令碼: XLuaFix.lua.txt
-- 呼叫帶參函式
CS.XLuaFix.Print(CS.XLuaFix.tmp)
-- 修改函式
xlua.hotfix(CS.XLuaFix,'Print',function(value)
CS.UnityEngine.Debug.Log('After ' .. value*value)
end)
-- 呼叫修改後的函式
CS.XLuaFix.Print(CS.XLuaFix.tmp)
lua指令碼: XLuaFixDispose.lua.txt
-- 釋放委託
xlua.hotfix(CS.XLuaFix,'Print',nil)
本人是用notepad寫lua指令碼的
notepad配置部落格
相關文章
- xLua熱更新外掛
- 熱更新解決方案--xlua學習筆記筆記
- Unity匯入xLua流程Unity
- 【Unity】XLua巨坑彙總Unity
- xLua熱更開發之一:初見xlua,你好
- 深入理解xLua基於IL程式碼注入的熱更新原理
- Unity3D熱更新之LuaFramework篇[08]--熱更新原理及熱更伺服器搭建Unity3DFramework伺服器
- Unity3D熱更新之LuaFramework篇[09]--資源熱更新與程式碼熱更新的具體實現Unity3DFramework
- Unity 小遊戲轉換(一)—— WebGL+XLua匯出Unity遊戲Web
- Unity 開源雙端框架 ET 中初嘗熱更新技術Unity框架
- Unity3D熱更新之LuaFramework篇[07]--怎麼讓unity物件繫結Lua指令碼Unity3DFramework物件指令碼
- xlua - 增加protobuf庫
- webpack 熱更新原理Web
- Hyperf - 熱更新Watcher
- React Native 熱更新React Native
- Vuex之熱更新Vue
- Unity 熱更--AssetBundle學習筆記 0.7Unity筆記
- Unity 熱更--AssetBundle學習筆記 0.8Unity筆記
- 熱更新配置檔案
- uniapp實現熱更新APP
- uni-app熱更新APP
- Flutter 應用熱更新Flutter
- Webpack 熱更新機制Web
- [使用目前最新版]HybridCLR6.9.0+YooAsset2.2.4實現純C# Unity熱更新方案 (一)C#Unity
- xLua中C#呼叫LuaC#
- xLua中Lua呼叫C#C#
- Xlua中LuaBehaviour的實現
- Xlua常見API彙總API
- Flutter Android 端熱修復(熱更新)實踐FlutterAndroid
- 淺析“熱更新”(熱修復)解決方案
- React Native 熱更新實踐React Native
- go熱更新問題求助Go
- js熱更新簡單分析JS
- Android熱更新實現方式Android
- Unity3D熱更新之LuaFramework篇[06]--Lua中是怎麼實現指令碼生命週期的Unity3DFramework指令碼
- Unity3D熱更新之LuaFramework篇[05]--Lua指令碼呼叫c#以及如何在Lua中使用DotweenUnity3DFramework指令碼C#
- ReactNative分散式熱更新系統React分散式
- Flutter 熱更新功能實現Flutter