(一)c#调用lua里的公共函数
(1)调用lua中无参无返回值的全局函数
第一种方式,用c#中的Action来映射lua中没有参数,没有返回值的全局函数:
lua代码:
function funGlo1()
print("This is a global function in lua")
end
function funGlo3(x,y)
print(x+y)
return x+y
end
c#中的代码
using UnityEngine;
using XLua;
using System;//action时要用
public class CSCallLuaGlobalFunciton : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString("require 'luaFile'");
//action适合lua中没有参数,也没有返回值的全局函数
Action act = luaEnv.Global.Get<Action>("funGlo1");
act();
}
}
第二种方式,用自己定义的委托,映射lua中的无参数,无返回值的全局函数
lua代码同上
c#代码:
using UnityEngine;
using XLua;
using System;//action时要用
public class CSCallLuaGlobalFunciton : MonoBehaviour
{
//自己定义的delegat,映射lua中没有参数和返回值的全局函数,这里的delegate是小写
public delegate void MyDelegate1();
void Start()
{
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString("require 'luaFile'");
//用自己定义的delegat,映射lua中没有参数和返回值的全局函数
MyDelegate1 d = luaEnv.Global.Get<MyDelegate1>("funGlo1");
d();
}
}
(2)用自定义delegate调用lua中有参数和返回值的全局函数
c#代码
using UnityEngine;
using XLua;
using System;//action时要用
public class CSCallLuaGlobalFunciton : MonoBehaviour
{
//自己定义的delegate,映射lua中有参数有返回值的全局函数
[CSharpCallLua]//注意这种delegate要加标签
public delegate int MyDelegate3(int x,int y);
void Start()
{
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString("require 'luaFile'");
// //自己定义的delegate,映射lua中有参数有返回值的全局函数
MyDelegate3 d3= luaEnv.Global.Get<MyDelegate3>("funGlo3");
int result3 = d3(1, 3);
print(result3);
}
ps:这个加标签的情况可以xlua配置文件中改,在xlua例子文件夹中的examplegenconfig文件中修改注册。
(3)用自定义delegate,映射lua中有参数,有多个返回值的lua全局函数
lua代码:
function funGlo4(x,y)
return x*y,x*x,y*y
end
c#代码
using UnityEngine;
using XLua;
using System;//action时要用
public class CSCallLuaGlobalFunciton : MonoBehaviour
{
[CSharpCallLua]//还是要加标签
public delegate int MyDelegate4(int x, int y,out int result2,out int result3);
void Start()
{
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString("require 'luaFile'");
//自定义的delegate,映射lua中有参数,有多个返回值的全局函数
MyDelegate4 d4 = luaEnv.Global.Get<MyDelegate4>("funGlo4");
int result2=0;
int result3=0;
int result1 = d4(1, 3, out result2, out result3);
print(result1+","+result2+","+result3);
}
}
(二)lua调用c#
(1)简单的调用
格式都是: CS.命名空间.函数名
lua代码
--lua控制csharp
--CS.UnityEngine.Debug.Log("lua call csharp");--lua调用unity中的debug
--local go=CS.UnityEngine.GameObject();--lua创建游戏物体
--go.name="root"
--lua查找游戏对象,获取对象上的游戏组件
--一个小技巧,可以在c#中写好代码,再黏贴到lua文件中,修改好
--local go1=CS.UnityEngine.GameObject.Find("Directional Light")
--local light=go1:GetComponent("Light")
--CS.UnityEngine.GameObject.Destroy(light)
--lua加载游戏预制体
--local CSUnity=CS.UnityEngine
--local cubeprefab=CSUnity.Resources.Load("CubePrefab")
--local go2=CSUnity.GameObject.Instantiate(cubeprefab)
(2)lua实现uinty周期函数
科普:
描述:
代表lua全局环境的LuaTable
void Tick()
描述:
清除Lua的未手动释放的LuaBase(比如,LuaTable, LuaFunction),以及其它一些事情。
需要定期调用,比如在MonoBehaviour的Update中调用。
lua代码
print("lua call test")
function luaAwake()
print("This is luaAwake()")
end
function luaStart()
print("This is luaStart()")
end
function luaUpdate()
print("This is luaUpdate()")
end
function luaDestroy()
print("This is luaDestroy()")
end
c#代码
using UnityEngine;
using XLua;
using System;//action要用的命名空间
public class LuaCallStart : MonoBehaviour
{
public TextAsset luafile;
LuaTable runTable;
Action _luaStart;
Action _luaAwake;
Action _luaUpdate;
Action _luaDestroy;
LuaEnv luaEnv;
private void Awake()
{
luaEnv = new LuaEnv();
runTable=luaEnv.NewTable();
LuaTable metaTable = luaEnv.NewTable(); //这是一个元表
metaTable.Set("__index", luaEnv.Global);//让元表的查询全部指向文件中的公共变量
runTable.SetMetaTable(metaTable);//把元表放入普通表中
metaTable.Dispose();//可以销毁元表
//这句可以解释成这个文件的内容,包含在这个表里
luaEnv.DoString(luafile.text, "luaFile2.lua", runTable);//注意这里的写法有顺序,要先设置表,在来dostring
_luaAwake = runTable.Get<Action>("luaAwake");//可以用表来查找全局函数了,因为其元表指向了全局变量
_luaStart = runTable.Get<Action>("luaStart");
_luaUpdate = runTable.Get<Action>("luaUpdate");
_luaDestroy = runTable.Get<Action>("luaDestroy");
if (_luaAwake != null)
{
_luaAwake();
}
}
void Start()
{
if (_luaStart != null)
_luaStart();
}
// Update is called once per frame
private void Update()
{
luaEnv.Tick();
if (_luaUpdate != null)
_luaUpdate();
}
private void OnDestroy()
{
if (_luaDestroy != null)
_luaDestroy();
}
}
(3)lua实现this指针
举个例子:在lua脚本中实现物体旋转
场景设置
c#代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System;//action要用的命名空间
public class LuaCallStart : MonoBehaviour
{
public TextAsset luafile;
LuaTable runTable;
Action _luaStart;
Action _luaAwake;
Action _luaUpdate;
Action _luaDestroy;
// Start is called before the first frame update
LuaEnv luaEnv;
private void Awake()
{
luaEnv = new LuaEnv();
runTable=luaEnv.NewTable();
LuaTable metaTable = luaEnv.NewTable(); //这是一个元表
metaTable.Set("__index", luaEnv.Global);//让元表的查询全部指向文件中的公共变量
runTable.SetMetaTable(metaTable);//把元表放入普通表中
metaTable.Dispose();//可以销毁元表
//把当前对象的指针传到表中,方便lua调用
runTable.Set("self", this);
//这句可以解释成这个文件的内容,包含在这个表里
luaEnv.DoString(luafile.text, "luaFile2.lua", runTable);//注意这里的写法有顺序,要先设置表,在来dostring
_luaAwake = runTable.Get<Action>("luaAwake");//可以用表来查找全局函数了,因为其元表指向了全局变量
_luaStart = runTable.Get<Action>("luaStart");
_luaUpdate = runTable.Get<Action>("luaUpdate");
_luaDestroy = runTable.Get<Action>("luaDestroy");
if (_luaAwake != null)
{
_luaAwake();
}
else
{
Debug.Log("没有找到该函数");
}
}
void Start()
{
if (_luaStart != null)
_luaStart();
}
// Update is called once per frame
private void Update()
{
luaEnv.Tick();
if (_luaUpdate != null)
_luaUpdate();
}
private void OnDestroy()
{
if (_luaDestroy != null)
_luaDestroy();
else
{
Debug.Log("没有找到luadestroy");
}
}
}
lua脚本
--用全局变量代替命名空间
cc=CS.UnityEngine
print("lua call test")
function luaAwake()
print("This is luaAwake()")
end
function luaStart()
print("This is luaStart()")
end
function luaUpdate()
print("This is luaUpdate()")
--实现物体自转
local v=cc.Vector3.up*30.0*cc.Time.deltaTime
--这里要注意是冒号
self.transform:Rotate(v)
end
function luaDestroy()
print("This is luaDestroy()")
end
(4)lua操控游戏物体
流程:c#建立个类,有物体名字和游戏物体,然后将游戏物体放入list【类名】的列表中,然后以key,value的方式将游戏物体添加进lua的table里,再在lua文件中使用
场景布置
c#代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System;//action要用的命名空间
public class LuaCallStart : MonoBehaviour
{
public TextAsset luafile;
LuaTable runTable;
Action _luaStart;
Action _luaAwake;
Action _luaUpdate;
Action _luaDestroy;
//用来装游戏物体的list
public List<GameObjectsClass> goList;
// Start is called before the first frame update
LuaEnv luaEnv;
private void Awake()
{
luaEnv = new LuaEnv();
runTable=luaEnv.NewTable();
LuaTable metaTable = luaEnv.NewTable(); //这是一个元表
metaTable.Set("__index", luaEnv.Global);//让元表的查询全部指向文件中的公共变量
runTable.SetMetaTable(metaTable);//把元表放入普通表中
metaTable.Dispose();//可以销毁元表
//把当前对象的指针传到表中,方便lua调用
runTable.Set("self", this);
//把golist里的物体,添加到runTable表中
for(int i = 0; i < goList.Count; i++)
{
runTable.Set(goList[i].name, goList[i].go);
}
//这句可以解释成这个文件的内容,包含在这个表里
luaEnv.DoString(luafile.text, "luaFile2.lua", runTable);//注意这里的写法有顺序,要先设置表,在来dostring
_luaAwake = runTable.Get<Action>("luaAwake");//可以用表来查找全局函数了,因为其元表指向了全局变量
_luaStart = runTable.Get<Action>("luaStart");
_luaUpdate = runTable.Get<Action>("luaUpdate");
_luaDestroy = runTable.Get<Action>("luaDestroy");
if (_luaAwake != null)
{
_luaAwake();
}
else
{
Debug.Log("没有找到该函数");
}
}
void Start()
{
if (_luaStart != null)
_luaStart();
}
// Update is called once per frame
private void Update()
{
luaEnv.Tick();
if (_luaUpdate != null)
_luaUpdate();
}
private void OnDestroy()
{
if (_luaDestroy != null)
_luaDestroy();
else
{
Debug.Log("没有找到luadestroy");
}
}
}
[Serializable]//序列化
//用来装游戏物体的类
public class GameObjectsClass
{
public string name;
public GameObject go;
}
lua代码
cc=CS.UnityEngine
print("lua call test")
function luaAwake()
print("This is luaAwake()")
end
function luaStart()
print("This is luaStart()")
end
function luaUpdate()
print("This is luaUpdate()")
--实现物体自转
local v=cc.Vector3.up*30.0*cc.Time.deltaTime
self.transform:Rotate(v)
--这里的名字要和设置进runtable表里的一致
A1.transform.position=cc.Vector3(5,5,5)
D1.transform.position=cc.Vector3(10,10,10)
end
function luaDestroy()
print("This is luaDestroy()")
end
(5)lua控制ui事件
场景布置
ps:这个脚本挂在button组件下,所以this指向的事button
lua代码
cc=CS.UnityEngine
print("lua call test")
--控制button组件以及inputfield组件
self:GetComponent("Button").onClick:AddListener(
function()
print("lua control button ok")
local i=login:GetComponent("InputField")
if i.text~="" then
print(i.text)
else
print("值不能为空")
end
end
)
c#代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using UnityEngine.UI;
public class LuaCallUI : MonoBehaviour
{
public TextAsset luafile;
LuaTable runTable;
public List<GameObjectsClass> goList;
LuaEnv luaEnv;
private void Awake()
{
luaEnv = new LuaEnv();
runTable = luaEnv.NewTable();
LuaTable metaTable = luaEnv.NewTable(); //这是一个元表
metaTable.Set("__index", luaEnv.Global);//让元表的查询全部指向文件中的公共变量
runTable.SetMetaTable(metaTable);//把元表放入普通表中
metaTable.Dispose();//可以销毁元表
//这个脚本挂载的游戏对象为this,方便lua调用
runTable.Set("self", this);
//把golist里的物体,添加到runTable表中
for (int i = 0; i < goList.Count; i++)
{
runTable.Set(goList[i].name, goList[i].go);
}
//这句可以解释成这个文件的内容,包含在这个表里
luaEnv.DoString(luafile.text, "luaFile2.lua", runTable);
}
}
ps:点号,冒号的总结,对象的方法用冒号,别的用点号?