using System;
using System.IO;
using System.Text;
using UnityEngine;
using XLua;
public class HelloWorld01 : MonoBehaviour
{
private LuaEnv luaEnv;
void Start()
{
luaEnv = new LuaEnv();//全局唯一
luaEnv.AddLoader(CustomLoader);//添加自定义路径
luaEnv.DoString("require '007' ");//在自定义路径中查找007文件
Action creatFun= luaEnv.Global.Get("init");//调用Lua中的init方法
creatFun();
}
private byte[] CustomLoader(ref string filepath)
{
string path = Application.dataPath + "/Scripts/Xlua/" + filepath + ".lua";//自定义Lua文件路径
return Encoding.UTF8.GetBytes(File.ReadAllText(path));//返回对应文件的byte[]数据
}
void OnDestroy()
{
luaEnv.Dispose();
luaEnv = null;
}
}
–https://www.jianshu.com/p/aeb52e214329
print('启动了Lua')
function init()
print("执行了Lua的全局方法init")--无参数的方法
CreatUnityObj()
end
function CreatUnityObj()
--创建C#对象
local go1 = CS.UnityEngine.GameObject("Cube")
local go2 = CS.UnityEngine.GameObject("Sphere")
--访问对象属性
print("GameObject1:", go1.name, "GameObject2:", go2.name)
--修改对象属性
go1.name = "Cube--"
go2.name = "Sphere--"
print("GameObject1:", go1.name, "GameObject2:", go2.name)
--调用对象方法(调用对象方法时注意使用":"语法糖)
go1:SetActive(false) --go1.SetActive(go1, false) 也可以这样调用
go2:SetActive(false) --go2.SetActive(go2, false) 也可以这样调用
end
访问C#静态方法、静态属性 | |
---|---|
下面的Lua代码:
获取Time类的引用
读取Time类的静态属性deltaTime
修改了Time类的静态属性timeScale
获取GameObject类的引用
调用GameObject类的静态方法Find,找到场景中的主相机Main Camera
function init()
print("执行了Lua的全局方法init")--无参数的方法
CreatUnityObj()
end
function CreatUnityObj()
--读取静态属性,直接点(.)
local Time=CS.UnityEngine.Time
print('Time.deltaTime:',Time.deltaTime)
--修改静态方法
print('Time.timeScale Before:',Time.timeScale)
Time.timeScale=0.5
print('Time.timeScale After:',Time.timeScale)
--调用静态方法
local GameObject=CS.UnityEngine.GameObject
local camera=GameObject.Find('Main Camera')
print('camera.name:',camera.name)
end
访问自定义的C#类
如果要通过Lua访问自己定义的类的话,需要给被Lua代码访问的类加上一个Attribute:[LuaCallCSharp],用来生成Lua的适配代码
下面对[LuaCallCSharp]的解释参考xLua的Github主页的FAQXLua.LuaCallCSharp
一个C#类型加了这个配置,xLua会生成这个类型的适配代码(包括构造该类型实例,访问其成员属性、方法,静态属性、方法),否则将会尝试用性能较低的反射方式来访问。
一个类型的扩展方法(Extension Methods)加了这配置,也会生成适配代码并追加到被扩展类型的成员方法上。
xLua只会生成加了该配置的类型,不会自动生成其父类的适配代码,当访问子类对象的父类方法,如果该父类加了LuaCallCSharp配置,则执行父类的适配代码,否则会尝试用反射来访问。
反射访问除了性能不佳之外,在il2cpp下还有可能因为代码剪裁而导致无法访问,后者可以通过下面介绍的ReflectionUse标签来避免。
XLua.ReflectionUse
一个C#类型类型加了这个配置,xLua会生成link.xml阻止il2cpp的代码剪裁。
对于扩展方法,必须加上LuaCallCSharp或者ReflectionUse才可以被访问到。
建议所有要在Lua访问的类型,要么加LuaCallCSharp,要么加上ReflectionUse,这才能够保证在各平台都能正常运行。
using UnityEngine;
using XLua;
[LuaCallCSharp()]
public class FatherClass
{
public string BaseField = "BaseField";
private string _BaseProperty = "BaseProperty";
public string BaseProperty {
get { return _BaseProperty; }
set { _BaseProperty = value; }
}
public FatherClass()
{
Debug.Log("BaseClass 构造方法");
}
public void BaseFunc()
{
Debug.Log("BaseFunc");
}
public static string BaseStaticField = "BaseStaticField";
public static void BaseStaticFunc()
{
Debug.Log("BaseStaticFunc");
}
}
[LuaCallCSharp]
public class SonClass:FatherClass
{
public string SonField = "SonField";
public static string SonStaticField = "SonStaticField";
public void SonPrint()
{
Debug.Log("SonClass");
}
public static void OnStaticPrint()
{
Debug.Log("OnStaticPrint");
}
}
print('启动了Lua')
function init()
print("执行了Lua的全局方法init")--无参数的方法
CreatUnityObj()
end
function CreatUnityObj()
local FatherClass=CS.FatherClass--获取一个类的映射
local fatherClass=CS.FatherClass()--实例化一个类
print('------fatherClass普通方法成员方法、字段属性-------')
print('fatherClass.BaseField:',fatherClass.BaseField)--获取BaseClass的成员变量
print('BaseProperty:',fatherClass.BaseProperty)--获取变量属性
--baseClass:BaseClass()--构造方法,直接传入参数调用
fatherClass:BaseFunc()--用冒号调用(:)成员方法
print('------FatherClass静态成员方法、字段属性-------')
print('FatherClass.BaseStaticField:',FatherClass.BaseStaticField)--获取静态属性(要用类名直接调用,否则无法调用到的)
FatherClass.BaseStaticFunc()--调用静态方法
print('---调用子类的方法')
----子类SonClass--继承自父类FatherClass
local SonClass=CS.SonClass
local sonClass=CS.SonClass()
---普通方法调用--
print("sonClass.SonField:",sonClass.SonField)--获取子类的普通成员变量
sonClass:SonPrint()--调用子类的普通成员方法
---通过子类调用父类的方法
print('---通过子类调用父类的成员方法')
print('sonClass.BaseField:',sonClass.BaseField)--获取BaseClass的成员变量
print('sonClass.BaseProperty:',sonClass.BaseProperty)--获取变量属性
print('---通过子类调用父类的静态方法')
print('SonClass.SonStaticField:',SonClass.SonStaticField)--获取BaseClass的成员变量
SonClass.OnStaticPrint()
end