XLua系列讲解_XLua调用C#

Posted DaLiangChen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XLua系列讲解_XLua调用C#相关的知识,希望对你有一定的参考价值。

搭建Lua运行环境

1.新建一个Lua脚本命名为 “LuaCallCSharp.lua.txt”(代码如下)

--[[测试Lua访问C#脚本]]

print("Hello World!")

2.新建一个C#脚本命名为“LuaCallCSharpBase”(代码如下)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

/// <summary>测试Xlua调用C#脚本</summary>
public class LuaCallCSharpBase : MonoBehaviour


    LuaEnv m_LuaEnv = null;

    private void Start()
    
        m_LuaEnv = new LuaEnv();
        m_LuaEnv.DoString("require 'LuaCallCSharp'");
    

    private void OnDestroy()
    
        m_LuaEnv.Dispose();
    


3.运行结果如下

 

lua中实例化一个Unity对象

1.在 “LuaCallCSharp.lua.txt” 脚本中添加如下代码

--1: Lua 中实例化一个 Unity 对象
local newGameObject = CS.UnityEngine.GameObject()
newGameObject.name="New GameObject"

2.运行结果如下

 

查找Unity中的对象

--查找Unity中的对象
local findObject = CS.UnityEngine.GameObject.Find("Main Camera")

 

调用C#父类和子类

1.新建一个C#脚本命名为“BaseCalss”(代码如下)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>测试Lua调用C#的父类和子类_父类</summary>
public class BaseCalss : MonoBehaviour

    public string BaseCalssName = "父类字段";

    public BaseCalss()
    
        Debug.Log("父类构造函数");
    

    public void ShowBaseCalssInfo()
    
        Debug.Log("BaseCalss/父类 ShowBaseCalssInfo() 函数被调用");
    


2.新建一个C#脚本命名为“SubClass”(代码如下) 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>测试Lua调用C#的父类和子类_子类</summary>
public class SubClass : BaseCalss

    public string SubCalssName = "子类字段";
    public SubClass()
    
        Debug.Log("子类构造函数");
    

    public void ShowSubCalssInfo()
    
        Debug.Log("SubClass/子类 ShowSubCalssInfo() 函数被调用");
    

3.修改 LuaCallCSharp.lua.txt 类(代码如下)

--[[测试Lua访问C#脚本]]

local subClass = CS.SubClass
local classObject = subClass()

classObject:ShowSubCalssInfo()            --调用子类普通函数
classObject:ShowBaseCalssInfo()			  --调用父类普通函数

print(classObject.SubCalssName)			  --调用父类普通字段
print(classObject.BaseCalssName)		  --调用父类字段

 4.运行结果如下

 

方法重载

Xlua支持方法重载,但是由于lua中的数据类型不像c#中细分的那么精细(比如:lua中数值类型只有number类型,而C#有Int、float、long、double ...)所有只支持“有限的重载”

1.新建一个c#类,命名为 “MethodOverloading”(代码如下)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>测试Lua调用C#方法重载</summary>
public class MethodOverloading : MonoBehaviour

    public void Method()
    
        Debug.Log(GetType() + "/Method()/无参重载方法");
    

    public void Method(float num1, float num2)
    
        Debug.Log(GetType() + "/Method(float num1,float num2)/重载方法");
    

    public void Method(int num1, int num2)
    
        Debug.Log(GetType() + "/Method(int num1, int num2)/重载方法");
    

    public void Method(string num1, string num2)
    
        Debug.Log(GetType() + "/Method(string num1, string num2)/重载方法");
    

2. 修改 LuaCallCSharp.lua.txt 类(代码如下)

--[[测试Lua访问C#脚本,方法重载]]

local classObject = CS.MethodOverloading()
classObject:Method()
classObject:Method(10,20)
classObject:Method("Hello","World")

3.运行结果如下

可以看到 number 类型调用C#中 “Method(float num1, float num2)” 函数。我们将C#中的函数颠倒一下顺序看看效果(修改如下)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>测试Lua调用C#方法重载</summary>
public class MethodOverloading : MonoBehaviour

    public void Method()
    
        Debug.Log(GetType() + "/Method()/无参重载方法");
    

    public void Method(int num1, int num2)
    
        Debug.Log(GetType() + "/Method(int num1, int num2)/重载方法");
    

    public void Method(float num1, float num2)
    
        Debug.Log(GetType() + "/Method(float num1,float num2)/重载方法");
    

    public void Method(string num1, string num2)
    
        Debug.Log(GetType() + "/Method(string num1, string num2)/重载方法");
    

4.运行结果如下

这次 number 类型调用C#中 “Method(int num1, int num2)” 函数,说明类型一致时优先重载上面的函数

 

调用带有复杂参数的函数

1.新建一个C#脚本,命名“ComplexPara”(代码如下)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>测试Lua调用带有复杂参数的函数</summary>
public class ComplexPara : MonoBehaviour

    public void Method(Student student)
    
        Debug.Log("name:" + student.name);
        Debug.Log("id:" + student.id);
        Debug.Log("score:" + student.score);
        Debug.Log("level:" + student.level);
    


public struct Student

    public string name;
    public int id;
    public float score;
    public EnumLevel level;


public enum EnumLevel

    difference,
    good,
    excellent,

2.修改 LuaCallCSharp.lua.txt 类(代码如下)

--[[测试Lua访问C#脚本,复杂参数]]

Student=name="张三",id=442213994,score=89.5,level=CS.EnumLevel.good

local classObject = CS.ComplexPara()
classObject:Method(Student)

3.运行结果如下 

 

调用带有接口参数的函数

1.新建一个C#类,命名“InterfacePara”(代码如下)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

/// <summary>测试Lua调用带有接口参数的函数</summary>
public class InterfacePara : MonoBehaviour

    public void Method(MyInterface myInterface)
    
        Debug.Log("name:" + myInterface.name);
        Debug.Log("id:" + myInterface.id);
        myInterface.Speak();
    


[CSharpCallLua]
public interface MyInterface

    string name  get; set; 
    int id  get; set; 
    void Speak();

2. 由于使用了Xlua中的“[CSharpCallLua]”特性,需要重新生成一下代码

3.修改 LuaCallCSharp.lua.txt 类(代码如下)

--[[测试Lua访问C#脚本,带接口参数]]
MyInterface=

	name="张三",
	id=1024,
	Speak=function()
		
		print("Lua中 Speak() 函数被调用")
	end



local classObject = CS.InterfacePara()
classObject:Method(MyInterface)

4.运行结果如下 

 

调用带有委托参数的函数

1.新建一个C#类,命名“DelegatePara”(代码如下)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

/// <summary>测试Lua调用带有委托参数的函数</summary>
public class DelegatePara : MonoBehaviour

    public void Method(MyDelegate del)
    
        Debug.Log(GetType() + "/Method(MyDelegate del)");
        del.Invoke(88);
    



[CSharpCallLua]
public delegate void MyDelegate(int num);

2. 由于使用了Xlua中的“[CSharpCallLua]”特性,需要重新生成一下代码

3.修改 LuaCallCSharp.lua.txt 类(代码如下)

--[[测试Lua访问C#脚本,带委托参数]]

myDelegate=function(num)
	
	print("Lua 中对应的委托方法。num:"..num)

end

local classObject=CS.DelegatePara()
classObject:Method(myDelegate)

4.运行结果如下 

 

调用泛型方法

lua不支持直接调用c#中的泛型方法,但是可以通过扩展方法功能进行封装后调用(具体如下案例)

1.新建一个c#类,命名“MyGengerric”(代码如下)

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>测试lua调用泛型函数</summary>
[XLua.LuaCallCSharp]
public class MyGengerric 

    public T GetMax<T>(T num1,T num2) where T:IComparable
    
        return (num1.CompareTo(num2)<0)?num2:num1;
    


2.新建一个扩展方法,命名为“Extension_MyGengerric”(代码如下)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>扩展方法</summary>
[XLua.LuaCallCSharp]
public static class Extension_MyGengerric

    public static int GetMax(this MyGengerric gen, int num1, int num2)
    
        return (num1 > num2) ? num1 : num2;
    

3. 由于使用了Xlua中的“[XLua.LuaCallCSharp]”特性,需要重新生成一下代码

4.修改 LuaCallCSharp.lua.txt 类(代码如下)

--[[测试Lua访问C#脚本,泛型方法]]

local maxNum = CS.MyGengerric():GetMax(10,20)
print("maxNum:"..maxNum)

5.运行代码如下

 

推荐学习资料

XLua入门到精通系列讲解教程目录

Xlua官方插件下载:里面有很多示例工程

lua基础教程:菜鸟教程网

欢迎对Unity技术感兴趣的朋友,加入QQ群:299412191 讨论 

以上是关于XLua系列讲解_XLua调用C#的主要内容,如果未能解决你的问题,请参考以下文章

XLua系列讲解_使用VsCode来书写Lua代码

XLua系列讲解_使用VsCode来书写Lua代码

Unity2020 几种常用热更新方案的优劣及XLua实战

深入xLua实现原理之C#如何调用Lua

Xlua hotfix C#案例

Xlua hotfix C#案例