Unity3d 基于xlua热更新实现系列二:Xlua脚本动态加载(半热更新)(含源码)

前言

之前一直在学习xlua的热更新,不过看了将近一个月的,略知一二了,但仿佛未形成体系,而且看再多,也不如动手实现一下。
遂打算实现一个完整体系热更新的demo,从编码、打包、服务器、下载、热更新等过形成整体的认知。并打算将整个过程进行记录,并分享给大家。
不过这只是个demo,仅以登录界面和场景作为热更新处理,且肯定不完美,有些地方实现方法不适合的地方也欢迎大家指出交流,该demo仅供参考,谨慎用于商业项目。
同时会将遇到的坑分享出来。

上一篇,我们实现了“登录功能熟悉lua重写C#”,lua脚本是在编辑器状态下关联起来的,本章,我们打算实现动态加载lua脚本,在生成包体后也可以通过修改(暂时是手动)lua脚本实现半热更新,后续更新的内容放在服务器就可以是真正意义上的热更新逻辑脚本了。

动态加载lua

我们编写了一个加载lua的函数,按脚本名字动态加载lua脚本内容。


    public static string LoadLuaScript(string filepath)
    {
        string path = @"" + Application.dataPath + "/HotUpdateRes/LuaScripts/" + filepath + ".lua";
        if (File.Exists(path))
        {
            return File.ReadAllText(path);
        }
        else
        {
            path = @"" + Application.dataPath + "/OriginalRes/LuaScripts/" + filepath + ".lua";
            if (File.Exists(path))
                return File.ReadAllText(path);
            else
                return null;
        }
}

设定了dataPath的HotUpdateRes/LuaScripts 和OriginalRes/LuaScripts的两个脚本路径,HotUpdateRes表示热更新的目录优先从此加载,OriginalRes为原本的资源目录。这样我们在请求服务器更新内容时,下载后将其放在HotUpdateRes。
这里为什么不用require,后面的坑点中有提出。

加载脚本并绑定相关生命函数:

 string LuaText = Global.LoadLuaScript("LoginUICtrl");
 if (!string.IsNullOrEmpty(LuaText))
 {
      luaEnv.DoString(LuaText, "LoginUICtrl", scriptEnv);
      Action luaAwake = scriptEnv.Get<Action>("awake");
      scriptEnv.Get("start", out luaStart);
      scriptEnv.Get("update", out luaUpdate);
      scriptEnv.Get("ondestroy", out luaOnDestroy);
     if (luaAwake != null)
         luaAwake();
} else
Debug.LogError("加载lua脚本失败!");

验证半热更新

打包后,我们将OriginalRes文件夹移动至XLuaHelloWord_Data文件夹下,
按上一篇的lua脚本运行:
Unity3d 基于xlua热更新实现系列二:Xlua脚本动态加载(半热更新)(含源码)_第1张图片

为了验证半热更新,我们可以两种方式:
1.HotUpdateRes/LuaScripts新建这个目录,然后重写

取消了cube的自传,效果:
Unity3d 基于xlua热更新实现系列二:Xlua脚本动态加载(半热更新)(含源码)_第2张图片

2.直接在OriginalRes中修改

效果同上。

源码

https://download.csdn.net/download/qq_33789001/85013117
打不开说明暂未通过审核

坑点

这个过程中遇到的坑:
1.require无效的问题
我按之前听的个教程来自定义了Lua加载器:

    public static byte[] LuaLoader(ref string filepath)
    {
        string path = Application.dataPath + "/HotUpdateRes/LuaScripts/" + filepath + ".lua.txt";

        if (File.Exists(path)) {
            Debug.Log("读取HotUpdateRes1");
            return File.ReadAllBytes(path);
        }
        else
        {
            Debug.Log("读取OriginalRes2");
            path = Application.dataPath + "/OriginalRes/LuaScripts/" + filepath + ".lua.txt";
            if (File.Exists(path))
                return File.ReadAllBytes(path);
            else
                return null;
        }
    }

并在Awake中添加了加载器:

luaEnv.AddLoader(Global.LuaLoader);

加载:

luaEnv.DoString("require 'LoginUICtrl'", "LoginUICtrl", scriptEnv);

结果:
C#传Xlua的这些参数(loginBtn)都是nil,而且自定义的加载器也加载成功:

Unity3d 基于xlua热更新实现系列二:Xlua脚本动态加载(半热更新)(含源码)_第3张图片

目前没有找到问题所在使用了自定义的加载函数(LoadLuaScript)。

2.关于xlua打包,无法打包成功的问题。
网上进行了查询,进行了如下步骤打包成功:
①将XLua下的示例代码(Assets\XLua\Examples)ExampleGenConfig.cs 文件剪切到Editor文件夹下 ;
②编辑ExampleGenConfig.cs BlackList中添加UnityEngine.Light下的SetLightDirty、shadowRadius、shadowAngle;
Unity3d 基于xlua热更新实现系列二:Xlua脚本动态加载(半热更新)(含源码)_第4张图片

③先清除XLua生成的代码 XLua–>Clear Generated Code
⑤生成XLua代码XLua–>Generate Code
Unity3d 基于xlua热更新实现系列二:Xlua脚本动态加载(半热更新)(含源码)_第5张图片

你可能感兴趣的:(Unity3D,Lua)