xlua框架解析以及demo展示(一)主要是加载lua文件,c#调用lua代码的各种方式

(一)先下载xlua的源码
地址:https://github.com/Tencent/xLua
下载好了源码之后把源码中的两个文件夹导入工程
在这里插入图片描述
(二)hello world
注意:lua虚拟机对象建议全局只有一个。

using UnityEngine;
using XLua;//使用这个要框架一定要引入命名空间

public class HelloWorld : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();//xlua是在虚拟机上运行的,所以要有虚拟机对象
        luaEnv.DoString("print('my first xlua print hello world')");//利用dostring执行lua代码
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

(三)读取和执行lua文件
三种方式:第一种以文本资源方式读取
新建lua脚本,扩展名如图所示
在这里插入图片描述
该脚本里面就一句输出语句
然后我们在c#脚本里用文本资源读取的方式执行该文件,代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

public class LuaFileDemo : MonoBehaviour
{
    public TextAsset luaTextAsset;
    // Start is called before the first frame update
    void Start()
    {
        string luastring = luaTextAsset.text;//读取文本里的lua语句
        LuaEnv luaEnv = new LuaEnv();//lua虚拟机环境
        luaEnv.DoString(luastring);//执行txt文件里的lua语句
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

第二种方式;用require直接引用文件名,这种方式是系统自带的加载器方式
首先引用的lua文件要在Resources文件夹下,不然找不到,这里是放到了resources的子文件夹下(不过不建议这么做,因为如果后面加txt扩展名的时候,即使用全路径也会报错找不到,而且用.lua.txt的扩展名也能让人很方便的看出这就是lua文件)
代码如下
这里的lua是:luaFile.lua

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

public class LuaFileDemo : MonoBehaviour
{
    
    // Start is called before the first frame update
    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();
        //ps:如果这里用luafile找不到文件的话,就使用全路径,从assets下开始的那种
        //luaFile是lua文件的名字,这里可以直接用lua扩展名,而不需要lua.txt
        luaEnv.DoString("require'Assets/Resources/luaFileDemo/luaFile'");
        //这种方式是系统的加载器自带的加载方式
        

    }

    
}

第三种,自定义加载器
这里用的lua文件是直接放在resources文件夹下的, 且文件是luaFile.lua.txt
第三种自定义加载器更商业化的做法

public class CustomerLoader : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();
        //里面是自定义加载器

        luaEnv.AddLoader(MyCustomLoader);
        //如果有自定义加载器,就先去找自定义加载器,然后再执行lua语句,没有自定义加载器,就用系统默认的
        //吐槽:也是奇怪了,带luaFile.lua.txt,只能直接放到resources下,不能放到resources的文件夹下,不然怎么样都识别不到?
        luaEnv.DoString("require 'luaFile'");
    }

    public byte[] MyCustomLoader(ref string filepath)
    {
        Debug.Log(filepath);//注意这里打印出来的是luaFile,文件路径,源码里string定义的也是filepath
        //来做个判断,如果找的到这个文件路径就返回文件的byte[],没有就返回空的字符串转化成的byte[]
        //这样的好处是即使没有这个文件也不会报错
        //因为resources不支持多个扩展名,所以要加上.lua
        string path = filepath + ".lua";
        TextAsset textAsset = Resources.Load(path) as TextAsset;
        if (textAsset == null)
        {
            
          //注意,这里要写成lua语句,直接写中文,是读不成lua语句的
            return System.Text.Encoding.UTF8.GetBytes("print('文件未找到')");
        }
        else
        {
            return System.Text.Encoding.UTF8.GetBytes(textAsset.text);
        }

    }


}

玄学可以参考这篇文章,也讲了三种加载方式

(四)如何用c#调用lua文件里的内容,如变量
代码如下
注意:如果再c#代码中修改了nu1的值,是不会影响到lua文件里的num1的值的

public class CCallLuaVarDemo : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();
        luaEnv.DoString("require'luaFile'");
        //从加载的lua脚本中读取num1的值
        int nu1 = luaEnv.Global.Get<int>("num1");
        print(nu1);
    }

   
}

(五)在c#中修改lua文件里的内容,如变量
代码如下

public class CCallLuaVarDemo : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();
        luaEnv.DoString("require'luaFile'");
        //从加载的lua脚本中读取num1的值
        int nu1 = luaEnv.Global.Get<int>("num1");//这里nu1的值还是10
        //修改lua文件里num1的值
        luaEnv.Global.Set<string, int>("num1", 1);
        //输出修改后lua文件里的变量num1的值
        luaEnv.DoString("print('num1')");

         
    }
 
}

注意,如果有过个虚拟机都对lua文件里的num1操作,输出的值是相互独立,互不影响的。所以建立全局只有一个lua虚拟机对象。
(六)c#中的类与lua文件中table的映射
可以参考这篇文章:关于表的映射
lua脚本里这样写

print("Hello This is a lua file")

--lua文件里建立的各种类型不同的变量
num1=10
str1="this is lua string "
table1={
    name="root",
    age=1,
    13,
    f=function()
        print("this is lua function")
    end,
    
    "red","blue","yellow",
    }

c#映射表中键值对的代码:

public class CSCallLuaTable : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();
        luaEnv.DoString("require 'luaFile'");
        //操作表中的键值对
        //输出lua文件中表table中的name:“root”,age:1
        //这里是lua文件中的的table1表映射到TableTemp类对象上
        TableTemp t = luaEnv.Global.Get<TableTemp>("table1");
        Debug.Log(t.name);
        Debug.Log(t.age);
        //注意这里即使把t.name赋值成了其它的值,也不会影响到table1里本身的name的值 ,即是深拷贝
    }

}

//新建一个类来专门映射lua文件中的表
public class TableTemp
{
    //用来映射lua文件中表table1中的name:“root”,age:1
    //注意这里都要是public不然不好在别的类使用
    //这里的变量名都要和表中一一对应
    public string name;
    public string age;
}

(七)利用c#中的接口使用table中的函数
科普一下:lua中self,点号,冒号的关系
游戏开发unity xlua框架知识系列:This type must add to CSharpCallLua报错解决方式
lua中的代码

print("Hello This is a lua file")

--lua文件里建立的各种类型不同的变量
num1=10
str1="this is lua string "
table1={
    name="root",
    age=1,
    13,
    f=function()
        print("this is lua function")
    end,
    
    "red","blue","yellow",
    }

function table1.fun1(self)
    print(self.age,self.name)
end

function table1:fun3(num1,num3)
    print(self.age,self.name)
    print(num1+num3)
end

c#中的代码

using UnityEngine;
using XLua;

public class CSCallLuaTableFunciton : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();
        luaEnv.DoString("require 'luaFile'");
        TableTemp t = luaEnv.Global.Get<TableTemp>("table1");
        t.fun1();
        t.f();
        t.fun3(1, 3);
        t.name = "ncount";//注意这里在c#中更改了lua中的name,和之前不一样是浅拷贝。
        luaEnv.DoString("print(table1.name)");//但是打开文件似乎还是root?
        print(t.name);//这里打印出来也是ncount
       
      
    }

    //用c#中的接口对应lua中的table
    //c#调用lua中的table要加下面这个标记
    [CSharpCallLua]
    public interface TableTemp
    {
        //接口中没有字段,所以用属性
         string name { set; get; }
         string age { set; get; }
        //对应函数中的三个方法
         void f();
         void fun1();
         void fun3(int x,int y);
    }

(八)Dictionary,list与table的映射
dictionary适合表中的键值对,包括函数
list适合没有键的
c#代码如下

public class CSCallLuaTableByDictionary : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();
        luaEnv.DoString("require 'luaFile'");
        //字典适合有键值对的表中对应
        Dictionary<string, object> dict1 = new Dictionary<string, object>();
        dict1 = luaEnv.Global.Get<Dictionary<string, object>>("table1");
        foreach(string key in dict1.Keys)
        {
            print(key + "," + dict1[key]);
            //这里打印的是table中的有键值对的内容,包括函数
            //具体打印的是:fun3,function :10 f function :12 name,root 这种类型的

        }
        //list适合没有键的表中对应
        //这里一个容易犯的的错误是,object是小写的,不是大写的
        List<object> list1 = new List<object>();
        list1 = luaEnv.Global.Get<List<object>>("table1");
        foreach(object o in list1)
        {
            Debug.Log(o.ToString());
        }
    }

  
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值