当前位置:网站首页>Unity metaverse (III), protobuf & socket realize multi person online
Unity metaverse (III), protobuf & socket realize multi person online
2022-07-29 05:04:00 【CoderZ1010】
List of articles
Protobuf
brief introduction
Google Protocol Buffer( abbreviation
Protobuf) yes Google The company is a portable and efficient structured data storage format , Can be used as dataserializeTools , Often used forCommunication protocol, AndJson、XMLcomparison ,Protobuf The advantage isHigher performance, It's smaller 、 faster , With efficientBinary systemWay to store , The generated binary messages are very compact , Therefore, the number of bytes transmitted on the network is less .
Use
We use Protobuf As a communication protocol , Creating a protocol class requires the following steps :
- Write according to grammar rules
.protofile ; - By compiling tools
protoc.exetake .proto File compiled into .cs file ;
To write .proto file
The rules of grammar are as follows :
- Use
messageDefining classes , amount to c# Mediumclass; - Use three field modifiers to decorate fields :
- required It means a
MandatoryField , Must be initialized ; - optional It means a
OptionalField , It can be done without initialization ; - repeated Indicates that the field can contain multiple elements , It can be seen as passing a
ArrayValue ;
- required It means a
- Field type , And
C#The corresponding relationship is as follows :
| proto | c# | remarks |
|---|---|---|
| bool | bool | Boolean type |
| string | string | String type |
| double | double | 64 Bit floating point |
| float | float | 32 Bit floating point |
| int32 | int | 32 An integer |
| uint32 | uint | Unsigned 32 An integer |
| int64 | long | 64 An integer |
| uint64 | ulong | Unsigned 64 An integer |
| sint32 | int | Coding is more than usual int32 Efficient |
| sint64 | long | Coding is more than usual int64 Efficient |
| fixed32 | uint | Unsigned 32 An integer |
| fixed64 | ulong | Unsigned 64 An integer |
| sfixed32 | int | Always 4 Bytes |
| sfixed64 | long | Always 8 Bytes |
| bytes | ByteString | Bytes of data |
- Field identification number
Each field has a unique
Identification number, These identifiers are used to identify each field in the binary format of the message , After useCan't change.[1,15] The identification number in the code will occupy1 byte.[16,2047] The ID number inside is occupied2 byte, So it should be reserved for those frequent message elements [1,15] Identification number inside .notes: Not available [19000-19999] Identification number ,protobuf These are reserved in the protocol implementation .
for example , We need to define AvatarProperty The protocol class is right Avatar Character attributes communicate ,proto The documentation is as follows
message AvatarProperty
{
required string userId = 1;
required int32 avatarId = 2;
required string name = 3;
required float posX = 4;
required float posY = 5;
required float posZ = 6;
required float rotX = 7;
required float rotY = 8;
required float rotZ = 9;
required float speed = 10;
}
compile .proto file
- function
cmd,cdopenprotoc.exeLocation path


- Enter the compile command
protoc -I=./ --csharp_out=./ AvatarProperty.proto

After successful compilation , You can see AvatarProperty.cs The file has been generated to the directory , Import it into Unity Then you can .

notes:AvatarProperty.csfrom protobuf The compiler tool generates , Import to Unity After thatDo not modify the.
Socket
We go through Socket TCP Realize network communication , Using my small development framework SKFramework Network communication module in :

SKFrameworkFramework open source address :Github - SKFramework
The client sends Avatar data
// Send once every certain interval Avatar data
timer = Timer.EverySeconds(interval, () =>
{
if (GameServer != null)
{
var ap = new AvatarProperty()
{
UserId = UserId,
PosX = AvatarController.transform.position.x,
PosY = AvatarController.transform.position.y,
PosZ = AvatarController.transform.position.z,
RotX = AvatarController.transform.eulerAngles.x,
RotY = AvatarController.transform.eulerAngles.y,
RotZ = AvatarController.transform.eulerAngles.z,
Speed = AvatarController.Instance.Speed,
};
// send data
GameServer.Send(ap);
}
});
timer.Launch();
TimerThe module isSKFrameworkTiming tools in the framework , You can also usePackaga Managerdownload ,EverySecondsIndicates how many seconds the callback function is executed , Here we willinternalSet to0.025, That is to say 1 Seconds will be sent 40 Time data , It can be adjusted appropriately .
Client reception Avatar data
After the client receives the message from the server , The message content will be passed The event system Make a throw :
// Throw a message
Messenger.Publish(msg.name, msg.content);
MessengerIt isSKFrameworkThe event system in the framework ,PublishMeans to publish a message , The first parameter represents the of the messageThe theme, The second parameter represents the... Of the messageContent.
The subscription topic is AvatarProperty The news of , When the news of this topic is released , Subscription events OnAvatarPropertyMsgEvent Will be executed .
// subscribe AvatarProperty news
Messenger.Subscribe<ByteString>(typeof(AvatarProperty).Name, OnAvatarPropertyMsgEvent);
stay OnAvatarPropertyMsgEvent Incident , According to the news user ID Judge the corresponding Avatar Whether the character instance exists , If it does not exist, create and initialize :
private void OnAvatarPropertyMsgEvent(ByteString bs)
{
// Deserialization
var ap = AvatarProperty.Parser.ParseFrom(bs);
if (!avatarDic.ContainsKey(ap.UserId))
{
// Receive this for the first time Avatar data First create Avatar figure
var instance = Object.Instantiate(Resources.Load<AvatarInstance>(typeof(AvatarInstance).Name));
// Deposit in Avatar Dictionaries
avatarDic.Add(ap.UserId, instance);
// initialization
instance.Init(ap);
}
// The goal is Avatar
avatarDic[ap.UserId].Set(ap);
}
AvatarInstance After receiving data , Use interpolation to calculate coordinates 、 rotate , And synchronization Animator Animation information :
using UnityEngine;
using UnityEngine.UI;
using SK.Framework;
namespace Metaverse
{
/// <summary>
/// Avatar example
/// </summary>
public class AvatarInstance : MonoBehaviour
{
public string UserId {
get; private set; }
[SerializeField] private Animator animator;
[SerializeField] private Canvas worldCanvas;
private Vector3 targetPos;
private Vector3 targetRot;
private const float lerpSpeed = 5f;
/// <summary>
/// initialization
/// </summary>
/// <param name="ap"></param>
public void Init(AvatarProperty ap)
{
UserId = ap.UserId;
Camera mainCamera = Camera.main != null ? Camera.main : FindObjectOfType<Camera>();
worldCanvas.worldCamera = mainCamera;
// mount Face2Camera Components Keep it always facing the camera
worldCanvas.GetComponent<Face2Camera>().Set(mainCamera, false, false);
worldCanvas.GetComponentInChildren<Text>().text = UserId;
}
/// <summary>
/// receive data
/// </summary>
/// <param name="ap"></param>
public void Set(AvatarProperty ap)
{
targetPos = new Vector3(ap.PosX, ap.PosY, ap.PosZ);
targetRot = new Vector3(ap.RotX, ap.RotY, ap.RotZ);
animator.SetFloat("Speed", ap.Speed);
}
private void Update()
{
// Interpolation operation
transform.position = Vector3.Lerp(transform.position, targetPos, Time.deltaTime * lerpSpeed);
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(targetRot), lerpSpeed);
}
}
}
Face2CamerabySKFrameworkA component tool in , Its function is to make objects alwaysTowards the camera.


synchronicity :

边栏推荐
- AttributeError: ‘module‘ object has no attribute ‘create_connection‘
- Reply from the Secretary of jindawei: the company is optimistic about the market prospect of NMN products and has launched a series of products
- Understand activity workflow
- Sguard64.exe ace guard client exe: frequent disk reading and writing, game jamming, and Solutions
- How does WPS use smart fill to quickly fill data? WPS method of quickly filling data
- roLabelImg转DATO格式数据
- 金达威董秘回复:公司看好NMN产品的市场前景,已推出系列产品
- IOS interview preparation - Online
- P2181 diagonal
- Leetcode (Sword finger offer) - 53 - I. find the number I in the sorted array
猜你喜欢

Torch.nn.crossentropyloss() details

What if the computer cannot open excel? The solution of Excel not opening

What if the office prompts that the system configuration cannot run?

ODOO开发教程之透视表

Jackson解析JSON详细教程

The song of the virtual idol was originally generated in this way!
![Academic | [latex] super detailed texlive2022+tex studio download installation configuration](/img/4d/f8c60c0fbbd98c4da198cfac7989fa.png)
Academic | [latex] super detailed texlive2022+tex studio download installation configuration

Flink+iceberg environment construction and production problem handling

Flink+Iceberg环境搭建及生产问题处理
![[untitled]](/img/6c/df2ebb3e39d1e47b8dd74cfdddbb06.gif)
[untitled]
随机推荐
Activity workflow table structure learning
Use annotation test in idea
荣耀2023内推,内推码ambubk
MySQL定时调用预置函数完成数据更新
P1009 [noip1998 popularization group] sum of factorials
电脑无法打开excel表格怎么办?excel打不开的解决方法
带你搞懂 Kubernetes 集群中几种常见的流量暴露方案
Excel卡住了没保存怎么办?Excel还没保存但是卡住了的解决方法
Excel怎么筛选出自己想要的内容?excel表格筛选内容教程
【微信小程序】swiper滑动页面,滑块左右各露出前后的一部分,露出一部分
How does WPS use smart fill to quickly fill data? WPS method of quickly filling data
JS daily question (12)
Simple user-defined authentication interface rules
搭建手机APP需要用到什么服务器
Introduction to auto.js script development
Reveal安装配置调试
EF core: one to one, many to many configuration
优炫数据库启动失败,报网络错误
C language implementation of three chess
PHP determines whether the user has logged in. If logged in, the home page will be displayed. If not, enter the login page or registration page