XLua C#调用Lua的全局变量、table、函数

//C# 调用Lua
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

//自定义委托(多个返回数值的函数)
//自定义委托(使用out关键字)
[CSharpCallLua]
public delegate void delAddingMutilReturn(int num1, int num2, out int res1, out int res2, out int res3);
//定义ref 关键字的委托
[CSharpCallLua]
public delegate void delAddingMutilRetRef(ref int num1, ref int num2, out int result);


public class XLuaCallTest : MonoBehaviour {

	//XLua的环境核心类(官方建议全局唯一)
	LuaEnv env = null;

	//自定义委托
	public delegate void delAdding(int num1, int num2);
	Action act = null;
	delAdding act2 = null;
	//注意: 以下两种委托定义,需要配置文件支持。
 	 Action act3 = null; //3个参数,没有返回值
	 Func act4 = null; //第一个int是返回值,后面2个是参数

	//委托声明
	delAddingMutilReturn act5 = null;
	delAddingMutilRetRef act6 = null;

	void Start () {

		env = new LuaEnv();
		env.DoString("require 'CsharpCallLua'");
		//c# 调用Lua
		//获取一个全局基本数据类型
		string str1= env.Global.Get("str");
		int num = env.Global.Get("number");
		float floNumber = env.Global.Get("floNumber");
		bool booFirstTime = env.Global.Get("IsFisrtTime");
		//测试结果
		Debug.Log("str1=" + str1);
		Debug.Log("num=" + num);
		Debug.Log("floNumber=" + floNumber);
		Debug.Log("booFirstTime=" + booFirstTime);

		//------------------------
		//访问一个全局table
		//方式1: 把table内容映射到普通class或struct,这个过程是值拷贝
		  //c#修改变量的值,Lua那边的值不变,修改Lua变量的值,c#这边的值也不变
		//gameLanguage表名 不要写错
		GameLanguage gameLan=env.Global.Get("gameLanguage");

		//输出
		Debug.Log("gameLan.str1=" + gameLan.str1);
		Debug.Log("gameLan.str1=" + gameLan.str2);
		Debug.Log("gameLan.str1=" + gameLan.str3);
		Debug.Log("gameLan.str1=" + gameLan.str4);

		Debug.Log("-------------------" );
		//方式2: 映射到一个interface (推荐方式)
		// 通过interface映射lua中的表,是一种引用拷贝。
		//接口需要添加特性标签[CSharpCallLua],否则无法生成实例代码
        //需要生成代码,在unity编辑器菜单 XLua - Generate Code
	   //得到lua中的表信息
	   IGameLanguage IgameLan = env.Global.Get("gameLanguage");
		//输出显示
		Debug.Log("[使用接口]gameLan.str1=" + IgameLan.str1);
		Debug.Log("[使用接口]gameLan.str2=" + IgameLan.str2);
		Debug.Log("[使用接口]gameLan.str3=" + IgameLan.str3);
		Debug.Log("[使用接口]gameLan.str4=" + IgameLan.str4);
		//演示接口的引用拷贝原理
		IgameLan.str1 = "我是修改后的内容";
		env.DoString("print('修改后gameLanguage.str1='..gameLanguage.str1)");
		//调用复杂的table
		//得到lua中的表信息
		IGameUser gameUser = env.Global.Get("gameUser");
		//输出显示
		Debug.Log("[使用接口]gameLan.ID=" + gameUser.ID);
		Debug.Log("[使用接口]gameLan.Name=" + gameUser.name);
		Debug.Log("[使用接口]gameLan.Age=" + gameUser.age);

		//输出调用方法
		gameUser.Speak();
		gameUser.Walking();
		int tmpResult = gameUser.Calulation(100, 200);
		Debug.Log("经过lua中计算,结果= " + tmpResult);

		Debug.Log("-------------------");
		//方式3: by value方式:映射到Dictionary<>,List<> (适合用在Lua简单表,无法用在复杂表)
		//映射到Dictionary
		Dictionary dicGameLan=env.Global.Get>("gameLanguage"); //gameLanguage 简单表
		foreach(string key in dicGameLan.Keys)
		{
			Debug.Log("Dic数据 key="+ key+" value= " + dicGameLan[key]);
			
		}

		//映射到list
		List ListLan = env.Global.Get>("programLanguage");
		foreach (string item in ListLan)
		{
			Debug.Log("programLanguageitem=" + item);
		}
		Debug.Log("-------------------");
		//方式4: by ref方式,映射到LuaTable类。(适合用在一些较为复杂且使用频率很
		//低的情况下,一般不推荐使用,因为效率低)
		XLua.LuaTable tabGameUser = env.Global.Get("gameUser");
		//输出显示
		Debug.Log("name=" + tabGameUser.Get("name"));
		Debug.Log("Age=" + tabGameUser.Get("age"));
		Debug.Log("ID=" + tabGameUser.Get("ID"));

		//输出表中函数
		XLua.LuaFunction funSpeak = tabGameUser.Get("Speak");
		funSpeak.Call();
		XLua.LuaFunction funWalking = tabGameUser.Get("Walking");
		funWalking.Call();

		XLua.LuaFunction funCalulation = tabGameUser.Get("Calulation");
		object[] objArray = funCalulation.Call(tabGameUser, 10, 20);
		Debug.Log("输出结果=" + objArray[0]);//输出结果: 70

		Debug.Log("-------------------");
	//-----------------------
	//访问一个全局的function
	//方式1: 映射到delegate [* 推荐方式]
	//注意: 
	//A: 含有out与ref关键字委托也需要添加特性标签[CSharpCallLua]
	//B: 委托引用后,退出luaEnv前,需要释放委托引用,否则lua报错! 
	//C: 对于Unity与C#中的复杂类型API,必须加入Xlua的配置文件,经过生
	//成代码后才能正确应用。 例如:Action 、 Func 等

		//得到lua中的函数信息(通过委托来进行映射)
		act = env.Global.Get("ProcMyFunc1"); //没有参数,没有返回值
         act.Invoke();		   //调用
		 //使用自定义委托调用具备两个输入参数的lua中的函数
		 //这里要在菜单上XLua-GenerateCode
		act2 = env.Global.Get("ProcMyFunc2");
		act2(50, 60);
		//定义三个输入参数的委托。
		//需要配置文件,文件路径在Assets/XLua/Examples/ExampleGenConfig.cs
		// 在CSharpCallLua里面写入  typeof(Action),
		//还要在菜单上XLua-GenerateCode
		act3 = env.Global.Get>("ProcMyFunc4");
		act3(20, 30, 40);

		//定义具备返回数值,两个输入数值的委托
        // Func 第一个int是返回类型
		//Func 要加入配置文件ExampleGenConfig
		//还要在菜单上XLua-GenerateCode
		act4 = env.Global.Get>("ProcMyFunc3");
		int intResult = act4(60, 40);

		//调用Lua多个返回值的函数
		//得到lua中的具有多个返回数值的函数(通过委托out关键字来进行映射)
		//要在菜单上XLua-GenerateCode
		act5 = env.Global.Get("ProcMyFunc5");
		//输出返回结果
		int intOutRes1 = 0;
		int intOutRes2 = 0;
		int intOutRes3 = 0;
		act5(100, 880,out intOutRes1, out intOutRes2, out intOutRes3);
		Debug.Log(string.Format("res1={0},res2={1},res3={2}", intOutRes1, intOutRes2, intOutRes3));
		//得到lua中的具有多个返回数值的函数(通过委托ref关键字来进行映射)
		//要在菜单上XLua-GenerateCode
		act6 = env.Global.Get("ProcMyFunc5");

		//输出返回结果
		int intNum1 = 20;
		int intNum2 = 30;
		int intResult2 = 0;

		act6(ref intNum1, ref intNum2, out intResult2);
		Debug.Log(string.Format("使用ref关键字,测试多输出 res1={0},res2={1},res3={2}", intNum1, intNum2, intResult2));




		//方式2: 映射到LuaFunction (无需生成代码,性能不高)

		//得到lua中的函数信息(通过LuaFunction来进行映射)
		LuaFunction luaFun = env.Global.Get("ProcMyFunc1");
		LuaFunction luaFun2 = env.Global.Get("ProcMyFunc2");
		LuaFunction luaFun3 = env.Global.Get("ProcMyFunc3");
		//调用具有多返回数值。
		LuaFunction luaFun4 = env.Global.Get("ProcMyFunc5");

		//输出
		luaFun.Call();
		luaFun2.Call(10, 20);
		object[] objArray2=luaFun3.Call(30, 40);
		Debug.Log("调用ProcMyFunc3 ,结果="+ objArray2[0]);
		object[] objArray3= luaFun4.Call(22, 80);   //多返回数值。
		Debug.Log(string.Format("测试多返回数值 res1={0},res2={1},res3={2}", objArray3[0], objArray3[1], objArray3[2]));


	}

	void OnDestory()
	{
		act = null;
		act2 = null;
		act3 = null;
		act4 = null;


		//释放LuaEnv
		env.Dispose();
	}

	public class GameLanguage
	{
		public string str1;
		public string str2;
		public string str3;
		public string str4;
	}

	//定义接口
	[CSharpCallLua]
	public interface IGameLanguage
	{
		string str1 { get; set; }
		string str2 { get; set; }
		string str3 { get; set; }
		string str4 { get; set; }
	}


	//定义接口
	[CSharpCallLua]
	public interface IGameUser
	{
		string name { get; set; }
		int age { get; set; }
		string ID { get; set; }

		void Speak();
		void Walking();
		int Calulation(int num1, int num2);

	}



}

 

Lua文件

CsharpCallLua.lua.txt

--测试Csharp 调用lua
--定义全局变量
str="全局变量"
number=10
local num=20  --测试是否可以调用local 的局部变量
floNumber=88.8
IsFisrtTime=true 

--定义一个简单表
gameLanguage={str1="C#语言",str2="lua语言",str3="C++语言",str4="C语言"}

--定义一个综合表(lua中的OOP思想)
gameUser={
	name="cuiyong",
	age=40,
	ID="18011112222",

	Speak=function()
		print("lua玩家在讨论中")
	end,

	Walking=function()
		print("lua玩家在健身中")
	end,
						--C#调用Lua的函数时,函数有一个隐藏参数,指向自身
	Calulation=function(age,num1,num2)--说明:age 这里命名可以任意,表示当前对象(即:gameUser)
		return age.age+num1+num2
	end
}

--定义更简单的表
programLanguage={"C#","lua","C++","C"}

--定义单独的lua函数
function ProcMyFunc1()
	print("procMyFunc1 无参函数")
end

function ProcMyFunc2(num1,num2)
	print("procMyFunc1 两个函数 num1+num2="..num1+num2)
end

function ProcMyFunc3(num1,num2)
	print("procMyFunc1 具备返回数值的函数")
	return num1+num2
end

function ProcMyFunc4(num1,num2,num3)
	print("procMyFunc4 两个函数 num1+num2+num3="..num1+num2+num3)
end

--定义具有多个返回数值的函数
function ProcMyFunc5(num1,num2)
	local result=num1+num2
	print("ProcMyFunc5 函数,具备返回多个数值")

	return num1,num2,result
end

 

你可能感兴趣的:(unity)