[游戏开发][unity]Xlua中使用proto、json、lpeg

news/2024/5/7 3:42:01/文章来源:https://blog.csdn.net/liuyongjie1992/article/details/127089110

Xlua官方教程里有,在创建lua虚拟机时,可以添加3个处理数据的库

_luaEnv = new LuaEnv();
_luaEnv.AddLoader(CustomLoaderMethod);
_luaEnv.AddBuildin("rapidjson", XLua.LuaDLL.Lua.LoadRapidJson);
_luaEnv.AddBuildin("lpeg", XLua.LuaDLL.Lua.LoadLpeg);
_luaEnv.AddBuildin("pb", XLua.LuaDLL.Lua.LoadLuaProfobuf);

Json和ProtoBuffer是我们开发中常见的工具,还有一个不是很常见的lpeg,找了几篇文章,大家自行跳转

https://www.jianshu.com/p/e8e1c5abfdbbhttps://www.jianshu.com/p/e8e1c5abfdbbLPEG库简介_suzuiyue的博客-CSDN博客_lpegLPEG库简介LPEG是一个供lua使用的基于 Parsing Expression Grammars 的模式匹配库,这篇文章只是讲其如何使用,并不涉及底层如何实现。LPEG 的函数主要分为三类,第一类是创建Pattern的构造函数,第二类是 Capture 函数, 第三类则是 match 等函数。 Capture 就是指一个Pattern,当前匹配时会产生某些捕获的值。Match 等函数lpeg.https://blog.csdn.net/suzuiyue/article/details/52905372

在lua当中如何使用这三个库呢,下面挨个介绍

1:Json的使用

引用rapidjson有几种方式

--调用方式1,声明一个全局变量RapidJson,代码执行后,可以在其他.lua文件中直接调用RapidJson 而不需要再次require('rapidjson')
RapidJson = require('rapidjson')--调用方式2,脚本内局部使用
local rapidJson = require('rapidjson')--调用方式3,方法内局部使用
function XXX()local rapidJson = require('rapidjson')
end

rapidjson具体使用,在调用encode和decode方法前,要先require('rapidjson')

--反序列化
local t = rapidjson.decode('{"a":123}')
print(t.a)
t.a = 456
--序列化
local s = rapidjson.encode(t)
print('json', s)

2:ProtoBuffer的使用

 pb的库在C#层已经添加,到了lua中可以直接调用,使用pb的前提肯定得让lua层的pb加载协议,协议才是序列化、反序列化的前提。

提示:Xlua的PB库支持proto2和proto3,需要在协议里标明是2还是3

xlua中有两种加载proto的方式,下面分别介绍


第一种加载proto方式:常规加载脚本文件,然后传递给pb加载库

以proto2版本的协议举例,这是一个常见的请求进入战斗协议,命名为Fight.proto文件,里面还引用了NetStruct_Fight.proto文件

syntax="proto2";
import "NetStruct_Fight.proto";message CSEnterBattle
{optional int32 battleSid = 1;         // 战役配置idoptional int32 isFixedArray = 2;	   // 是否固定阵容0不是 1是
}//[返回][游戏服]进入战斗结果
message SCEnterBattle
{optional int64 battleId = 1;				//服务器战斗序号repeated CampData camps = 2;                // 战斗阵营数据 (仅站位和card_sid)
}
local pcNew = nilfunction StartLoadProto()--protoc是一个lua文件,一般是lua库里带着的此处需要引用一下protoc = require "Framework/protoc"pcNew= protoc.new()--由于我的Fight.proto里引用了另一个proto,因此先加载引用LoadProto("NetStruct_Fight")--加载完引用后,再加载proto才不会报错LoadProto("Fight")
endfunction LoadProto(fileName)--C#资源加载器local AssetsData = CS.MoAssetText()AssetsData:Load("Battle/Proto/"..fileName..".txt")--不管你怎么加载,一定是从Unity里把协议文本取出来local protoString = AssetsData:GetText()--这一句是核心语句,协议文本加载入pb库,现在pb就知道该如何解析bytes数据啦assert(pcNew:load(protoString,fileName..".proto"))end

第一种加载文本的方式可以根据自己的框架来写,我这里是在lua中生成一个C#文本加载器,然后从C#层加载文件。


下面开始介绍第二种加载proto方式

assert(ProtocLib:load [[syntax = "proto3";message CSEnterBattle{int32 battleSid = 1;         // 战役配置idint32 isFixedArray = 2;	   // 是否固定阵容0不是 1是}//[返回][游戏服]进入战斗结果message SCEnterBattle{int64 battleId = 1;				//服务器战斗序号CampData camps = 2;                // 战斗阵营数据 }//阵营数据message CampData{ int32 id = 1;                     //阵营idint32 UnitId = 2;               //阵营类型}]]
)

仔细看上面代码你会发现,其实就是把proto协议里的内容全部都写到一个lua脚本里去,这个lua脚本包括了所有引用和非引用的proto数据结构,我这里的文件叫protoDefine.lua.txt文件,我们可以写一个批处理工具,把协议全都按行写入到一个文件中。如果你的协议非常多,那么会生成一个几千行甚至几万行的lua文件。项目启动的时候,在合适的位置调用 require "Net/ProtoDefine"加载这个脚本即可把协议加载到库。

上面介绍了两种加载proto协议的方式


加载完proto协议,我们当然要使用它呀,也就是序列化和反序列化数据

function UsePB()--第一步,加载bytes,请注意,EnterBattleMsg是我本地已经序列化出来的二进制数据文件测试用--将来肯定是从服务器获取二进制数据local bytes = LoadBytes("EnterBattleMsg")--反序列化,使用proto库里的SCEnterBattle结构体序列化该bytes数据local SCEnterBattleTab = assert(pb.decode('SCEnterBattle', bytes))--请注意,反序列化后得到SCEnterBattleTab,它是个table--获取数据如下print("战役Id: ".. SCEnterBattleTab.battleId)--序列化语句local bytes = pb.encode('SCEnterBattle', SCEnterBattleTab)--此时我们又得到了一个最初的bytes二进制数据print(pb.tohex(bytes))--打印数据
endfunction LoadBytes(fileName)--C#资源加载器local AssetsData = CS.MoAssetText()--同步加载文件AssetsData:Load("Battle/Proto/"..fileName..".bytes")--不管你怎么加载,一定是从Unity里把二进制数据读出来return AssetsData:GetBytes()end

3:lpeg的使用

 lpeg的功能非常多,建议直接去看上面分享的链接,详细看一下使用

local lpeg = require "lpeg"local match = lpeg.match
local P = lpeg.P-- value是string的情况
local ps = P'ab'
print(match(ps, "a"))  ---> nil
print(match(ps, "abcd"))  ---> 3  注:只匹配"ab"

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

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

相关文章

零基础学SQL(一、数据库与SQL简介)

一、数据库(database)是什么 目录 一、数据库(database)是什么 二、数据库专业术语 三、常见数据库类型 四、什么是SQL 五、为什么要学习SQL 我们从百度词条中可以看到,百度对数据库的介绍如下: 数据库是“按照数据结构来组织、存储和管理…

RabbitMQ总结

一、简介 什么是 MQ MQ Message Queue 消息队列 消息队列:存放内容是消息的 FIFO(先入先出) 队列。是一种跨进程的通信机制,用于上下游传递消息。 为什么要用 MQ ?作用 1、应用解耦 以电商系统为例&#xff0c…

玻色量子荣获第二届“率先杯”未来技术创新大赛“决赛优胜奖”

​9月22日至23日,由中国科学院、深圳市人民政府联合主办的第二届“率先杯”未来技术创新大赛决赛在深圳、北京两地以“线上线下结合”的形式成功举办。大赛组委会办公室秘书处组织专家按照《大赛评审方案》对进入决赛的项目进行评审,经择优遴选&#xff…

vue3项目创建并运行

vue搭建 准备环境 npmnodewebpackvs code npm 使用brew命令行进行下载安装指定版本: brew install npm查看版本号: $ npm -v 8.15.0Node 进入官网nodejs,根据自己电脑的版本进行下载安装,如果是mac电脑,可以直接…

分布式文件存储系统MinIO笔记

文章目录一、MinIO介绍1、文件系统应用场景2、MinIO介绍3、MinIO优点4、MinIO的基础概念5、纠删码EC(Erasure Code)6、存储形式7、存储方案二、Minio环境搭建1、介绍2、单机部署2.1 单机部署2.2 基于Linux部署2.3 基于docker部署(推荐)3、minio 纠删码模…

塑料划分PP PE PS PA ABS PVC

**PET(聚酯)代号1, **又叫涤纶树脂,原料呈乳白色或浅黄色,透明性好,无毒,具有密度高,硬度高,耐磨损,但不耐热水侵泡,不耐碱等特点,使…

2022年暨南大学计算机830真题

学科、专业名称:网络空间安全 研究方向:网络空间安全083900 考试科目名称及代码:数据结构830 考生注意:所有答案必须写在答题纸(卷)上,写在本试题上一律不给分。 一、 单项选择题 (每题2分,共20分) 下列程…

[python刷题模板] 珂朵莉树 ODT (基于支持随机访问的跳表

[python刷题模板] 珂朵莉树 ODT (基于支持随机访问的跳表) 一、 算法&数据结构1. 描述2. 复杂度分析3. 常见应用4. 常用优化二、 模板代码0. 区间推平(lg),单点询问(lg) CF292E. Copying Data1. 区间推平,区间询问最小值2. 区…

Unity Lighting 面板的参数设置用途详细总结

一、Environment 环境光 二、Scene 1、如果选择生成LightMap 要关闭实时光,开启烘培光 lighting mode为Mixed时,lighting settings的Mixed Lighting可用于设置混合的方式:Baked Indirect mode提供最高质量的光照,其设置只牵扯间…

windows环境下elasticsearch使用教程

windows环境下elasticsearch使用教程如下: 一、首先安装jdkElasticSearch是基于lucence开发的,lucence是apache开发的,因此ElasticSearch运行环境就需要java jdk支持。所以要先安装JAVA环境。由于ElasticSearch 5.x 往后依赖于JDK 1.8的&…

HAPPE+ER:一款让脑电研究人员“更快乐”的软件,可用于事件相关电位(ERP)分析的标准化预处理管道

导读 事件相关电位(ERP)设计是用脑电图(EEG)检测神经认知功能的常用方法。然而,传统的ERP数据预处理方法是手动编辑,这是一个主观且耗时的过程。最近创建了许多自动化通道,以满足EEG数据预处理的标准化、自动化和量化的需求;然而…

知识经济时代的基石:知识协同

管理学家彼得德鲁克(1994)指出:“企业管理的本质不在于技术与程序,而在于使知识有效。”在知识占主导地位的社会里,企业依靠知识进行创新的能力代表了企业在竞争中的优势,也是企业成功与否的标志。 世界变…

C++——string的封装

参考string类完成my_string类 #include <iostream> #include<cstring> using namespace std; class my_string { private:char *str;int len; public://无参构造my_string(){len 15;str new char[len];cout<<"无参构造"<<endl;}//有参构造…

IDEA通过原型(骨架)创建MavenJavaWeb项目

IDEA通过原型&#xff08;骨架&#xff09;创建MavenJavaWeb项目 目录IDEA通过原型&#xff08;骨架&#xff09;创建MavenJavaWeb项目一、通过原型&#xff08;骨架&#xff09;创建MavenJavaWeb项目二、配置tomcat一、通过原型&#xff08;骨架&#xff09;创建MavenJavaWeb项…

【PTA】输出学生成绩

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 专栏&#xff1a;PTA习题及解析 介绍&#xff1a;记录了博主在pta学习练题 目录前言1.简介2.优点一、题目二、代码前言 1.简介 “PTA程序…

【面试题】面试官: Vue如何实现权限管理?

我正在参加「掘金启航计划」 一、权限管理 权限管理就是让不同的用户只能访问自己权限内的资源&#xff0c;有以下几种 路由权限&#xff0c;用户登录后只能看到自己权限内的导航菜单&#xff0c;且只能访问自己权限内的路由地址视图权限&#xff0c;用户只能看到自己权限内…

朗涛任命Juanita Zhang为中国大陆区总经理,Peggy Hon为中国香港区总经理

在迅速发展的消费环境中&#xff0c;带领才华横溢的多元创意团队&#xff0c;持续推动业务发展 &#xff08;中国上海&#xff0c;2022年9月27日&#xff09;近日&#xff0c;全球顶尖的品牌设计与咨询公司朗涛宣布重要人事任命&#xff0c;分别任命Juanita Zhang为中国大陆区总…

Eureka注册不上或注册后IP不对(多网卡的坑)

Eureka注册不上或注册后IP不对&#xff08;多网卡的坑&#xff09; 一、问题发现 ​ 使用SpringCloud一套的微服务项目在开发测试环境都再正常不过了&#xff0c;到生产部署的时候启动服务就死活无法启动&#xff0c;去看启动日志发现&#xff0c;在获取配置中心配置时连接不…

SpringBoot保姆级教程(二)SpringBoot入门

目录 一.通过官网搭建项目 二.通过IDEA脚手架搭建项目 三.SpringBoot项目结构 四.通过Maven搭建项目 五.编写Java代码 一.通过官网搭建项目 接下来我们搭建一个SpringBoot项目&#xff0c;并引入SpringMVC的功能&#xff0c; 首先我们可以通过官网搭建项目&#xff1a; 1 …

MYSQL介绍——数据库的增删改及常用函数

数据操作语言——INSERT语句 Insert 语句可以向数据库中插入数据&#xff0c;可以是一条数据&#xff0c;也可以是多条数据&#xff0c;它有以下语法形式&#xff1a; 下面给出一个插入语法的示例&#xff1a; INSERT INTO t_dept(deptno,dname,loc) VALUES(50,司法部,济南)…