XLua教程之C#调用Lua

上一篇文章

XLua教程之入门篇-CSDN博客

在C#脚本中访问lua全局数据,特别是table以及function,代价比较大,建议尽量少做相关操作。

LuaEnv.Global.Get

用于获取一个全局变量,但是无法获取局部变量(用local修饰)

全局基本类型变量

支持int、float、double、bool、string类型

string value1 = luaenv.Global.Get<string>("stringValue");
Debug.Log($"string:{value1}");float value2 = luaenv.Global.Get<float>("floatValue");
Debug.Log($"float:{value2}");bool value3 = luaenv.Global.Get<bool>("boolValue");
Debug.Log($"bool:{value3}");double value4 = luaenv.Global.Get<double>("doubleValue");
Debug.Log($"double:{value4}");int value5 = luaenv.Global.Get<int>("intValue");
Debug.Log($"int:{value5}");

全局函数

测试:Lua脚本侧代码

--无参无返回值
function SayHi()print("hello world!")
end--有参有返回值
function GetNumSum(a,b,c)local result = a+b+c;print(result)return result
end--变长参数多返回值
function GetManyResult(...)local list = {...}local result1 = 0;for _,v in ipairs(list) doresult1 = result1 + vendlocal result2 = 1;for _,v in ipairs(list) doresult2 = result2 * vendreturn result1,result2
end

第一种方法  映射到委托delegate(推荐使用)

这种是建议的方式,性能好很多,而且类型安全。缺点是要生成代码(如果没生成代码会抛InvalidCastException异常)

1、先注册对应Lua函数的C#委托,并添加 [CSharpCallLua]标签。(无参无返回值可以不用添加该标签,xlua默认支持)

//无参无返回值
public delegate void NoParamNoReturn();//有参有返回值
[CSharpCallLua]
public delegate int XParamOneReturn(int a,int b,int c);//变长参数1返回值
[CSharpCallLua]
public delegate int XParam1Return(params int[] temp);

2、先清空生成的xlua插桩代码,再重新生成

3、调用

//无参无返回值
NoParamNoReturn func1 = luaEnv.Global.Get<NoParamNoReturn>("SayHi");
func1();//有参有返回值
XParamOneReturn func2 = luaEnv.Global.Get<XParamOneReturn>("GetNumSum");
var result1 = func2(1,2,3);
Debug.Log(result1);//变长参数1返回值
XParam1Return func3 = luaEnv.Global.Get<XParam1Return>("GetManyResult1"); 
int a =default(int);
int b =default(int);
var result2 = func3(1,2,3,4);
Debug.Log(result2);

第二种方法  映射到LuaFunction

LuaFunction上有个变参的Call函数,可以传任意类型,任意个数的参数,返回值是object的数组,对应于lua的多返回值。

//无参无返回值
LuaFunction func1 = luaEnv.Global.Get<LuaFunction>("SayHi");
func1.Call();//有参有返回值
LuaFunction func2 = luaEnv.Global.Get<LuaFunction>("GetNumSum");
var result1 = func2.Call(1,2,3);
foreach (var item in result1)
{Debug.Log(item);
}//变长参数多返回值
LuaFunction func3 = luaEnv.Global.Get<LuaFunction>("GetManyResult");
var result2 = func3.Call(1,2,3);
foreach (var item in result2)
{Debug.Log(item);
}

对比:

优先使用映射到委托方案

映射到XLua自带的LuaFunction,简单方便,但是会消耗性能;

映射到Delegate委托,官方建议,性能比LuaFunction要好很多,而且类型安全;但需要在自定义委托前添加[CSharpCallLua]特性标签

特性映射到委托 (Delegate)映射到 LuaFunction
性能极高 (接近原生C#调用)较低 (涉及查找、压参、调用、返回等一系列开销)
用法像调用普通C#委托一样调用其 Call(...) 方法,传入参数数组
类型安全强类型,编译时检查参数和返回值类型弱类型,参数和返回值都是 object[],运行时易出错
内存开销较大(每次调用可能产生临时 object[] 垃圾)
适用场景高频调用(如 Update、UI事件回调)低频调用一次性调用参数数量/类型不固定
配置要求需要标记 [CSharpCallLua] 并生成代码无需任何额外配置,开箱即用

全局表

根据表的数据结构类型可以按照不同的情况,选择不同的映射形式。

如果表的形式类似于列表,可以映射到C#的List<T>。

如果表的形式类似于字典,可以映射到C#的Dictionary<T>。

如果表的形式类似于类,可以映射到C#的class。

映射到List<T>

List<int> list1 = luaEnv.Global.Get<List<int>>("list1");
foreach (var item in list1)
{Debug.Log(item);
}

映射到Dictionary<T>

Dictionary<int, string> dic = luaEnv.Global.Get<Dictionary<int, string>>("list2");
foreach (var item in dic)
{Debug.Log($"{item.Key}:{item.Value}");
}

映射到class

先根据lua表,声明对应C#类结构,再调用

public class Student
{public int id;public string name;public bool sex;public float score;
}Student student = luaEnv.Global.Get<Student>("Student");
Debug.Log($"{student.id} {student.name} {student.sex} {student.score}");

映射到LuaTable

xLua自带映射,兼容Lua表多种情况,不用定义c#类结构,开箱即用。但是性能消耗比较大,一般情况不推荐使用。

LuaTable student = luaEnv.Global.Get<LuaTable>("Student");
Debug.Log($"{student.Get<int>("id")}");
Debug.Log($"{student.Get<string>("name")}");
Debug.Log($"{student.Get<bool>("sex")}");
Debug.Log($"{student.Get<float>("score")}");

LuaEnv.Global.Set

用于修改一个全局变量

//string
luaenv.Global.Set("stringValue", "天天向上");
//float
luaenv.Global.Set("floatValue", 99.99);
//bool
luaenv.Global.Set("boolValue", false);
//double
luaenv.Global.Set("doubleValue", 9.999999999);
//int
luaenv.Global.Set("intValue", 438);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/96654.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/96654.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ 标准库中的哈希函数:从std::hash到自定义哈希器

C 标准库中的哈希函数&#xff1a;从 std::hash 到自定义哈希器 1. 引言 在上一篇中&#xff0c;我们介绍了哈希表为什么能够实现 O(1) 查找。 核心秘密在于&#xff1a;哈希函数。 在 C 标准库中&#xff0c;哈希表容器&#xff08;如 unordered_map、unordered_set&#xff0…

在图形 / 游戏开发中,为何 Pixels Per Unit(PPU)数值越小,物体在屏幕上显示的尺寸越大?

1. 什么是 PPU&#xff1f; PPU&#xff08;Pixels Per Unit&#xff09;指的是 多少像素对应游戏世界中的一个单位&#xff08;Unit&#xff09;。 在 Unity 等游戏引擎中&#xff0c;1 Unit 通常被视为世界空间的基本长度&#xff0c;比如 1 米。2. PPU 与物体大小的关系PPU …

【ZYNQ开发篇】Petalinux和电脑端的静态ip地址配置

使用Petalinux工具为ZYNQ板卡搭建嵌入式Linux操作系统&#xff0c;成功搭建后&#xff0c;用户通常会使用客户端软件对ZYNQ板卡上的Linux系统进行访问&#xff0c;软件需要知道ZYNQ板卡的ip地址才能进行访问&#xff0c;如果ip地址是动态变化的&#xff0c;软件每次访问都要重新…

AVL树知识总结

AVL树概念性质一颗AVL树或是空树&#xff0c;或者具有一下性质的二叉搜索树&#xff1a;左右都是AVL树&#xff0c;左右子树高度差的绝对值不超过1AVL树有n个结果&#xff0c;高度保持在O&#xff08;logN&#xff09; 搜索时间复杂度O(logN&#xff09;模拟实现插入定义&#…

返利app的跨域问题解决方案:CORS与反向代理在前后端分离架构中的应用

返利app的跨域问题解决方案&#xff1a;CORS与反向代理在前后端分离架构中的应用 大家好&#xff0c;我是阿可&#xff0c;微赚淘客系统及省赚客APP创始人&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在返利APP的前后端分离架构中&#xff0c;跨…

【dl】python基础 深度学习中需要用到的python基础

直接在jupyter写笔记然后导出md格式真的太好用了本文笔记来自小破站视频BV1K14y1c75ePython 基础 1. 变量 1.1 三种基本变量类型 # 字符串 str str_v "123"# 数字 int或float num_v 11 float_v 12.0# 布尔型 bool bool_v True1.1.1 字符串 f字符串&#xff1a;在…

Vue FullPage.js 完整使用指南:Vue 3 官方全屏滚动解决方案

概述 vue-fullpage.js 是 FullPage.js 的官方 Vue.js 3 包装器&#xff0c;为 Vue 3 应用提供了强大的全屏滚动功能。该插件基于成熟的 FullPage.js 库&#xff0c;支持多种滚动效果和丰富的配置选项&#xff0c;特别适用于企业级数据大屏、产品展示、单页应用等场景。 官方信…

软件工程实践一:Git 使用教程(含分支与 Gitee)

文章目录目标一、快速上手1. Windows 安装 Git2. 初始化 / 克隆二、核心概念速览三、常用命令清单1) 查看状态与差异2) 添加与提交3) 历史与回溯4) 撤销与恢复&#xff08;Git 2.23 推荐新命令&#xff09;5) 忽略文件四、分支与合并&#xff08;Branch & Merge&#xff09…

css`min()` 、`max()`、 `clamp()`

min() 用来计算多个数值中最小的那个&#xff0c;非常适合做自适应。 width: min(50vw, 500px) 50vw 表示 视口宽度的 50% 500px 表示 500px min(50vw, 500px) 表示会取两者中 最小的那个 作为最终的宽度&#xff0c;。 使用场景 限制某个元素宽度不超过某个值&#xff1b; 响…

【WRF-VPRM 预处理器】HEG 安装(服务器)-MRT工具替代

目录 HEG 安装 验证 HEG 安装与否 设置环境变量(建议) 命令行接口(Command Line Interface) hegtool 工具 hegtool 用法 Header File 格式 功能1:`gdtif` 工具 – MISR 数据处理 `gdtif` 使用方式 参数文件格式(Parameter File Format) 功能2:`resample` 工具 – 重采样…

PyTorch 神经网络

神经网络是一种模仿人脑神经元链接的计算模型&#xff0c; 由多层节点组成&#xff0c; 用于学习数据之间的复杂模式和关系。神经网络通过调整神经元之间的连接权重来优化预测结果&#xff0c;这个过程可以涉及到向前传播&#xff0c;损失计算&#xff0c;反向传播和参数更新。…

详细解析苹果iOS应用上架到App Store的完整步骤与指南

&#x1f4f1;苹果商店上架全流程详解 &#x1f469;‍&#x1f4bb;想要将你的App上架到苹果商店&#xff1f;跟随这份指南&#xff0c;一步步操作吧&#xff01; 1️⃣ 申请开发者账号&#xff1a;访问苹果开发者网站&#xff0c;注册并支付99美元年费&#xff0c;获取开发者…

三维GIS开发实战!Cesium + CZML 实现火箭飞行与分离的 3D 动态模拟

CZML是一种基于JSON的数据格式&#xff0c;专门用于在Cesium中描述3D场景和时间动态数据。本文将详细介绍了CZML的特点&#xff08;JSON格式、时间动态性、层次结构等&#xff09;和基本组件&#xff0c;并给出了一个火箭发射的实例。通过搭建Cesium开发环境&#xff08;使用vi…

Spring Boot 深入剖析:BootstrapRegistry 与 BeanDefinitionRegistry 的对比

在 Spring Boot 的启动过程中&#xff0c;BootstrapRegistry 和 BeanDefinitionRegistry 是两个名为“Registry”却扮演着截然不同角色的核心接口。理解它们的差异是深入掌握 Spring Boot 启动机制和进行高级定制开发的关键。BootstrapRegistry public static ConfigurableAppl…

贪心算法应用:速率单调调度(RMS)问题详解

Java中的贪心算法应用&#xff1a;速率单调调度(RMS)问题详解 1. 速率单调调度(RMS)概述 速率单调调度(Rate Monotonic Scheduling, RMS)是一种广泛应用于实时系统中的静态优先级调度算法&#xff0c;属于贪心算法在任务调度领域的经典应用。 1.1 基本概念 RMS基于以下原则&…

Cesium4--地形(OSGB到3DTiles)

1 OSBG OSGB&#xff08;OpenSceneGraph Binary&#xff09;是基于 OpenSceneGraph&#xff08;OSG&#xff09; 三维渲染引擎的二进制三维场景数据格式&#xff0c;广泛用于存储和传输倾斜摄影测量、BIM、点云等大规模三维模型&#xff0c;尤其在国产地理信息与智慧城市项目中…

多语言共享贩卖机投资理财共享售卖机投资理财系统

多语言共享贩卖机投资理财/共享售卖机分红/充电宝/充电桩投资理财系统 采用thinkphp内核开发&#xff0c;支持注册赠金、多级分销&#xff0c;功能很基础 修复后台用户列表管理 可自定义理财商品 多种语言还可以添加任意语言 源码开源 多级分销 注册赠金等

[Windows] PDF 专业压缩工具 v3.0

[Windows] PDF 专业压缩工具 v3.0 链接&#xff1a;https://pan.xunlei.com/s/VOZwtC_5lCF-UF6gkoHuxWMoA1?pwdchg8# PDF 压缩工具 3.0 新版功能特点 - 不受页数限制&#xff01; 一、核心压缩功能 1.多模式智能压缩 支持 4 种压缩模式&#xff1a;平衡模式&#xff08…

SHEIN 希音 2026 校招 内推 查进度

SHEIN 希音 2026 校招 内推 查进度 &#x1f3e2;公司名称&#xff1a;SHEIN 希音 &#x1f4bb;招聘岗位&#xff1a;前端、后端、测试、产品、安全、运维、APP 研发、数据分析、设计师、买手、企划、招商、管培生 &#x1f31f;内推码&#xff1a;NTA2SdK &#x1f4b0;福利待…

ARM (6) - I.MX6ULL 汇编点灯迁移至 C 语言 + SDK 移植与 BSP 工程搭建

回顾一、核心关键字&#xff1a;volatile1.1 作用告诉编译器&#xff1a;被修饰的变量会被 “意外修改”&#xff08;如硬件寄存器的值可能被外设自动更新&#xff09;&#xff0c;禁止编译器对该变量进行优化&#xff08;如缓存到寄存器、删除未显式修改的代码&#xff09;。本…