XLua Lua访问C#中的方法(一)普通访问

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;
    }
}

XLua Lua访问C#中的方法(一)普通访问_第1张图片
–https://www.jianshu.com/p/aeb52e214329

  • 使用下列Lua代码来创建两个GameObject对象,访问对象的name属性并调用其SetActive方法
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

XLua Lua访问C#中的方法(一)普通访问_第2张图片

访问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

XLua Lua访问C#中的方法(一)普通访问_第3张图片

访问自定义的C#类
如果要通过Lua访问自己定义的类的话,需要给被Lua代码访问的类加上一个Attribute:[LuaCallCSharp],用来生成Lua的适配代码
下面对[LuaCallCSharp]的解释参考xLua的Github主页的FAQ

XLua.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

XLua Lua访问C#中的方法(一)普通访问_第4张图片

你可能感兴趣的:(Lua)