1、作者教程:http://www.gad.qq.com/article/detail/24967
2、GitHub地址:https://github.com/Tencent/xLua 下载之后只需要把Plugins、XLua两个文件夹导入到Unity3D的Assets目录下就可以了。可以按照XLua文件夹下的XLua教程进行学习(如下图)
001-利用XLua在控制台输出Hello world
/*
*Title:"XLua学习"项目开发
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua; //引入xLua命名空间
public class HelloWorld : MonoBehaviour {
private LuaEnv _luaenv; //推荐全局唯一
void Start () {
_luaenv = new LuaEnv(); //Lua运行环境
//_luaenv.DoString("print('Hello world')"); //执行字符串形式的Lua代码
_luaenv.DoString("CS.UnityEngine.Debug.Log('Hello world')"); //调用C#的Api
}
private void OnDestroy()
{
_luaenv.Dispose(); //释放lua运行环境
}
}
在Resources文件夹下新建一个Lua文件。如:HelloWorld.lua.txt(由于用Resources.Load
/*
*Title:"XLua学习"项目开发
*
*Description:
* 用于场景002
* 读取Lua文件来执行Lua代码
*Date:2017
*
*Version:0.1
*
*Modify Recoder:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public class HelloWorldByFile : MonoBehaviour {
LuaEnv _luaEnv;
// Use this for initialization
void Start () {
_luaEnv = new LuaEnv();
//方法1
//TextAsset ta = Resources.Load("HelloWorld.lua");//后缀自动添加.txt,因为是TextAsset类型
//_luaEnv.DoString(ta.text); //读取文本的字符串并运行
//方法2 用xLua自带的Loader加载和执行
_luaEnv.DoString("require 'HelloWorld'"); //HelloWorld相当于HelloWorld.lua.txt,XLua的Loader会自动在Resources目录下加载
}
void OnDestroy()
{
_luaEnv.Dispose();
}
}
003-自定义Loader,读取其他目录下的Lua文件
/*
*Title:"XLua学习"项目开发
*
*Description:
* 自定义Loader(加载器)
*
*Date:2017
*
*Version:0.1
*
*Modify Recoder:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System.IO;
public class DefineLoader : MonoBehaviour {
private LuaEnv _luaEnv;
// Use this for initialization
void Start () {
_luaEnv = new LuaEnv();
_luaEnv.AddLoader(MyLoader); //增加一个Loader
_luaEnv.DoString("require 'DefineLoaderTest'");
}
//通过require加载一个文件的时候,会访问每一个Loader(先访问自定义的Loader后内置Loader)直到返回的不为空
private byte[] MyLoader(ref string filePath)
{
Debug.Log(filePath); //这里filePath为DefineLoaderTest
string absPath = Application.streamingAssetsPath + "/" + filePath + ".lua.txt"; //获取文件所在目录
//把lua文件里面的字符串转换成字节数组返回,lua文件如果有中文需要把编码改为UTF8
return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));
}
void OnDestroy()
{
_luaEnv.Dispose();
}
}
CSharpCallLua(lua代码):
intA = 100
floB = 0.52
isRun = true
strName = 'Happy'
person = {
name = 'Jackey',age = 20,3,4.5,true,"stringgg",
eat = function(self,foodName) --self代表当前对象,比C#对应的对象多一个参数
print("正在吃:"..foodName)
end
}
--[其他方式
function person:eat(foodName) --用:的方式,会自动添加self
print("正在吃:"..foodName)
end
function person.eat(self,foodName) --用.的方式,要自行添加
print("正在吃:"..foodName)
end
--]
function add(a,b) --全局函数
print(a+b)
return a+b,a,b
end
C#代码:
/*
*Title:"XLua学习"项目开发
*
*Description:
* C#访问Lua里面的全局变量
*
*Date:2017
*
*Version:0.1
*
*Modify Recoder:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System;
public class CSharpCallLua : MonoBehaviour {
private LuaEnv _env;
// Use this for initialization
void Start () {
_env = new LuaEnv();
_env.DoString("require 'CSharpCallLua'"); //加载并执行lua文件
/*获取基本变量*/
int intA = _env.Global.Get("intA"); //获取Lua里面Int类型的全局变量
Debug.Log(intA);
float floB = _env.Global.Get("floB"); //获取Lua里面float类型的全局变量
Debug.Log(floB);
bool isRun = _env.Global.Get("isRun"); //获取Lua里面bool类型的全局变量
Debug.Log(isRun);
string strName = _env.Global.Get("strName"); //获取Lua里面string类型的全局变量
Debug.Log(strName);
/*获取table的方式一,通过类Class(Struct)*/
Person p = _env.Global.Get("person"); //值拷贝,C#修改数据并不会同步到Lua,Lua修改也不影响C#
Debug.Log(p.name);
Debug.Log(p.age);
/*获取table的方式二,通过接口interface(推荐)*/
IPerson ip = _env.Global.Get("person"); //传引用,在C#修改会影响Lua里面的变量
Debug.Log(ip.name);
Debug.Log(ip.age);
ip.eat("鸡腿"); //相当于ip.eat(ip,"鸡腿");
/*获取table的方式三,通过键值对Dictionary、集合List(推荐)*/
//Dictionary--只能映射table里面有键的元素
Dictionary dict = _env.Global.Get>("person");
foreach (string key in dict.Keys)
{
Debug.Log(key + '-' + dict[key]);
}
//List--只能映射table里面没有键的元素
List
005-通过lua代码访问C#
LuaCallCSharp(lua代码):
CS.UnityEngine.GameObject("new by lua") --创建游戏物体(new对象)
print(CS.UnityEngine.Time.deltaTime) --访问C#静态属性
CS.UnityEngine.Time.timeScale = 0.5 --设置C#中的属性
local camera = CS.UnityEngine.GameObject.Find('Main Camera') --用局部变量保存C#中的对象
camera.name = "update by lua" --修改对象名称
local gameObject = CS.UnityEngine.GameObject --用局部变量进行引用,可以节省性能,以及减少编码量
local light = gameObject.Find('Directional Light')
light.name = 'new light name'
local cameraCam = camera:GetComponent('Camera') --获取Camera上的组件。推荐使用冒号调用成员函数,如果用点的话,第一个参数需要是当前对象
gameObject.Destroy(cameraCam) --移除这个组件
C#代码:
/*
*Title:"XLua学习"项目开发
*
*Description:
* 在lua里访问C#
*
*Date:2017
*
*Version:0.1
*
*Modify Recoder:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public class LuaCallCSharp : MonoBehaviour {
private LuaEnv _env;
// Use this for initialization
void Start()
{
_env = new LuaEnv();
_env.DoString("require 'LuaCallCSharp'"); //加载并执行lua文件
}
void OnDestroy()
{
_env.Dispose();
}
}
Lua调用侧的参数处理规则:C#普通参数算一个输入形参,ref修饰的算一个输入形参,out不算,然后从左往右对应lua调用侧的实参列表。
Lua调用侧的返回值处理规则:C#函数的返回值(如果有的话)算一个返回值,out 算一个返回值,ref算一个返回值,然后从左往右对应lua的多返回值。
007-特性[LuaCallCSharp]和[CSharpCallLua]
在Lua获取或者调用C#的时候用[LuaCallCSharp]
在C#获取或者调用Lua的时候用[CSharpCallLua]
在枚举,委托,接口等前面加上[CSharpCallLua]或者[LuaCallCSharp]
008-lua中相当于C#中+=或-=的事件注册
例如testobj里有一个事件:public event Action TestEvent;
增加事件回调:testobj:TestEvent('+',lua_evnet_callback)
移除事件回调:testobj:TestEvent('-',lua_event_callback)