Mirror学习笔记(五)概念指南

news2024/11/13 0:35:19

在这里插入图片描述

文章目录

  • 一、Authority(权限)
  • 二、IDs(身份编号)
  • 三、Attributes(属性)
  • 四、Time Synchronization(同步时间)
  • 五、Data types(数据类型)
  • 六、Serialization(序列化)
  • 七、Synchronization(同步)
  • 八、Communications(通讯)
  • 九、GameObject(游戏对象)


顶层脚本API:
Mirror是一个高级网络库,这以为着他包含了多人游戏常见的多数命令,使用都无需关心各中实现细节。
Mirror允许 :
1.使用Network Manager控制游戏网络状态
2.操作客户端游戏,其中主机也是玩家客户端。
3.使用通用序列化程序,序列化数据
4.发送和接受网络消息
5.将网络命令从客户端发送到服务器端
6.进行服务器到客户端的远程调用
7.将网络事件从服务器发送到客户端


底层脚本API:
Mirror需要底城的Transport才能在byte[]级别上连接/断开/发送/接收消息
引擎和编辑器集成
Mirror的网络集成在引擎和编辑器中,允许您使用组件和视频工具来构建您的多人游戏,它提供了以下功能:
1.用于网络对像管理的组件 :NetworkIdentity。
2.用于网络的脚本 :NetworkBehaviour.
3.对像转换可以配置自同步。
4.脚本变量的自动同步。
5.支持Unity场景中䛂不联网对象。
6.网络组件


一、Authority(权限)

Network Authority 权限是决定谁拥有一个对象控制权的标志。
服务端权限
意味为着由服务端控制该对象,一般用于控制移动平台,npc和其他非玩家网络对像。
客户端权限
意味着由客户端控制该对象,当客户端断开连接时该对像将自动销毁。
及时客户端拥有权限,服务器仍可以通过SyncVar控制其并序列化功能。组件将需要使用命令来更新服务器上的状态与其他客户端同步。
如何赋予权限
默认情况情况情况下,服务器对所有对像具有权限。服务器可以授予客户端需要的对象控制权限,比如你的玩家对象。
如果您使用NetworkServer.AddPlayerForConnection生成一个玩家对象,那么它将自动获得权限。
使用NetworkServer.Spawn
你可以在生成对象时授予客户端权限,这是通过将连接传递给生成消息来完成的
GameObject go = Instantiate(parfab);
NetworkServer.Spawn(go,connectionToClient);
使用identity.AssignClientAuthority
在你可以随时 使用AssignClientAuthority向客户端授予权限。这可以通过在要授予权限的对象上调用AssignClientAuthority来完成。
identity.AssignClientAuthority(conn);
当玩家拿物品时 ,你可以这样做:
void CmdPickupItem(NetworkIdentity item){
Item.AssignClientAuthority(connectionToClient)
}
如何移除权限:
你可以使用identity.RemoveClientAuthority从客户端移除权限。
无法从玩家对象中移除权限。相反你必须使用NetworkServer.ReplacePlayerForConnection替换player对象。
当给予或从对像中移除权限时,将向该客户端发送一条消息通知他们。这时候OnStartAuthority或OnStopAuthority函数。
检查权限:
客户端 : 使用identity.hasAuthority可以检查本地玩家是否具有权限。
服务端 : 可以使用identity.connectionToClient查看哪个客户端是否有权限。


二、IDs(身份编号)

Asset Id(资产ID)
Mirror使用GUID作为 Asset Id。每个带有Network Identity组件的prefab都有一个Asset Id,它是Unity的AssetDatabase.AssetPathToGUID转换为16字节。Mirror需要用他来知道生成哪些预制体。

Scene Id(场景ID)
Mirror使用uint作为场景ID.场景(层次结构)有NetworkIdentity组件的都在OnPosProcessScene中分配一个场景ID。Mirror需要它来区分场景对象,因为Unity没有针对场景中不同游戏对象的唯一ID

Network Instance id(网络实例Id)
Mirror将uint用于NetId.每个NetworkIdentity都会在NetworkIdentity.OnStartServer中或在生成NetId。Mirror在客户端和服务器之间传递消息使用id来判断哪个对象是消息的接收者。

Connection Id
每个网络连接都有一个连接id,由底层(传输层)分配。当服务器/主机连接id o时为本地连接。


三、Attributes(属性)

网络属性将添加到网络成员函数中,以使它们 在客户端或服务端上运行。
这些属性可以用于Unity游戏方法(如Start或Update)以及其他方法中。
当使用抽象方法或虚方法时,属性也需要应用于覆盖方法。

[Server] : 只有服务器可以调用该方法
[ServerCallback] : 与Server相同,但在客户端不会发出警告
[Client] : 只有客户端可以调用该方法
[ClientCallback] : 与Client相同,但服务器不会发出警告
[Command] : 从客户端调此函数时上运行此函数。
[ClientRpc] : 服务端使用远程调用(RPC)在客户端上运行该函数。
[SyncVar] : 用于将变量从服务器自动同步到所有客户端。不要从客户端分配他们这是没有意义的。不可以为空,会报错。你可以使用
int,long,float,string,vector3等所有简单类型,和Network Identity和游戏对象(如有Identity).

当客户端接收到来自服务器的更新时,可以使用SyncVar Hooks在客户端运行代码。


四、Time Synchronization(同步时间)

对于许多算法你需要在客户端和服务器之间同步时间。Mirror会自动为您操同步。
如要获取当前时间,请使用以下代码:

double now  = NetworkTime.time;

它将在客户端和服务器中返回相同的值,它从0开始,时间是double类型,绝不应该投身到浮点数上。将其转换为浮点数上将会失去一定精度。
Mirror还将计算应用程序看到的RTT(往返时间):

double rtt = NetworkTime.rtt;

您可以测量准确性:

double time_standard_deviation = NetworkTime.timeSd;

如何返回0.2则表示时间测量值上下摆动大概0.2秒
通过使用EMA平滑值 来补偿网络间隔。
您可以家只发送ping的频率:

NetworkTime.PingFrequency = 2 ;

您可以配置计算中使用的ping结果数:

NetworkTime.PingWindowSize = 10;

五、Data types(数据类型)

客户端可以与服务器通过“远程操作”,"状态同步"或"网络消息"的方式相互传递数据
Mirror支持多重可用于数据类型,包括:

1.基本的Unity C#类型 : btye、short、int 、long、unit、ushort、ulong、float、double、char、string 等…

2.内置Unity 数据类型 : Vector3、Quaternion、Reck、Plane 等…

3.内置的Unity类型 即后台结构 Color、Sprite Texture2D、Ray 等…

4.URI (统一资源标识)

5.NetworkIdentity,NetworkBehaviourl
–5.1这些不应该在SyncVal或Sync*中使用,因为如果对像尚未生成,它们在客户端中将为空。

6.具有NetworkIdentity的网络对象(不是预制体)

7.具有上述任何一项结构
–7.1 你必须提花整个结构值,而不仅仅是更改其属性值
–7.2 建议用IEquatable以避免装箱,并将结构是指为只读,因为修改参数值不会重新同步

8.在类中,只要每个字段都有支持的数据类型
–8.1 必须替换整个类值,而不仅仅是更改期属性
–8.2 这将产生垃圾,因为每次分配时都会在接收器上重新实例化

9.ScriptableObject 只要每个字段都有接受支持的数据类型
–9.1 这将产生垃圾,因为每次分配时都会在接收器上重新实例化

10.上述任何一荐的数组
–SyncVars或SyncLists不支持

11.上太空任何一个的ArraySegments

Game Object(游戏对象)
SyncVars、SyncLists和SyncDictionaries中的游戏对像在某些情况并不可靠,用应慎重使用。
只要游戏对象在服务器和客户端上都存在,引用就不会有问题。
当同步数据到达客户端时,该客户端上可能还不存在引用的游戏对象,从而导致同步数据值为空。
这是因为内部Mirror从NetworkIdentity传递netId并尝试在客户端的NetworkIdentity.spawned字典中查到它。
如果该对象还没在客户端生成,找不到匹配的对象。它可以在相同的有效负载中,特别是对于加入的客户端,但在另一个对象同步数据后。
游戏对象由于网络可见性问题,它也可能是空的
你可能会发现,同步NetworkIdentity.netId(uint)并执行管理局 查找以获取对象会更可靠,也许可以使用协程NetworkClient.spawned查找获得对象。
在这里插入图片描述
Custom Data Types(自定义数据类型)
有时候你不想使用Mirror类型生成序列化,则可以通过 NetworkWriter和NetworkReader来添加支持的类型。
例如要对DataTime添加内容,可以参考以下例子:
在这里插入图片描述

然后你可以使用DateTime 在你的[Command] 或 SyncList

Inheritance and Polymorphism (继承 和 多态)
有时候您可能希望发送多态类型的数据命令。出于安全原因Mirror不会序列化类型名称以保持消息较小,因此Mirror无法通过查看来确定接收的类型。
以下代码不是开箱即用的
在这里插入图片描述

如果为类型提供自定义序列化程序,CmdEquipu将会起作用。例如:

ScriptableObjects
人们通常希望从客户端或服务端发送可以编写脚本的对对象。例如,你可能创建一堆可编辑脚本的对象,并且将装备的脸放在这里同步。
Mirror将通过ScriptableObject为脚本生成一个读取器和写入器。创建实力并封复制所有数据。

然而生成reader和writer并不适合所有场合。可编辑脚本的对象通常会引用其他资源,例如texture、prefab或其他无法序列化的类型。可编写脚本的对象通常存在Resources文件夹中。

可编写脚本对象有时候会包含大量数量,导致生成和写入器可能无法正常工作。
你可以传递名称,而不传递可编辑脚本的对象数据,而另一方面可以按名称 查找相同的对象。这样您可以在可编辑脚本对象中拥有的任何类型数据。可以通过提供自定义读取器和写入器来做。
在这里插入图片描述


六、Serialization(序列化)

Mirror使用Weaver为类型创建Serialize(序列化)和Deserialize(反序列化)函数。Weaver在unity中使用Mono.Cecil编译 dll后编辑他们。这使得Mirror有许多复杂的功能,例如SyncVar、ClientRpc和消息。而无需要用户手动设置所有内容。


七、Synchronization(同步)

状态同步是指脚本对Int、float、string和bool值进行同步。
状态同步是从服务器到远程客户端完成的。本地客户端没有序列化到它的数据,它不需要,因为它与服务器共享场景。但是在本地客户端上用SyncVar挂钩。
数据不会以相反方向同步(从远端到服务器).炙此您只需要使用命令。

SyncVars : 是继承自NetworkBehaviour脚本的变量,从服务器同步到客户端
SyncEvents(Obsolete) : 类型于ClientRpc网络事件,但它们是会在游戏对像上调用函数,而是出发事件。18.0.0版本后弃用。
SyncLists : 包含值列表并将数据从同步到客户端。
SyncDictionary : 是一个关联数组,其中包含键值对的无序列表
SyncHashSet : 一组不重复无序值。
SyncSortedSet : 一组排序的不重复值

同步到所有者:
假设场景中有50个人,都有各自的背包。这时候玩家A拾取了一个道具。
这时Mirror默认会将此道具同步到场景中50个玩家A的背包中,然后其他玩家并不能看到获取的内容,这很浪费,也是个安全问题。
如果这里你将Inventory组件中的Setwork Sync Mode设置为Owner则玩家A的库存将仅与客户端A同步。
典型的例子是包括任务、纸牌、技能、经验等不需要别的客户端知道的消息。

高级状态同步:
多数情况下,SyncVars足够装状态同步到序列化客户端。但是某些下可能需要更为浮渣的序列化代码。此页面仅适用于需要自定义同步解决方法的高级开发人员。
超出了Mirror常规的SyncVar功能。

自定义同步状态:
使用自定义同步状态,可以在NetworkBehaviour上实现于SyncVar序列号的虚函数。这些函数包括:
在这里插入图片描述

使用该标志可以区分首次和后续系列化,首次同步时必须有完整状态快照后面则不用,有助于节省宽带。


八、Communications(通讯)

多人游戏开发时,除了同步网络游戏对像的属性外,你可能还要发送和信息。在Mirror网络传输中,有三种主要的方式来传达此类信息。
远程操作:
远程操作允许您通过网络用脚本中的方法。您可以专门在“所有的客户端"或"单个客户端"上创建"服务器"调用方法。还可以让客户端用服务器上的方法,使用远程操作,您可以将数据作为参数传递 给你的方法,与本地调用非常类似。
Network Callback(网络回调):
网络回调允许您 挂载在游戏过程中发生的内置Mirror事件,例如玩家加入或离开时、游戏对象创建或销毁时,你可以实现两种网络回调:
网络管理回调,用于本身相关的回调(例如客户端连接或断开连接时)
网络行为回调,用于与单个网络对像相关的调用(例如,当它的Start 函数被调用时,或是新玩家加入时需要做特定的事)
网络消息:
网络消息是发送消息的"低级"方法(尽管它们扔被归类为网络高级API的不部分)。它们允许您使用脚本直接在客户端和服务器之间发送数据。
可以发送数据类型(int、string、及unity基本类型Vector3等).由于您自己实现了这个,这些消息不会直接与任何特定的游戏对象或unity相关联。


九、GameObject(游戏对象)

网络游戏对像是由Mirror的网络系统控制同步。使用同步联网对像您 可以为别的客户端创建共享的内容。
Mirror中的多人游戏通常使用包含游戏对象和常规游戏对象的场景构建。

联网游戏对像是在游戏过程中需要在所有一起玩游戏的相互间需要同步移动或改变参数的对象。
非联网游戏对像在游戏过程 中完全不移动或变化的,如场景中的山,岩石,树木、云等。

网络对像是附加了网络身份组件的对象。但并不是只有网络身份对象就能起作用。Network Identity组件是同步的起点为它允许网络管理器同步创建销毁,别的参数同步没有指定。

网络游戏中每个对像如何同步,取决于游戏类型及对像的用途。您可能想要同步的一些内容比如是:
1.移动及放置
2.动画游戏对象的动画状态
3.参数的值

其中一些东西可以通过Mirror自动同步。联网游戏对像的同步创建和销毁由NetworkManager管理,称为Spawning.
可以使用Network Transform组件来同步放置,也可以使用Network Animator来同步游戏的动画。
同步参数变量则需要你用脚本实现。

游戏玩家对象:
Mirror处理玩家游戏与非玩家的方式不同。当新玩家加入游戏时(或连接到服务器时),该玩家的游戏成为该玩家客户端上的本地玩家游戏对象。

Unity为每个玩家关联一个玩家对象,并将网络命令路由到该单独的游戏对象。玩家不能在其他玩家游戏上调用命令,只能在自己的对象上调用命令。

NetwrokBehaviour类(用于创建网络脚本的派生类),有个isLocalPlayer属性。在每个客户端玩家对像上Mirror在NetworkBehaviour脚本上该属性为true.并调用OnStartLocalPlayer()回调。
这以为着每表客户端都有个与此不同的对象,因为在每个客户端上一个不同的为本地玩家,余都是别的玩家。
可以通过isLocalPlayer判断是否本地玩家,设置摄像头跟进。
默认情况下新玩家加入NetworkManager组件会自动创建玩家预设,要精致创建可以取消勾选AutoCreate Player.

自定义角色生成:
Mirror允许用户对默认玩家进行自定义.默认情况 下会为你创建预设,你可以使用自定义继承NetworkManager进行修改。

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

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

相关文章

Qt信号与槽-思维导图-学习笔记

Qt 信号与槽 Qt 信号与槽机制 基本概念 信号与槽机制:Qt 编程的基础与创新,使得处理界面组件交互操作更加直观和简单 信号(Signal):在特定情况下被发射的事件,如按钮点击的 clicked() 信号、组合框项变化…

服务器数据恢复—服务器raid常见故障产生原因数据恢复方案

磁盘阵列(raid)是一种将多块物理硬盘整合成一个虚拟存储的技术。raid模块相当于一个存储管理中间层,上层接收并执行操作系统及文件系统的数据读写指令,下层管理数据在各个物理硬盘上的存储及读写。相对于单独的物理硬盘&#xff0…

超算互联网-Stable Diffusion 2.1文生图教程

一、名词简介 1. 超算互联网 超算互联网是一种基于云计算的高性能计算平台,用户可以通过互联网接入超级计算资源。它集成了大量的计算节点,提供强大的计算能力,适用于科学计算、深度学习、人工智能等领域。用户可以利用超算互联网平台运行复…

Neural Architecture Search:使用Ultralytics框架进行YOLO-NAS目标检测

Neural Architecture Search:使用Ultralytics框架进行YOLO-NAS目标检测 前言相关介绍前提条件实验环境安装环境项目地址LinuxWindows 使用Ultralytics框架进行YOLO-NAS目标检测进行预测进行验证 参考文献 前言 由于本人水平有限,难免出现错漏&#xff0c…

旧照片如何修复翻新?这3个方法值得收藏

旧照片如何修复翻新?旧照片的修复翻新是一项既具有挑战性又充满意义的工作。它不仅仅是一个简单的图像处理过程,更是一次穿越时空的旅行,让那些被岁月遗忘的珍贵回忆重新焕发光彩。每一张旧照片都承载着独特的历史和情感价值,通过…

CTF-PWN-web pwn初探

文章目录 参考简介生命周期php扩展模块搭建php扩展模块初始化编写扩展模块编译扩展模块测试 检查调试相关技巧/proc/self/maps泄露php堆PHP 内存管理机制空闲堆块管理示例解释1. 内存分配示例2. 内存释放示例3. tcache poison 攻击 溢出mprotect改栈权限反弹shell 常用phpexp 参…

[Pytorch案例实践008]基于卷积神经网络和通道注意力机制的图像分类实战

一、项目介绍 这是一个蜜蜂、蚂蚁图像分类项目,旨在使用卷积神经网络(CNN)结合SE(Squeeze-and-Excitation)模块进行二分类任务。以下是项目的详细介绍: 项目背景 图像分类是计算机视觉中的一个基本任务&a…

一图看懂数据仓库、数据平台、数据中台、数据湖的内涵和区别!

当大数据平台出现的时候,有人是说这不就是大号的数据仓库吗?当数据中台出现的时候,有人说这不就是数据仓库的进一步包装吗?数据湖的出现更是让很多人陷入困惑。 事实上,数据仓库、数据平台、数据中台、数据湖还是有区别的,不仅…

算法 三

堆 满二叉树:节点满的。 完全二叉树定义:最下层从左往右满,不跳。 下标性质 大根堆:某个节点为根节点,其下的所有结点都小于根节点。 小根堆 重要的变量 heapSize:当前堆的有效节点个数 重要的两个过程…

RCE-无字母数字绕过正则表达式

目录 一、源码展示 二、分析源码 2.1异或运算 2.2或运算 2.3取反运算 一、源码展示 <?php error_reporting(0); highlight_file(__FILE__); $code$_GET[code]; if(preg_match(/[a-z0-9]/i,$code)){die(hacker); } eval($code); 二、分析源码 根据源码&#xff0c;我…

数据治理:国家标准 GB/T 43697-2024《数据安全技术 数据分类分级规则》

按照国家数据分类分级保护有关要求,参照本文件制定本行业本领域的数据分类分级标准规范,重点可明确以下内容: 明确行业数据分类细则,确定数据分类所依据的业务属性,给出按照业务属性划分的数据类别:分析行业领域数据的领域、群体、区域、精度、规模、深度、重要性等分级要素…

设计模式-单一职责模式

DecoratorBridge Decorator 动机 在某些情况下我们可能会 “过度地使用继承来扩展对象的功能”&#xff0c;由于继承为类型引入的静态特质&#xff0c;使得这种扩展方式缺乏灵活性&#xff1b;并且随着子类的增多&#xff08;扩展功能的增多&#xff09;&#xff0c;各种子类的…

基于RK3568+FPGA医用心电监护仪解决方案

医用心电监护仪解决方案 随着我国老龄化速度加快、规模扩大&#xff0c;越来越多民生领域的热点引起民众的关注。庞大的老龄化群体将是一个严峻的问题&#xff0c;各种社会保障政策的实施和各级医疗资源的扩展与升级正在有效化解这一难题。 在这种背景下&#xff0c;医用心电监…

如何构建一个帮助你高效学习编程的完美笔记系统?

在编程学习的过程中&#xff0c;笔记记录是一项至关重要的技能。尤其是在学习Python这样一门功能强大、广泛应用的编程语言时&#xff0c;建立一个高效的笔记系统不仅能帮助你更好地掌握知识&#xff0c;还能提高你的编程效率。那么&#xff0c;如何构建一个帮助你高效学习Pyth…

Java面试八股之消息队列有哪些协议?各种协议有哪些具体实现

消息队列有哪些协议&#xff1f;各种协议有哪些具体实现 消息队列协议是指在消息队列系统中&#xff0c;用于消息的发送、接收和管理的一套通信规则。不同的协议有着不同的特性和应用场景&#xff0c;以下是一些常见的消息队列协议及其具体实现&#xff1a; AMQP (Advanced M…

【leetcode】杨辉三角 、移除元素(Java语言描述)

杨辉三角 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRows 1 输出: [[1]] …

SecureCoding in C and C++(二)

经过上期的环境搭建过后&#xff0c;我们将正式的学习C系列&#xff0c;首先要学习的是C的一些常用的变量 从编译和连接学起似乎也是不错的选择。 个人总结的一句话&#xff1a;编译其实就是对预处理语句进行处理后&#xff0c;然后对语句进行处理。对预处理语句&#xff0c;例…

C++——list列表容器经典案例——手机按销量降序排列,若销量相同则按价格降序排列

需求&#xff1a;使用list列表对商品进行排序&#xff0c;先通过销量降序排&#xff0c;若销量相同则根据价格升序排列输出 涉及到的知识点&#xff1a;list列表容器、自定义数据类型、自定义排序规则 实现步骤&#xff1a; 1&#xff0c;自定义数据类型Product&#xff0c;…

Android 实现多进程通讯(如何实现多进程开发,Binder、AIDL)

目录 1&#xff09;为什么App需要多进程 2&#xff09;什么是多进程开发? 3&#xff09;如何实现多进程开发&#xff1f; 4&#xff09;跨进程间通讯(案例) 5&#xff09;多进程需要注意什么问题&#xff1f; 6&#xff09;多进程的底层原理是什么&#xff1f;【待写】 …

【Python机器学习】树回归——使用Python的tkinter库创建GUI

机器学习给我们提供了一些强大的工具&#xff0c;能从未知数据中抽取出有用的信息。因此&#xff0c;能否这些信息以易于人们理解的方式呈现十分重要。如果人们可以直接与算法和数据交互&#xff0c;将可以比较轻松的进行解释。其中一个能够同时支持数据呈现和用户交互的方式就…