Protobuf的使用以及介绍

1.Protobufd的概念

Protocol Buffers(简称 Protobuf)是一种用于序列化结构化数据的语言无关、平台无关、可扩展的机制。它由 Google
开发,用于解决数据交换和持久化的问题。Protobuf 定义了一种简单的语言来描述数据结构,然后使用这个描述生成用于序列化数据的代码。

2.Protobuf的使用

  • 先去https://github.com/protocolbuffers/protobuf/tree/main/csharp将Probuf源码下载下来
    在这里插入图片描述
    将它下载到项目文件夹里
    在这里插入图片描述
    打开它的源码
    在这里插入图片描述
    打开之后重新生成解决方案
    在这里插入图片描述
    他会提示有6个成功
    在这里插入图片描述
    如果你没有下载相关库,vs会有提示信息,下载安装就好了
    在这里插入图片描述
    在这里插入图片描述
    如若控制台还报错缺少库,可以直接去官网下载相关的库

将这三个文件拷贝到Unity的Plugin文件夹里面
在这里插入图片描述
在这里插入图片描述
最后在Unity项目中创建一个ProtoHelper脚本实现序列化和反序列化的接口

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Google.Protobuf;
using System;

public class ProtoHelper : MonoBehaviour
{
    //protobuf序列化接口
    public static byte[] ToBytes(object message)
    {
        return ((Google.Protobuf.IMessage)message).ToByteArray();
    }
    //反序列化接口
   public static T ToObject<T>(byte[] bytes) where T : Google.Protobuf.IMessage
    {
        var message = Activator.CreateInstance<T>();
        message.MergeFrom(bytes);
        return message;
    }
   
}

然后将这个类拷贝到你的服务端代码
在这里插入图片描述
创建一个protocol-buffers文件夹
在这里插入图片描述
结构如下
在这里插入图片描述
vs安装Google.protobuf.Tools,打开如下面板,在搜索框输入Google.protobuf.Tools,找到之后直接安装
在这里插入图片描述
zai
安装成功控制台会提示,文件夹里面会有这个包
在这里插入图片描述
在这里插入图片描述
将这个Window64位的protoc.exe拷贝到之前创建的protocol-buffers下的tool
在这里插入图片描述
在这里插入图片描述
这里有两个批处理文件,这个批处理脚本的作用是编译 Protocol Buffers (.proto) 文件为 C# 代码,使用了 protoc.exe 这个工具。内容如下:

@echo off

set "PROTOC_EXE=%cd%\tool\protoc.exe"
set "WORK_DIR=%cd%\ProtoFile"
set "CS_OUT_PATH=%cd%\cs"
::if not exist %CS_OUT_PATH% md %CS_OUT_PATH%

for /f "delims=" %%i in ('dir /b protoFile "ProtoFile/*.proto"') do (
   echo gen protoFile/%%i...
   "%PROTOC_EXE%"  --proto_path="%WORK_DIR%" --csharp_out="%CS_OUT_PATH%" "%WORK_DIR%\%%i")
echo finish... 

pause

解释:
@echo off:

这行指令告诉批处理关闭命令回显,这意味着在运行脚本时不会在屏幕上显示命令本身,只会显示执行结果。

set “PROTOC_EXE=%cd%\tool\protoc.exe”

这行设置了一个变量 PROTOC_EXE,它指向了 protoc.exe 的路径,该路径位于当前目录下的 tool 文件夹中。

set “WORK_DIR=%cd%\ProtoFile” 和 set “CS_OUT_PATH=%cd%\cs”

这两行分别设置了两个变量,WORK_DIR 指向了 ProtoFile 文件夹的路径CS_OUT_PATH 指向了 cs 文件夹的路径。

::if not exist %CS_OUT_PATH% md %CS_OUT_PATH%

这一行是一个注释,原本可能是用于检查输出路径是否存在,如果不存在则创建该路径。但由于前面已经注释掉了,所以这行代码不会执行。

for /f “delims=” %%i in (‘dir /b protoFile “ProtoFile/*.proto”’) do (…)

这行开始一个 for 循环,它遍历 ProtoFile 文件夹下所有的 .proto 文件。

echo gen protoFile/%%i…

这行会打印当前正在处理的 .proto 文件的路径。

%PROTOC_EXE% --proto_path=“%WORK_DIR%” --csharp_out=“%CS_OUT_PATH%” “%WORK_DIR%%%i”

这行是真正调用 protoc.exe 的命令,它将当前 .proto 文件编译为 C# 代码,然后输出到指定路径。参数–proto_path 指定了 .proto 文件的搜索路径,–csharp_out 指定了生成的 C# 代码的输出路径。

echo finish…

这行会在编译完成后打印 “finish…”。

pause: 这行会让脚本暂停,等待用户按下任意键继续,这样可以让用户看到脚本的输出结果。

打开D:\Unity 2023.1.20f1c1\NetProject\protocol-buffers\ProtoFile\PlayerMessage文件
在这里插入图片描述
点击批处理_GenAllC#.bat将cs文件生成出来
在这里插入图片描述
PlayerMessage.cs里面就会有相关字段的定义
在这里插入图片描述
将PlayerMessage.cs文件拷贝到unity中进行检验

在这里插入图片描述
在GameManger中加入一段代码

if (Input.GetKeyDown(KeyCode.S))
{

    LoginS2C loginS2C = new LoginS2C();
    loginS2C.Account = "xxx";
    loginS2C.Password = "yyy";
    loginS2C.Test.Add(1);
    loginS2C.Test.Add(2);
    loginS2C.Test.Add(3);
    loginS2C.Test.Add(4);
    byte[] data = ProtoHelper.ToBytes(loginS2C);

    Debug.Log(data.Length);

    LoginS2C loginS2C_test = ProtoHelper.ToObject<LoginS2C>(data);
    var act = loginS2C_test.Account;
    var pwd = loginS2C_test.Password;
    Debug.Log(act+" "+pwd);
}

GameObject就变成这样了

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Client.Instance.Start();

        var loginPrefab = Resources.Load<GameObject>("LoginView");//加载Resources/LoginView目录下的一个预制体
        var loginView = GameObject.Instantiate<GameObject>(loginPrefab);//实例化这个预制体
        loginView.AddComponent<LoginView>();//将LoginView脚本挂载在这个实例化的对象上
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.A)) {

            Client.Instance.Send(Encoding.UTF8.GetBytes("login..."));
        }
        if (Input.GetKeyDown(KeyCode.S))
        {

            LoginS2C loginS2C = new LoginS2C();
            loginS2C.Account = "xxx";
            loginS2C.Password = "yyy";
            loginS2C.Test.Add(1);
            loginS2C.Test.Add(2);
            loginS2C.Test.Add(3);
            loginS2C.Test.Add(4);
            byte[] data = ProtoHelper.ToBytes(loginS2C);

            Debug.Log(data.Length);

            LoginS2C loginS2C_test = ProtoHelper.ToObject<LoginS2C>(data);
            var act = loginS2C_test.Account;
            var pwd = loginS2C_test.Password;
            Debug.Log(act+" "+pwd);
        }
       
    }
}

当运行unity按下S键之后,会出现这样的结果
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值