前言
与LuaFramework的对比
xlua如何打热补丁
- 注意要在player setting里面设置Hotfix_Enable
- 每次修改完C#代码之后都要进行HotfixInjector【热补丁注入】
- lua代码如下
xlua.private_accessible(CS.UIScript);
xlua.hotfix(CS.UIScript, 'InitColor', function(self)
self.mText.text = "hello world";
self.mImage.color = CS.UnityEngine.Color.green;
self = nil;
end
)
print('热更新完毕~');
xlua的加载器
- 因为要从streamingAsset文件夹中加载文件
- xlua默认是只能从resource文件夹加载的
- 所以创建一个加载器
luaEnv = new LuaEnv();
luaEnv.AddLoader(StreamingAssetLoader);
//streamingAssetLoader加载器
private byte[] StreamingAssetLoader(ref string filepath)
{
print(filepath);
print(Application.streamingAssetsPath);
string absPath = Application.streamingAssetsPath + "/" + filepath + ".lua.txt";
string content = File.ReadAllText(absPath);
return Encoding.UTF8.GetBytes(content);
}
从本地修复
- 增加一个场景,在该场景里面进行修复
- 首先从本地StreamingAssets文件夹里面获取lua文件,然后就行了
- 即使要修复的脚本涉及多个场景,也可以覆盖
private LuaEnv luaEnv;
// Start is called before the first frame update
void Start()
{
luaEnv = new LuaEnv();
luaEnv.DoString("require 'Do'");
}
从服务器端修复
- 生成资源信息文件,包含lua文件的名与lua文件的md5,用‘|’划分
- 在服务器获取资源信息文件,与本地的资源信息文件进行对比
- 如果完全相同,就直接加载lua文件进行修复
- 如果不同,就获取需要更新的lua文件名,同时用服务器的资源文件对本地的进行替换,
- 组拼地址后从服务器下载lua文件对本地进行替换
- 然后加载lua文件,进行热修复
代码如下
private string webFileUrlBase = null;
private string webFilesUrl = null;
private string webLuaUrl = null;
private LuaEnv luaEnv;
private string localFilesAddress = null;
private string[] webFiles;
private string[] localFiles;
private string localFilesPath = Application.streamingAssetsPath+"/files.txt";
// Start is called before the first frame update
void Awake()
{
luaEnv = new LuaEnv();
luaEnv.AddLoader(StreamingAssetLoader);
webFileUrlBase = "http://192.168.0.106/";
webFilesUrl = webFileUrlBase + "Files.txt";
localFilesAddress = "file://" + Application.streamingAssetsPath+"/files.txt";
StartCoroutine("LoadAsset");
}
private IEnumerator LoadAsset()
{
#region 下载服务器端的files.txt
WWW www = new WWW(webFilesUrl);
yield return www;
if (www.isDone)
{
webFiles = www.text.Split('|');
}
#endregion
#region 加载本地的files.txt
WWW local_www = new WWW(localFilesAddress);
yield return local_www;
if (local_www.isDone)
{
localFiles = local_www.text.Split('|');
}
#endregion
//进行md5校验
if (localFiles[1] != webFiles[1])
{
#region 需要更新
Debug.Log("需要更新");
#region 更新客户端files文件
File.Delete(localFilesPath);
FileStream fs = new FileStream(localFilesPath, FileMode.CreateNew);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(webFiles[0].Trim() + "|" + webFiles[1].Trim());
sw.Close();
fs.Close();
#endregion
#region 下载web端的lua文件
WWW webLua = new WWW(webFileUrlBase + webFiles[0]);
yield return webLua;
if (webLua.isDone)
{
File.Delete(Application.streamingAssetsPath + "/Do.lua.txt");
FileStream temp = new FileStream(Application.streamingAssetsPath + "/Do.lua.txt", FileMode.CreateNew);
StreamWriter sw2 = new StreamWriter(temp);
sw2.Write(webLua.text);
sw2.Close();
temp.Close();
}
#endregion
#endregion
}
luaEnv.DoString("require 'Do'");
yield return new WaitForSeconds(2);
SceneManager.LoadScene("SampleScene");
}
//streamingAssetLoader加载器
private byte[] StreamingAssetLoader(ref string filepath)
{
print(filepath);
print(Application.streamingAssetsPath);
string absPath = Application.streamingAssetsPath + "/" + filepath + ".lua.txt";
string content = File.ReadAllText(absPath);
return Encoding.UTF8.GetBytes(content);
}