找回密码
 立即注册
查看: 324|回复: 0

XLua系列讲解_XLua调用C#

[复制链接]
发表于 2021-8-13 14:09 | 显示全部楼层 |阅读模式
搭建Lua运行环境

1.新建一个Lua脚本命名为 “LuaCallCSharp.lua.txt”(代码如下)
  1. --[[测试Lua访问C#脚本]]
  2. print("Hello World!")
复制代码
2.新建一个C#脚本命名为“LuaCallCSharpBase”(代码如下)
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using XLua;
  5. /// <summary>测试Xlua调用C#脚本</summary>
  6. public class LuaCallCSharpBase : MonoBehaviour
  7. {
  8.     LuaEnv m_LuaEnv = null;
  9.     private void Start()
  10.     {
  11.         m_LuaEnv = new LuaEnv();
  12.         m_LuaEnv.DoString("require 'LuaCallCSharp'");
  13.     }
  14.     private void OnDestroy()
  15.     {
  16.         m_LuaEnv.Dispose();
  17.     }
  18. }
复制代码
3.运行结果如下


lua中实例化一个Unity对象

1.在 “LuaCallCSharp.lua.txt” 脚本中添加如下代码
  1. --1: Lua 中实例化一个 Unity 对象
  2. local newGameObject = CS.UnityEngine.GameObject()
  3. newGameObject.name="New GameObject"
复制代码
2.运行结果如下


查找Unity中的对象
  1. --查找Unity中的对象
  2. local findObject = CS.UnityEngine.GameObject.Find("Main Camera")
复制代码
调用C#父类和子类

1.新建一个C#脚本命名为“BaseCalss”(代码如下)
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. /// <summary>测试Lua调用C#的父类和子类_父类</summary>
  5. public class BaseCalss : MonoBehaviour
  6. {
  7.     public string BaseCalssName = "父类字段";
  8.     public BaseCalss()
  9.     {
  10.         Debug.Log("父类构造函数");
  11.     }
  12.     public void ShowBaseCalssInfo()
  13.     {
  14.         Debug.Log("BaseCalss/父类 ShowBaseCalssInfo() 函数被调用");
  15.     }
  16. }
复制代码
2.新建一个C#脚本命名为“SubClass”(代码如下)
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. /// <summary>测试Lua调用C#的父类和子类_子类</summary>
  5. public class SubClass : BaseCalss
  6. {
  7.     public string SubCalssName = "子类字段";
  8.     public SubClass()
  9.     {
  10.         Debug.Log("子类构造函数");
  11.     }
  12.     public void ShowSubCalssInfo()
  13.     {
  14.         Debug.Log("SubClass/子类 ShowSubCalssInfo() 函数被调用");
  15.     }
  16. }
复制代码
3.修改 LuaCallCSharp.lua.txt 类(代码如下)
  1. --[[测试Lua访问C#脚本]]
  2. local subClass = CS.SubClass
  3. local classObject = subClass()
  4. classObject:ShowSubCalssInfo()            --调用子类普通函数
  5. classObject:ShowBaseCalssInfo()                          --调用父类普通函数
  6. print(classObject.SubCalssName)                          --调用父类普通字段
  7. print(classObject.BaseCalssName)                  --调用父类字段
复制代码
4.运行结果如下


方法重载

Xlua支持方法重载,但是由于lua中的数据类型不像c#中细分的那么精细(比如:lua中数值类型只有number类型,而C#有Int、float、long、double ...)所有只支持“有限的重载”
1.新建一个c#类,命名为 “MethodOverloading”(代码如下)
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. /// <summary>测试Lua调用C#方法重载</summary>
  5. public class MethodOverloading : MonoBehaviour
  6. {
  7.     public void Method()
  8.     {
  9.         Debug.Log(GetType() + "/Method()/无参重载方法");
  10.     }
  11.     public void Method(float num1, float num2)
  12.     {
  13.         Debug.Log(GetType() + "/Method(float num1,float num2)/重载方法");
  14.     }
  15.     public void Method(int num1, int num2)
  16.     {
  17.         Debug.Log(GetType() + "/Method(int num1, int num2)/重载方法");
  18.     }
  19.     public void Method(string num1, string num2)
  20.     {
  21.         Debug.Log(GetType() + "/Method(string num1, string num2)/重载方法");
  22.     }
  23. }
复制代码
2. 修改 LuaCallCSharp.lua.txt 类(代码如下)
  1. --[[测试Lua访问C#脚本,方法重载]]
  2. local classObject = CS.MethodOverloading()
  3. classObject:Method()
  4. classObject:Method(10,20)
  5. classObject:Method("Hello","World")
复制代码
3.运行结果如下


可以看到 number 类型调用C#中 “Method(float num1, float num2)” 函数。我们将C#中的函数颠倒一下顺序看看效果(修改如下)
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. /// <summary>测试Lua调用C#方法重载</summary>
  5. public class MethodOverloading : MonoBehaviour
  6. {
  7.     public void Method()
  8.     {
  9.         Debug.Log(GetType() + "/Method()/无参重载方法");
  10.     }
  11.     public void Method(int num1, int num2)
  12.     {
  13.         Debug.Log(GetType() + "/Method(int num1, int num2)/重载方法");
  14.     }
  15.     public void Method(float num1, float num2)
  16.     {
  17.         Debug.Log(GetType() + "/Method(float num1,float num2)/重载方法");
  18.     }
  19.     public void Method(string num1, string num2)
  20.     {
  21.         Debug.Log(GetType() + "/Method(string num1, string num2)/重载方法");
  22.     }
  23. }
复制代码
4.运行结果如下


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

1.新建一个C#脚本,命名“ComplexPara”(代码如下)
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. /// <summary>测试Lua调用带有复杂参数的函数</summary>
  5. public class ComplexPara : MonoBehaviour
  6. {
  7.     public void Method(Student student)
  8.     {
  9.         Debug.Log("name:" + student.name);
  10.         Debug.Log("id:" + student.id);
  11.         Debug.Log("score:" + student.score);
  12.         Debug.Log("level:" + student.level);
  13.     }
  14. }
  15. public struct Student
  16. {
  17.     public string name;
  18.     public int id;
  19.     public float score;
  20.     public EnumLevel level;
  21. }
  22. public enum EnumLevel
  23. {
  24.     difference,
  25.     good,
  26.     excellent,
  27. }
复制代码
2.修改 LuaCallCSharp.lua.txt 类(代码如下)
  1. --[[测试Lua访问C#脚本,复杂参数]]
  2. Student={name="张三",id=442213994,score=89.5,level=CS.EnumLevel.good}
  3. local classObject = CS.ComplexPara()
  4. classObject:Method(Student)
复制代码
3.运行结果如下


调用带有接口参数的函数

1.新建一个C#类,命名“InterfacePara”(代码如下)
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using XLua;
  5. /// <summary>测试Lua调用带有接口参数的函数</summary>
  6. public class InterfacePara : MonoBehaviour
  7. {
  8.     public void Method(MyInterface myInterface)
  9.     {
  10.         Debug.Log("name:" + myInterface.name);
  11.         Debug.Log("id:" + myInterface.id);
  12.         myInterface.Speak();
  13.     }
  14. }
  15. [CSharpCallLua]
  16. public interface MyInterface
  17. {
  18.     string name { get; set; }
  19.     int id { get; set; }
  20.     void Speak();
  21. }
复制代码
2. 由于使用了Xlua中的“[CSharpCallLua]”特性,需要重新生成一下代码


3.修改 LuaCallCSharp.lua.txt 类(代码如下)
  1. --[[测试Lua访问C#脚本,带接口参数]]
  2. MyInterface=
  3. {
  4.         name="张三",
  5.         id=1024,
  6.         Speak=function()
  7.                
  8.                 print("Lua中 Speak() 函数被调用")
  9.         end
  10. }
  11. local classObject = CS.InterfacePara()
  12. classObject:Method(MyInterface)
复制代码
4.运行结果如下


调用带有委托参数的函数

1.新建一个C#类,命名“DelegatePara”(代码如下)
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using XLua;
  5. /// <summary>测试Lua调用带有委托参数的函数</summary>
  6. public class DelegatePara : MonoBehaviour
  7. {
  8.     public void Method(MyDelegate del)
  9.     {
  10.         Debug.Log(GetType() + "/Method(MyDelegate del)");
  11.         del.Invoke(88);
  12.     }
  13. }
  14. [CSharpCallLua]
  15. public delegate void MyDelegate(int num);
复制代码
2. 由于使用了Xlua中的“[CSharpCallLua]”特性,需要重新生成一下代码


3.修改 LuaCallCSharp.lua.txt 类(代码如下)
  1. --[[测试Lua访问C#脚本,带委托参数]]
  2. myDelegate=function(num)
  3.        
  4.         print("Lua 中对应的委托方法。num:"..num)
  5. end
  6. local classObject=CS.DelegatePara()
  7. classObject:Method(myDelegate)
复制代码
4.运行结果如下


调用泛型方法

lua不支持直接调用c#中的泛型方法,但是可以通过扩展方法功能进行封装后调用(具体如下案例)
1.新建一个c#类,命名“MyGengerric”(代码如下)
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. /// <summary>测试lua调用泛型函数</summary>
  6. [XLua.LuaCallCSharp]
  7. public class MyGengerric
  8. {
  9.     public T GetMax<T>(T num1,T num2) where T:IComparable
  10.     {
  11.         return (num1.CompareTo(num2)<0)?num2:num1;
  12.     }
  13. }
复制代码
2.新建一个扩展方法,命名为“Extension_MyGengerric”(代码如下)
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. /// <summary>扩展方法</summary>
  5. [XLua.LuaCallCSharp]
  6. public static class Extension_MyGengerric
  7. {
  8.     public static int GetMax(this MyGengerric gen, int num1, int num2)
  9.     {
  10.         return (num1 > num2) ? num1 : num2;
  11.     }
  12. }
复制代码
3. 由于使用了Xlua中的“[XLua.LuaCallCSharp]”特性,需要重新生成一下代码


4.修改 LuaCallCSharp.lua.txt 类(代码如下)
  1. --[[测试Lua访问C#脚本,泛型方法]]
  2. local maxNum = CS.MyGengerric():GetMax(10,20)
  3. print("maxNum:"..maxNum)
复制代码
5.运行代码如下


推荐学习资料

XLua入门到精通系列讲解教程目录
Xlua官方插件下载:里面有很多示例工程
lua基础教程:菜鸟教程网
欢迎对Unity技术感兴趣的朋友,加入QQ群:299412191 讨论

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-6-5 03:48 , Processed in 0.151409 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表