上篇文章介绍了FlatBuffer描述文件编写和转换,本篇介绍Lua代码中如何实现协议的序列化和反序列化操作。另外为了可以在Unity中可以执行Lua代码,把XLua插件导入测试工程。
测试脚本
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;
/*
* Author:W
* Lua脚本中关于FlatBuffer协议的序列化与反序列化操作
*/
public class ReadAndWriteTest2 : MonoBehaviour {
private LuaEnv luaEnv;
void Awake()
{
luaEnv = new LuaEnv();
luaEnv.AddLoader(CustomLoader);
luaEnv.DoString("require('LuaReadAndWrite')");
}
/// <summary>
/// 自定义Lua文件加载器
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private byte[] CustomLoader(ref string pFileName)
{
pFileName = pFileName.Replace('.', '/');
string fileName = pFileName + ".lua";
if (Application.isEditor)
{
string luaPath = (Application.dataPath + "\\LuaFiles\\" + fileName).Replace("\\", "/");
return File.ReadAllBytes(luaPath);
}
return null;
}
void OnDestroy()
{
if (luaEnv != null)
luaEnv.Dispose();
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
LuaReadAndWrite测试代码如下:
--引入flatbuffers
local flatbuffers = require("flatbuffers")
--引入转换生成Lua协议文件
local weapon = require("MyGame.Sample.Weapon")
local monster = require("MyGame.Sample.Monster")
local vec3 = require("MyGame.Sample.Vec3")
local color = require("MyGame.Sample.Color")
local equipment = require("MyGame.Sample.Equipment")
-- 创建Builder
local builder = flatbuffers.Builder(1024)
--[[序列化]]--
-- 武器1序列化
local weaponOne = builder:CreateString("Sword")
weapon.Start(builder)
weapon.AddName(builder, weaponOne)
weapon.AddDamage(builder, 3)
local sword = weapon.End(builder)
-- 武器2序列化
local weaponTwo = builder:CreateString("Axe")
weapon.Start(builder)
weapon.AddName(builder, weaponTwo)
weapon.AddDamage(builder, 5)
local axe = weapon.End(builder)
--武器数组序列化
monster.StartWeaponsVector(builder, 2)
builder:PrependUOffsetTRelative(sword)
builder:PrependUOffsetTRelative(axe)
local weapons = builder:EndVector(2)
--背包物品序列化
monster.StartInventoryVector(builder, 2)
for i=2,1,-1 do
builder:PrependByte(i)
end
local inv = builder:EndVector(2)
--路径数组序列化
monster.StartPathVector(builder, 2)
vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
vec3.CreateVec3(builder, 4.0, 5.0, 6.0)
local path = builder:EndVector(2)
-- 怪兽名称序列化
local name = builder:CreateString("Orc")
-- 怪兽序列化
monster.Start(builder)
--位置
monster.AddPos(builder, vec3.CreateVec3(builder, 1.0, 2.0, 3.0))
--血量
monster.AddHp(builder, 300)
--名称
monster.AddName(builder, name)
--物品
monster.AddInventory(builder, inv)
--颜色
monster.AddColor(builder, color.Red)
--武器
monster.AddWeapons(builder, weapons)
--已装备的武器
monster.AddEquippedType(builder, equipment.Weapon)
monster.AddEquipped(builder, axe)
--路径
monster.AddPath(builder,path);
local orc = monster.End(builder)
builder:Finish(orc)
--获取buffer字符串【存储、网络传输】
local bufAsString = builder:Output()
--[[反序列化]]--
local buf = flatbuffers.binaryArray.New(bufAsString)
local mon = monster.GetRootAsMonster(buf, 0)
print("monster Mana="..mon:Mana())
print("monster Hp="..mon:Hp())
print("monster Name="..mon:Name())
print("monster Color="..mon:Color())
print("monster Pos X="..mon:Pos():X())
print("monster Pos Y="..mon:Pos():Y())
print("monster Pos Z="..mon:Pos():Z())
for i=1,mon:InventoryLength() do
print("monster inventory="..mon:Inventory(i))
end
for i=1,mon:WeaponsLength() do
print("monster weapon name="..mon:Weapons(i):Name().." damage="..mon:Weapons(i):Damage())
end
local unionWeapon = weapon.New()
unionWeapon:Init(mon:Equipped().bytes,mon:Equipped().pos)
print("monster equipped name="..unionWeapon:Name().." damage="..unionWeapon:Damage())
运行结果如下
项目Demo工程下载地址:链接:https://pan.baidu.com/s/1yBd9aTg9jVDemuBB9n7cNw 提取码:2cce