Bootstrap

xLua游戏中的热更新(基于Unity2017)

学习目标:

掌握XLua

学习时间:

2021.8.18

学习产出:

1.什么是热更新

热:就是刚出炉
简单来说就是当游戏某个功能出现bug,或者修改了某个功能,或者增加了某个功能的时候,我们不需要重新下载安装安装包,就可以更新游戏内容。

热更新的好处:不用浪费流量重新下载,不用通过商店审核更加快速,不用重新安装玩家可以更快体验到更新的内容

目前比较受欢迎的热更新方案:uLua tolua xLua

2.热更新方案

这些热更新方案都是基于Lua语言的,也可以叫做lua插件(可以运行lua,并实现了lua和C#交互的插件)。
所以本质上这些热更新方案就是一个lua插件,可以运行lua,并实现了lua和C#交互的插件。

1,(luainterface cs2lua tolua)–>ulua(不再维护,转到主要维护tolua)
2,tolua(基于tolua开发了luaframework)
3,slua代码质量好,性能比tolua低
4,C#light、LSharp同一个作者(商用比较少)

3.腾讯的xLua

作者发布的教程
GitHub网址
官方常见问题解释

xLua为Unity、 .Net、 Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用。

xLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯自研游戏,因其良好性能、易用性、扩展性而广受好评。现在,腾讯已经将xLua开源到GitHub。
  2016年12月末,xLua刚刚实现新的突破:全平台支持用Lua修复C#代码bug。
  目前Unity下的Lua热更新方案大多都是要求要热更新的部分一开始就要用Lua语言实现,不足之处在于:
1、接入成本高,有的项目已经用C#写完了,这时要接入需要把需要热更的地方用Lua重新实现;
2、即使一开始就接入了,也存在同时用两种语言开发难度较大的问题;
3、Lua性能不如C#;
  xLua热补丁技术支持在运行时把一个C#实现(函数,操作符,属性,事件,或者整个类)替换成Lua实现,意味着你可以:
1、平时用C#开发;
2、运行也是C#,性能秒杀Lua;
3、有bug的地方下发个Lua脚本fix了,下次整体更新时可以把Lua的实现换回正确的C#实现,更新时甚至可以做到不重启游戏;
  这个新特性iOS,Android,Window,Mac都测试通过了,目前在做一些易用性优化。

4.将lua放入Unity中运行

我们需要从GitHub上下载插件,然后将其Asset文件夹下面的文件放入创建的工程的Asset文件夹下,我们就可以使用xLua插件去开发了。
在这里插入图片描述
我们引入命名空间,实例化LuaEnv,用其内置的方法去执行Lua代码。

using XLua;

private LuaEnv luaenv;
    // Start is called before the first frame update
    void Start()
    {
   
        luaenv = new LuaEnv();//引入命名空间

        luaenv.DoString("print('hello world!')");
        luaenv.DoString("CS.UnityEngine.Debug.Log('hello world!')");  //lua调用C#的方法
    }
    private void OnDestroy()
    {
   
        luaenv.Dispose();//释放内存
    }

实现效果
在这里插入图片描述

5.直接读取lua文件执行

我们可以直接读取xxx.lua.txt文件来执行代码。
首先需要在Resources文件夹下面定义我们的lua代码,记得要在后缀.lua后面加上.txt。这样Unity才会识别
loader是加载器

 private LuaEnv luaenv;
    // Start is called before the first frame update
    void Start()
    {
   
        luaenv = new LuaEnv();//引入命名空间
        //TextAsset ta = Resources.Load<TextAsset>("helloworld.lua");   //默认查找helloword.txt
        //if (ta)
        //{
   
        //    luaenv.DoString(ta.text);
        //}

        luaenv.DoString("require 'helloworld'");//loader 从Resources找helloworld.lua.txt
    }

    private void OnDestroy()
    {
   
        luaenv.Dispose();//释放内存
    }

6.创建自己的lLoader(加载器)

自己创建的Loader,返回的参数便是要执行的代码。
如果返回null,那么就用系统的内置加载器,去Resources去找文件。
如果返回的不是null,那么就执行返回的语句

 
    private LuaEnv luaenv;
    // Start is called before the first frame update
    void Start()
    {
   
        luaenv = new LuaEnv();//引入命名空间
        luaenv.AddLoader(MyLoader);    //Loader就是通过这个自定义的loader去找,如果返回null,那么就用系统内置的。从Resources去找文件 如果不是返回null,那么就执行返回的语句
         luaenv.DoString("require 'test007'");
    }
    
    //这个Loader返回null,那么就相当于使用系统内置的loader
    //private byte[] MyLoader(ref string filePath)
    //{
   
    //    print(filePath);
    //    return null;
    //}
    //private byte[] MyLoader(ref string filePath)
    //{
   
    //    print(filePath);
    //    string s = "print(123)";
    //    return System.Text.Encoding.UTF8.GetBytes(s);//。如果不是返回null,那么就执行返回的语句  这里输出123
    //}

   //这里就是通过文件夹找到文件,然后返回文件里面的代码,然后去执行
    private byte[] MyLoader(ref string filePath)
    {
   
        print(filePath);
        string absPath = Application.streamingAssetsPath + "/" + filePath + ".lua.txt";
        print(absPath);
        return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));//如果不是返回null,那么就执行返回的语句
    }
    private void 

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;