LuaFramework_UGUI-master详细讲解(一)

  最近公司要用到lua,在朋友介绍和自己查阅资料之后,便认真研究LuaFramework-UGUI-master这套框架,点这里进行下载。给想学习lua的同学一些建议,少看视频,多看源码。另外以下纯属个人在win10上自己看源码得到的结论,读者若发现错误尽可指出,求不喷。

  在从github上下载压缩包以后,打开压缩包可以看到Assets目录的结构如下:

  

使用unity打开时会自动提示我们自动生成常用类型注册文件,直接点击确定即可,本质是自动生成Assets/LuaFramework/ToLua/Source/Generate下的warp文件,用来将unity常用类的方法和变量注册到LuaState中去(嘘,其实我蒙的,大家随便听听)

  这时候直接运行main场景的话,会报以下错误,

  因为我们忘记了一个重要的步骤--生成资源(此时还没有StreamingAssets文件夹),点击菜单栏->LuaFramework->Build Windows Resource,然后等待片刻即可(此时自动生成了StreamingAssets资源)。这一步骤至关重要,本章节下面将全面详细讲述该操作的运行流程。

  首先,点击菜单栏Build Windows Resource调用的是LuaFramework/Editor/Packager脚本的BuildAssetResource()方法,不同平台都调用该方法,参数就是目标,方法内容如下


  该方法首先判断数据路径Util.DataPath(c:/luaframework/)是否存在,存在则调用Delete方法(true表示递归删除,即其内所有文件全被删除),然后删除并重建StreamingAssets文件夹。然后默认调用HandLuaBundle()//处理Lua代码包,下面会详细介绍。

  HandleLuaBundle()函数是很重要的一步,用于将源目录LuaFramework/Lua和LuaFramework/ToLua/Lua下的所有.lua文件都通过ToLuaMenu.CopyLuaBytesFiles()方法复制到临时目录Assets/Lua对应的子目录下,并添加后缀名.bytes(意思就是根据在源目录的相对路径,在该临时目录下会自动创建对应子文件夹)。然后就遍历该临时目录的所有子文件夹的路径,去掉每个子文件夹路径对应的相同多余前缀并替换'\'为'_',并分别在头部和尾部拼接"lua/lua_"和".unity3d",最终得到的name就是一个完整的assetbundleName。代码如下:

  static void HandleLuaBundle() {
        string streamDir = Application.dataPath + "/" + AppConst.LuaTempDir;//创建临时文件夹
        if (!Directory.Exists(streamDir)) Directory.CreateDirectory(streamDir);

        string[] srcDirs = { CustomSettings.luaDir, CustomSettings.FrameworkPath + "/ToLua/Lua" };//源lua目录
        for (int i = 0; i < srcDirs.Length; i++) {
            if (AppConst.LuaByteMode) {//默认false
                string sourceDir = srcDirs[i];
                string[] files = Directory.GetFiles(sourceDir, "*.lua", SearchOption.AllDirectories);
                int len = sourceDir.Length;

                if (sourceDir[len - 1] == '/' || sourceDir[len - 1] == '\\') {
                    --len;
                }
                for (int j = 0; j < files.Length; j++) {
                    string str = files[j].Remove(0, len);
                    string dest = streamDir + str + ".bytes";
                    string dir = Path.GetDirectoryName(dest);
                    Directory.CreateDirectory(dir);
                    EncodeLuaFile(files[j], dest);
                }    
            } else {
                ToLuaMenu.CopyLuaBytesFiles(srcDirs[i], streamDir);//将源lua文件夹下的所有.lua拷贝到临时文件夹下对应目录(子文件夹根据路径自动生成)
            }
        }
        string[] dirs = Directory.GetDirectories(streamDir, "*", SearchOption.AllDirectories);//获取临时文件下的所有子文件夹路径
        for (int i = 0; i < dirs.Length; i++) {
            string name = dirs[i].Replace(streamDir, string.Empty);//去掉多余前缀
            name = name.Replace('\\', '_').Replace('/', '_');
            name = "lua/lua_" + name.ToLower() + AppConst.ExtName;//得到完整的assetBundleName

            string path = "Assets" + dirs[i].Replace(Application.dataPath, "");
            AddBuildMap(name, "*.bytes", path);
        }
        AddBuildMap("lua/lua" + AppConst.ExtName, "*.bytes", "Assets/" + AppConst.LuaTempDir);

        //-------------------------------处理非Lua文件 将非lua文件全都拷贝到StreamingAssets对应子文件夹下----------------------------------
        string luaPath = AppDataPath + "/StreamingAssets/lua/";
        for (int i = 0; i < srcDirs.Length; i++) {
            paths.Clear(); files.Clear();
            string luaDataPath = srcDirs[i].ToLower();
            Recursive(luaDataPath);
            foreach (string f in files) {
                if (f.EndsWith(".meta") || f.EndsWith(".lua")) continue;
                string newfile = f.Replace(luaDataPath, "");
                string path = Path.GetDirectoryName(luaPath + newfile);
                if (!Directory.Exists(path)) Directory.CreateDirectory(path);

                string destfile = path + "/" + Path.GetFileName(f);
                File.Copy(f, destfile, true);
            }
        }
        AssetDatabase.Refresh();
    }



  我们在得到完整的assetBundleName以后,就可以调用AddBuildMap()方法来创建AsssetBundleBuild对象设置要打包的名称和资源并添加到List集合中。从HandleLuaBundle()方法可以看出,该框架是遍历临时文件夹下的所有子文件夹,然后根据该子文件夹生成一个独特的abName,一个name对应一个AssetBundleBuild对象,即临时文件夹下的每一个子文件夹下的所有.lua文件都会被打入同一个ab文件中。

   最后一个值得一提的是files.txt配置文件的内容以及它是怎样生成的,在BuildFileIndex()方法中,遍历被拷贝到StreamingAssets文件夹中的所有文件(包含非lua文件,不包含.meta文件) 获取绝对路径,去掉路径字符串包含StreamingAssets的多余前缀,得到每个文件的唯一路径,作为files.txt文件的第一列,而第二列则是该文件的md5值。

    static void BuildFileIndex() {
        string resPath = AppDataPath + "/StreamingAssets/";
        ///----------------------创建文件列表-----------------------
        string newFilePath = resPath + "/files.txt";
        if (File.Exists(newFilePath)) File.Delete(newFilePath);

        paths.Clear(); files.Clear();
        Recursive(resPath);

        FileStream fs = new FileStream(newFilePath, FileMode.CreateNew);
        StreamWriter sw = new StreamWriter(fs);
        for (int i = 0; i < files.Count; i++) {
            string file = files[i];
            string ext = Path.GetExtension(file);
            if (file.EndsWith(".meta") || file.Contains(".DS_Store")) continue;

            string md5 = Util.md5file(file);
            string value = file.Replace(resPath, string.Empty);
            sw.WriteLine(value + "|" + md5);
        }
        sw.Close(); fs.Close();
    }
以上是对点击Build Window Resource时执行流程重要部分的讲解,如有遗漏和错误,请大家尽管指出。我会努力尽快更新。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自动生成绑定代码文件,非反射调用 大量内建基础类型支持,如枚举,委托,事件,Type, 数组,迭代器等 支持多种协同形式 支持所有unity内部类导出,支持委托类型导出 支持导出自定义,跳过某个空的基类,修改导出名称等 支持扩展函数自定义导出, 比如DoTween 支持值类型Nullable导出,包括Nullable等 支持Lua中function转委托,可以区分需要不同委托的参数的重载函数 支持c# LuaFunction对象转委托,简化调用方式。 支持无GC的多参数调用形式 支持重载函数自动折叠, 如:Convert.ToUInt32只导出double参数的函数 支持重载函数自动排序, 如:参数个数相同, object参数执行级最低, 不会出现错误匹配情况 支持导出函数重命名, 可以分离导出某个重载函数(可以导出被折叠掉的函数) 支持使用编辑器类改写导出规则 支持this数组访问,索引为int可以通过[]访问,其他可使用.get_Item或者.this:get()访问数组成员 支持委托(事件)+-lua function。支持通过函数接口的Add和Remove委托操作 支持静态反射操作, 形式同c# 支持peer表,可在lua端扩展导出的userdata 支持自定义struct压入和读取,做到无GC,并且结构成员无类型限制, 参考例子24 支持preloading, 可以通过requie后绑定wrap文件 支持int64, uint64 大量的lua数学类型,如Quaternion, Vector3, Mathf等 包含第三方lua扩展,包括luasocket, struct, lpeg, utf8, pb等库 当lua出现异常,能够同时捕获c#端和lua端堆栈,便于调试 print信息,在编辑器点击日志, 能自动打开对应lua文件 支持unity所有版本 支持Lua hook C#相代码实现,一定程度上支持利用Lua代码修改C#端代码的bug(暖更新使用说明)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值