IT圈老男孩1 发表于 2021-8-12 11:34

xlua热更新1

学习网址:https://www.bilibili.com/video/av33897278?from=search&seid=12858754428946767754
热:就是刚出炉
简单来说,就是当游戏某个功能出现bug,或者修改了某个功能,后者增加了某个功能的适合,我们不需要重新下载安装安装包,就可以更新游戏内容。
热更新的好处:不用浪费流量重新下载,不用通过商店审核更加快速,不用重新安装玩家可以更快体验到更新的内容。
目前比较受欢迎的热更新方案:ulua、tolua、xlua。
为什么C#脚本不可以直接更新
C#是一门变成语言,它运行之前需要进行编译,而这个编译的过程在移动平台无法完成,所以当我们游戏的逻辑更改,C#代码发生改变的时候,我们就需要重新在开发环境下编译,然后重新打包,然后让玩家去下载更新最新的版本。
这个体验差:包下载需要的时间较长,而且很多资源没有更新,需要要重新下载,浪费流量。
unity提供了一个资源更新技术,就是通过AssetBundle,我们可以通过AB更新游戏UI,也可以把脚本或者其他代码当初资源打包成AB然后更新到客户端。
ulua
https://github.com/jarjin/uLua ?本项目已经不再更新维护,由tolua #代替
tolua
https://github.com/topameng/tolua
xlua
https://github.com/Tencent/xLua 鹅厂
xlua为unity、.net、mono等C#环境增加lua脚本编程的能力,借助xlua,这些lua代码可以方便的和C#相互调用。
下载xlua插件:
https://github.com/Tencent/xLua
解压之后,将asset下的两个文件夹,拖入到unity项目。



例1:执行DoString
using UnityEngine;
using XLua;

public class Demo_001 : MonoBehaviour
{voidStart(){
      LuaEnv luaenv = new LuaEnv();
      luaenv.DoString("print('hello world.')");
      luaenv.Dispose();}}输出:



如果改为调用unity里的Debug.Log:
luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");则输出为:



例2:加载lua文件
lua文件目录:放在Resources目录下:


lua内容为:



测试代码:
using UnityEngine;
using XLua;
public class demo_002 : MonoBehaviour
{void Start (){

      TextAsset ta = Resources.Load<TextAsset>("test.lua");
      LuaEnv luaenv = new LuaEnv();
      luaenv.DoString(ta.text);
      luaenv.Dispose();}}或者通过require方式加载文件:
using UnityEngine;
using XLua;
public class demo_002 : MonoBehaviour
{void Start (){//TextAsset ta = Resources.Load<TextAsset>("test.lua");
      LuaEnv luaenv = new LuaEnv();//luaenv.DoString(ta.text);
      luaenv.DoString("require 'test'");

      luaenv.Dispose();}}例3:自定义loader



using UnityEngine;
using XLua;
using System.IO;

public class demo_002 : MonoBehaviour
{void Start (){

      LuaEnv luaenv = new LuaEnv();
      luaenv.AddLoader(MyLoader);
      luaenv.DoString("require 'test'");
      luaenv.Dispose();}

    private byte[]MyLoader(ref string filePath){print(filePath);
      string absPath = Application.streamingAssetsPath +"/"+ filePath +".lua.txt";return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));}}输出:



例4:C#访问lua变量



test.lua.txt放在resources目录下。
测试代码:
using UnityEngine;
using XLua;
using System.IO;

public class demo_002 : MonoBehaviour
{void Start (){

      LuaEnv luaenv = new LuaEnv();
      luaenv.DoString("require 'test'");double a = luaenv.Global.Get<double>("a");print(a);
      string b = luaenv.Global.Get<string>("b");print(b);double c = luaenv.Global.Get<double>("c");print(c);
      luaenv.Dispose();}}例子5:C#访问lua的table——方式1类
放在中文乱码:


lua中的table:
person ={name="小明", age =12}C#代码:
using UnityEngine;
using XLua;
using System.IO;

public class demo_002 : MonoBehaviour
{void Start (){

      LuaEnv luaenv = new LuaEnv();
      luaenv.DoString("require 'test'");
      Person p = luaenv.Global.Get<Person>("person");print(p.name +"-"+ p.age);
      luaenv.Dispose();}//定义一个类,成员同名
    class Person
    {
      public string name;
      public int age;}}下面通过类去修改lua中的table成员:
Person p = luaenv.Global.Get<Person>("person");print(p.name +"-"+ p.age);
p.name ="小花";
luaenv.DoString("print(person.name)");发现lua中的person成员name没有被改变,总结,如果通过C#中的类去映射lua中的table,其是值拷贝,不会影响lua中的table成员。
还有一种方式是通过接口映射,如下:
using UnityEngine;
using XLua;
using System.IO;

public class demo_002 : MonoBehaviour
{voidStart(){

      LuaEnv luaenv = new LuaEnv();
      luaenv.DoString("require 'test'");
      IPerson p = luaenv.Global.Get<IPerson>("person");print(p.name +"-"+ p.age);
      p.name ="小花";
      luaenv.DoString("print(person.name)");
      luaenv.Dispose();}//加入注解
    interface IPerson
    {
      string name { get; set;}//必须是属性int age { get; set;}}}例6:C#调用lua的函数
person ={name="小明", age =12,
sayHello =function(self, name)print(name);
                   end
}注意lua中的function定义加了一个参数self
C#代码:
using UnityEngine;
using XLua;
using System.IO;

public class demo_002 : MonoBehaviour
{voidStart(){

      LuaEnv luaenv = new LuaEnv();
      luaenv.DoString("require 'test'");
      IPerson p = luaenv.Global.Get<IPerson>("person");
      p.sayHello("xiaoming");
      luaenv.Dispose();}
    interface IPerson
    {
      string name { get; set;}int age { get; set;}voidsayHello(string name);}}除了上面的lua定义函数的方式,还可以是:
function person.sayHello(self, name)print(name);
end或者:
function person:sayHello(name)print(name);
end
页: [1]
查看完整版本: xlua热更新1