acecase 发表于 2021-8-13 14:09

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


public interface MyInterface
{
    string name { get; set; }
    int id { get; set; }
    void Speak();
}2. 由于使用了Xlua中的“”特性,需要重新生成一下代码


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

}


public delegate void MyDelegate(int num);2. 由于使用了Xlua中的“”特性,需要重新生成一下代码


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>

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>

public static class Extension_MyGengerric
{
    public static int GetMax(this MyGengerric gen, int num1, int num2)
    {
      return (num1 > num2) ? num1 : num2;
    }
}3. 由于使用了Xlua中的“”特性,需要重新生成一下代码


4.修改 LuaCallCSharp.lua.txt 类(代码如下)
--[[测试Lua访问C#脚本,泛型方法]]

local maxNum = CS.MyGengerric():GetMax(10,20)
print("maxNum:"..maxNum)5.运行代码如下


推荐学习资料

XLua入门到精通系列讲解教程目录
Xlua官方插件下载:里面有很多示例工程
lua基础教程:菜鸟教程网
欢迎对Unity技术感兴趣的朋友,加入QQ群:299412191 讨论
页: [1]
查看完整版本: XLua系列讲解_XLua调用C#