xlua用法 c#调用lua脚本

C# 调用 lua

脚本基本的结构

c#脚本
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using XLua;
using System;
using System.IO;

namespace XLuaTest1
{
    [CSharpCallLua]
    public class mTable{
        public string name;
        public int value;
    }

    [LuaCallCSharp]
    public class LuaTest : MonoBehaviour
    {
        // lua虚拟机,建议全局1个
        internal static LuaEnv luaEnv = new LuaEnv(); //all lua behaviour shared one luaenv only!
        // 用于处理gc
        internal static float lastGCTime = 0;
        internal const float GCInterval = 1;//1 second 
        
        private LuaTable scriptEnv;

        // lua虚拟机与unity相杜英的三个生命周期
        private Action luaStart;
        private Action luaUpdate;
        private Action luaOnDestroy;

        void Awake()
        {
            //初始化全局表
            scriptEnv = luaEnv.NewTable();
            // 为每个脚本设置一个独立的环境,可一定程度上防止脚本间全局变量、函数冲突
            // 初始化本地表
            LuaTable meta = luaEnv.NewTable();
            // 把lua化境交给本地表
            meta.Set("__index", luaEnv.Global);
            // 将本地表作为元表,给全局表
            scriptEnv.SetMetaTable(meta);
            //释放本地表
            meta.Dispose();

            //------------------------运行脚本
            luaEnv.DoString("print(888)");
            //绑定lua秀吉的生命周期
            Action luaAwake = scriptEnv.Get<Action>("awake");
            scriptEnv.Get("start", out luaStart);
            scriptEnv.Get("update", out luaUpdate);
            scriptEnv.Get("ondestroy", out luaOnDestroy);

            if (luaAwake != null)
            {
                luaAwake();
            }
        }

        // Use this for initialization
        void Start()
        {
            //虚拟机启动后触发
            if (luaStart != null)
            {
                luaStart();
            }
        }

        // Update is called once per frame
        void Update()
        {
            //lua脚本跟随mono每帧执行
            if (luaUpdate != null)
            {
                luaUpdate();
            }
            //gc相关.清除Lua的未手动释放的LuaBase对象(比如:LuaTable, LuaFunction),以及其它一些事情。
            if (Time.time - LuaTest.lastGCTime > GCInterval)
            {
                luaEnv.Tick();
                LuaTest.lastGCTime = Time.time;
            }
        }

        void OnDestroy()
        {
            // 触发销毁相关动作
            if (luaOnDestroy != null)
            {
                luaOnDestroy();
            }
            // 释放lua相关内存
            luaOnDestroy = null;
            luaUpdate = null;
            luaStart = null;
            scriptEnv.Dispose();
        }
    }
}
lua脚本
-- unity脚本启动时调用的方法
function start()
    print("lua start...")
end
-- 销毁时调用
function ondestroy()
    print("lua destroy")
end

c# 调用lua脚本的三种方法

【直接运行代码】

luaEnv.DoString("print(888)");

【运行Resources目录下的lua脚本】

// 直读 Assets/Resources下的lua脚本。比如脚本是test.lua.txt,输入脚本名忽略扩展名txt,即test.lua。 
TextAsset luaScript = Resources.Load<TextAsset>("lua.lua") as TextAsset;
luaEnv.DoString(luaScript.text, "", scriptEnv);

【运行任意目录下的lua脚本】

void Start(){
	//....lua虚拟机初始化等等....//
	//加载脚本loader
	luaEnv.AddLoader(LuaTxtLoader);
	//传入脚本路径并执行脚本
	luaEnv.DoString("require 'Resources/lua.lua.txt'");
	// 脚本loader 用于访问任意目录
}
private byte[] LuaTxtLoader(ref string filePath)
{
    string luaPath = Application.dataPath + "/" + filePath;
    string strLuaContent = File.ReadAllText(luaPath);
    byte[] result = System.Text.Encoding.UTF8.GetBytes(strLuaContent);
    return result;
}  

c#调用lua脚本中的变量

【调用脚本的全局变量】

【c#代码】

// 第二种调用脚本方法 运行Resources下的脚本
TextAsset luaScript = Resources.Load<TextAsset>("lua.lua") as TextAsset;
luaEnv.DoString(luaScript.text, "", scriptEnv);
//获取脚本中的全局变量
int mInt = scriptEnv.Get<int>("gloableInt");
Debug.Log("int from lua script:"+mInt);

【lua代码】

-- 全局变量
gloableInt = 23

调用脚本table中的数据

【lua代码】

-- 全局变量
mTable = {
    name = "number",
    value = 3
}
mTable1 = {"苍井空", "小泽玛利亚"}

【c#代码:用类映射读取】

//为了调用lua table必须在c#创建相应的结构
public class mTable{
    public string name;
    public int value;
}
public class luaTest:MonoBehaviour{
	void Start(){
			// 用mTable类 映射lua脚本的同结构table
            mTable mtable = scriptEnv.Get<mTable>("mTable");
            Debug.Log("int from lua script:" + mtable.name);
	}
}

【c#代码:用Dictionary 映射键值对数据】

	void Start(){
            // 用Dictionary 映射键值对数据
            Dictionary<string, object> dic = luaEnv.Global.Get<Dictionary<string,object>>("mTable");
            foreach (string item in dic.Keys)
            {
                print(item + " " + dic[item]);
            }
	}

【c#代码:用list映射没有key的table数据】

	void Start(){
            List<object> list = luaEnv.Global.Get<List<object>>("mTable1");
            foreach (var item in list)
            {
                print(item);
            }
	}

【c#代码:用LuaTable映射没有key的table数据】

	void Start(){
            // 使用LuaTable类映射
            LuaTable luaTable = luaEnv.Global.Get<LuaTable>("mTable");
            print(luaTable.Get<string>("name"));
	}

c# 调用lua脚本中的函数

没有参数的全局函数

【c# 代码】

// 用Action接受函数
Action act1 = luaEnv.Global.Get<Action>("func");
// 执行
act1();
// 用完了必须注销,否则无法gc
act1 = null;

【lua 代码】

function func()
    print("func");
end

带参数和返回值的全局函数

修改带有【CSharpCallLua】标签的代码后,必须生成xlua代码,否则会发生InvalidCastException的报错
步骤:点击unity工具栏 > xLua > Generate Code
【c# 代码】

// 定义委托 并添加编译标签
[CSharpCallLua]
public delegate int Add(int a, int b);

// 执行委托
Add add = scriptEnv.Get<Add>("add");
Debug.Log("有参的方法返回值:" + add(3, 9)); 
//用完必须注销
add = null;

【lua 代码】

function add(a,b)
    print('luaadd:',a+b);
    return a+b;
end

有多个返回值的全局函数(ref or out)

修改带有【CSharpCallLua】标签的代码后,必须生成xlua代码,否则会发生InvalidCastException的报错
步骤:点击unity工具栏 > xLua > Generate Code
【c# 代码】

// 定义委托 并添加编译标签
// lua代码中的方法有2个参数,4个返回值。在c#中声明时都要转成参数。包括2个普通参数,4个out/ref参数
[CSharpCallLua]
public delegate void Add(int x, int y, out int a, out int b, out string s, out int c);

// 获取脚本中的函数
Add add = scriptEnv.Get<Add>("add");
//声明返回变量
int a,b,c;string s;
//执行方法,输入两个参数,返回4个值
add(3, 9, out a, out b, out s, out c) ;
Debug.Log("有参的方法返回值:" + a + "-" + b + "-" + s + "-" + c); 
//必须注销,否则无法gc
add = null;

【lua 代码】

--输入2参数,返回4参数  ,在c#的委托中都要处理成输入参数。
function add(a,b)
    print('luaadd:',a+b);
    return 9,6,'结果:',a+b;
end
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千年奇葩

从来没受过打赏,这玩意好吃吗?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值