2021年7月19日星期一

XLua基础

XLua简介

Xlua是腾讯研发的一款Lua开源插件,为Unity、 .Net、 Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用,在游戏中,该技术多用于热更新。可以在GitHub上搜索XLua进行下载,如果网速太慢,也可以在gitee上下载

[gitee链接]  https://gitee.com/mirrors/xlua?utm_source=alading&utm_campaign=repo 

 

C#执行Lua脚本

我们在学习每一个课程的时候,最先接触的都是"Hello world",在XLua中,如何执行该语句呢?将下载的Xlua项目打开,并且创建一个新的脚本,引入XLua命名空间,并挂载到游戏物体。

 //声明一个Lua虚拟机
   public static LuaEnv lua;

   private void Start()
  {
       //对虚拟机进行实例化
       lua = new LuaEnv();
       //用C#的UnityEngine.Debug.Log打印日志
       lua.DoString("CS.UnityEngine.Debug.Log('Hello world')");
       lua.Dispose();
  }

此时,运行项目,可以看到在控制台中打印出了 Hello world

Tips💁‍♂:一个LuaEnv实例对应Lua虚拟机,出于开销的考虑,建议全局唯一。

通过Lua.DoString函数,我们可以在Lua语言中快速执行C#代码,但是当Lua脚本内容较多时,将不是很方便执行,这时可以将脚本写在Lua文件中,并C#中执行.

首先在Unity中创建Resources文件夹,并在里面创建一个txt文本文件,命名为"Demo1.lua.txt"(其要求的是一个文本文档,文件名中的.lua并没有其他含义,仅仅是起标识作用),在文本中加入CS.UnityEngine.Debug.Log("Hello world,load file"),接下来加载该文件

private void Start()
{
   //对虚拟机进行实例化
   lua = new LuaEnv();

   //方式一:通过TextAsset加载
   TextAsset asset = Resources.Load<TextAsset>("LuaDemo1.lua");
   lua.DoString(asset.text);
   
   //方式二:通过Require加载(常用),只能使用Resources与内置的路径的lua文件,不能自定义路径
   lua.DoString("require 'LuaDemo1'");
   
   //方式三:自定义Loader加载,使用Require加载有不能自定义路径等缺点,通过自定义Loader则可以解决上述问题
   lua.AddLoader(DemoLoader);
   lua.DoString("require 'LuaDemo1'");
}

//自定义Loader函数,执行DoString时会自动调用该函数,里面可以实现自己的逻辑
private byte[] DemoLoader(ref string filepath)
{
   string path = filepath + ".lua";
   TextAsset asset = Resources.Load<TextAsset>(path);

   return asset.bytes;
}

 

C#获取与修改Lua中的值

获取Lua中的变量

首先我们修改lua文本文档LuaDemo1中的内容,定义下面两个变量

    x = 123;
   y = "456"

接下来在C#中获取x和y的值,Global是Lua中的一个全局表,里面包含了所有的全局变量

    lua.DoString("require 'LuaDemo1'");

//获取Lua中的值
   int x = lua.Global.Get<int>("x");
   string y = lua.Global.Get<string>("y");

   Debug.Log(x + " , " + y); //打印 123 , 456

//修改Lua中的值
lua.Global.Set("x", 321);
Debug.Log(lua.Global.Get<int>("x"));   //打印 321

 

获取Lua中的Table

如果Lua脚本中包含Table,又该怎么调用呢?我们在Lua文本中添加Table,如下所示

    x = 123;
   y = "456"
   
--定义person表
   person =
  {
       name = "slayer",
       age = 8,
       "only string",
       999,
       speak = function()
           print("this is a function in Person")
       end
  }

--通过.的方式为person表添加函数
   function person.sayName(self)
       print(self.name)
   end

--通过:的方式为person表添加函数 等价于 person.getAge(self)
   function person:getAge()
       print(self.age)
   end

C#若要获取Lua中Table值,可以通过类或者接口建立映射,然后获取其值,下面展示如何使用接口获取

    private void Start()
  {
       lua.DoString("require 'LuaDemo1'");

       //上面person表中,对于"only string",999这样单独的值,可以通过List建立映射
       List<object> list = new List<object>();
       list = lua.Global.Get<List<object>>("person");
       foreach (var val in list)
      {
           Debug.Log(val); //分别打印"only string",999
      }

       IPersonal person = lua.Global.Get<IPersonal>("person");
       Debug.Log(person.name); //输出 "slayer"
       Debug.Log("Sum:" + person.getSum(12, 34)); //输出 46
  }    

//定义IPersonal接口,注意这里必须使用 CSharpCallLua 标签
//并且里面的属性和方法要和Lua脚本中的person表对应
  [CSharpCallLua]
   public interface IPersonal
  {
       string name { get; set; }
       string age { get; set; }

       void sayName();

       int getSum(int num1, int num2);
  }

 

获取Lua中的函数

我们先在Lua脚本中定义两个函数,如下所示:

    function m_Print(msg)
       print(msg)
   end

   function Add(a,b)
       return a + b
   end

要在C#中调用这两个函数,需要使用委托,对于没有返回值的,可以使用C#自带的Action,有返回值则使用Func,当然也可以自定义委托

    lua.DoString("require 'LuaDemo1'");

//通过Action获取Lua中的映射,并执行该函数
   Action<string> mPrint = lua.Global.Get<Action<string>>("m_Print");
   mPrint("Hello world");

   Func<int, int, int> add = lua.Global.Get<Func<int, int, int>>("Add");
   int ans = add(1, 2);
   Debug.Log("Add ans:" + ans); //输出 3

 

错误信息:InvalidCastException: This type must add to CSharpCallLua:XXXX

执行上述代码时,可能会出现上述错误,该错误表面当前使用的类型没有加上CSharpCallLua标签,此时我们需要将该标签添加到对应的地方,正常情况下错误将会消失.但有时候,明明添加了该标签,还是提示这个错误,这时通过下面三个步骤一般都可以解决.

  • 方式一:在Unity的Player Setting中将API Compatibility Level设置为 .NET 4.X

     

  • 方式二:点击XLua -> Clear Generated Code -> Generated Code

     

  • 方式三:在Assets文件夹中,找到XLua -> Examples,找到ExampleGenConfig.cs文件,在CSharpCallLua中按照格式添加你要调用的方法

     

    再不行就只能换一个版本重试了.

 

XLua调用C#静态方法

  在上一节中我们学习了怎么通过C#调用XLua打印"Hello world",那么XLua如何调用C#呢?一行代码轻松搞定

首先创建一个txt文件保存XLua脚本内容,我们命名为"LuaDemo2.lua.txt",里面的内容如下

--调用C#中Debug.Log函数
--Lua通过CS来访问C#的代码,后面的UnityEngine为命名空间
--CS.UnityEngine.Debug.Log("Hello world")

--在写代码时经常需要调用CS.UnityEngine里面的函数,为了方便我们可以定义一个变量将其保存起来
--使用local关键字定义一个局部变量 下面代码实现的效果与上面相同
local cu = CS.UnityEngine
cs.Debug.Log("Hello world")

--调用其他方法、字段也与之类似,例如
--print(cu.Time.deltaTime)

要执行这行代码,我们创建一个C#脚本,并执行Lua文件

lua.DoString("require 'LuaDemo2'");  //打印Hello world

 

XLua访问自定义的C#类

在C#中定义一个名为People的类,内容如下:

public class People
{
   public string name;
   public int age;

   public void Show()
  {
       Debug.Log(name + ":" + age);
  }
}

接下来在XLua中对其进行访问

--找到People类并对其进行实例化,等价于:
--local people = CS.People &......

原文转载:http://www.shaoqun.com/a/888730.html

跨境电商:https://www.ikjzd.com/

万国邮政联盟:https://www.ikjzd.com/w/861

kk馆:https://www.ikjzd.com/w/1713

欧麦:https://www.ikjzd.com/w/2085


XLua简介Xlua是腾讯研发的一款Lua开源插件,为Unity、.Net、Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用,在游戏中,该技术多用于热更新。可以在GitHub上搜索XLua进行下载,如果网速太慢,也可以在gitee上下载[gitee链接]https://gitee.com/mirrors/xlua?utm_source=alading
moss:https://www.ikjzd.com/w/1653
世界之窗元旦有倒数吗?夜场门票是多少?_世界之窗旅游攻略:http://www.30bags.com/a/428052.html
世界之窗元宵节烟花秀时间?深圳世界之窗烟花秀几点开始?:http://www.30bags.com/a/431462.html
世界之窗元宵节有表演吗?深圳世界之窗元宵节演出时间?:http://www.30bags.com/a/431461.html
世界之窗最近有什么优惠活动吗?:http://www.30bags.com/a/397226.html
被两个男人夹在中间玩 一前一后两个撑坏了:http://lady.shaoqun.com/a/248029.html
少妇口述:好色男邻居趁老公出差跟我一夜情:http://lady.shaoqun.com/m/a/70312.html
婚外性导师 她趴着张开双腿让我进入(2/2):http://lady.shaoqun.com/m/a/43840.html
南部满福水世界门票2021年7月价格:http://www.30bags.com/a/513891.html
老婆和租客在厕所做不可说的事,老公要离婚!妻子:修理水管:http://lady.shaoqun.com/a/426297.html
印度公开拍卖女孩的"初夜",便宜免费玩,可耻:http://lady.shaoqun.com/a/426298.html
女床这个小习惯不好说,但是有七大健康好处!:http://lady.shaoqun.com/a/426299.html

没有评论:

发表评论