Mirror学习笔记(一) 简介

在这里插入图片描述

文章目录

  • 一、常规学习:
      • Mirror核心功能有
      • 服务器和主机
  • 二、时间戳批处理
      • 时间戳
  • 三、TCP和UDP
  • 四、CCU(同时在线人数)
  • 五、SyncDirection(同步方向)
  • 六、RTT(往返时间)
  • 七、Connection Quality(连接质量)
  • 八、Lag Compensation(滞后补偿)
      • 一、独立算法类LagCompensation.cs
      • 二、Log Compensator组件
  • 九、Client Side Prediction(客户端预测)
  • 十、History Bounds(历史边界)


一、常规学习:

Mirror是一个用于Unity多人游戏的功能系统。它允许在其中一个参与者同时承担服务器的功能,因此不需要专用的服务器进程从而减少了开发人员的工作量。

Mirror核心功能有

1.消息处理程序
2.通用高性能序列化
3.分布式对像管理
4.状态同步
5.服务器与客户端的各种链接等.

服务器和主机

1.服务器是游戏的一个实例,所有客户端与其链接。由服务器对数据进行处理并回传给各客户端展示。
2.服务器可以是“专用服务器”也可以是“主机服务器”。
“专用服务器”仅作为服务器支行游戏实例。
“主机服务器 “当没有专用服务器时,即充当服务器也充当客户端。
下图代表了三个玩家。在游戏充当了主机也就是本地客户端,并且两者在同一客户端支行。另外两个是远程客户端。
在这里插入图片描述

因为主机与本地服务器在同一进程中,因而可以使用“特殊”的通讯方便直接调用方法和消息。
远端客户端则通过常规的网络通讯与服务器交互,Mirror会自动处理这些工作。

多人游戏系统目标之一是使服务端、客户端代码相同。因而多数时候你只需要考虑一种类型的客户端,Mirror将会自动处理差异。

二、时间戳批处理

你发送的每条消息将被批处理直至当前帧结束,以最大程度的减少传输的消耗。消息中将会把大量的小消息合并为一条进行发送。
客户端和服务端都会进行批处理以最大化的减少性能消耗。

时间戳

确保远程发送消息的时序性,接收到消息后对他们之间进行插值。可以准确的知道物在服务器上,何时处于何处。
早期版本通过NetworkTransform来实现,成本巨大因为需要包含一个4字节(float),甚至8字节(double),当在大型游戏中时,宽带压力会迅速增加。
而NetworkTransform只是其中一种组件,其他的组件也可能需要时间戳,这将进一步增加宽带消耗。
为了减轻宽带压力,Mirror每个批次都包含8个字节,但并不是每条消息都包含,而是每1200个字节批出来一次,这有效减轻了宽带压力。

在客户机上,所有对象数据都以消息/批处理的形式从服务器到达。因此,在任何给定的时间,您都可以发现对象的Rpc/OnDeserialize/OnMessage处理程序何时由服务器通过NetworkClient.connection.remoteTimeStamp发送。

在服务器上,只有玩家拥有的对像才能于家连接中获得消息。因此,在任何时间,您都可以找到对像的Cmd/OnDeserialize/OnMessage处理程序,由客户端能过connectionToClient.remoteTimeStam发送

三、TCP和UDP

TPC由1970年开发,UDP由1980年引入,TCP内靠性,时序性,但延迟较高,UDP反之。

四、CCU(同时在线人数)

Mirror 可以处理多少个CCU,通常来说每个地图可以处理200CCU,但理论上是可以达到1000个。
官方尝试了一些项目480CCU时已有些卡顿,同时3D比2D的开销会更大。

五、SyncDirection(同步方向)

Mirror新增了SyncDirection功能
在这里插入图片描述

Mirror 中通常从服务器同步到客户端,但某些组件(如:NetworkTransform)需要在客户权限的情况下同步到服务器,因为OnSerialize只会从服务器到客户端,这里有几个缺点:
1.同时进行OnSerialize和手动远程调用需要大量的额外代码
2.会有额外宽带消耗,因每个命令包含一个函数哈希
3.间隔需要手动实现,因为syncInterval仅适用于OnSerialize.
因此OnSerialize提供了从客户端同步到服务器,组件提供了SyncDirection功能。

六、RTT(往返时间)

往返时间是指消息到另一端并返回的时间,由以下两个因素决定:
1.延迟:网络通过互联网传播需要时间
2.更新间隔:消息需要被处理并发送回另一端,与服务器处理时间及压力有关。
用户可以在NetworkTime.rtt查看,服务器可以在每个不同链接的NetworkServer.connection.rtt查看
如果你想在游戏中显示rtt可以使用NetworkPingDisplay

七、Connection Quality(连接质量)

Mirror的连接由三部分组成:
ConnectionQuality.cs提供了以下连接质量级别:
Public enum ConnectionQuality : byte
{
EXCELLENT, //高水平理想体验
GOOD, //非常适合所有人,高水平连接
FAIR, //非常明显卡顿,让人不愉悦
POOR, //无效的玩家
ESTIMATING, //仍在评估
}
两种发起方式:
Simple(based on Ping & Jitter)
Pragmatic( 基于快照插值)
NetworkPingDisplay
此组件可以添加到NetworkManager中,以在屏幕右下角显示ping和连接质量指示

NetworkManager回调
以覆盖CalculateConnectionQuality方式注入。可以在NetworkManager中配置。
OnConnectionQualityChanged可用于向用户显示警告,默认情况 下会发出一条日志。

八、Lag Compensation(滞后补偿)

快节奏的第一人称射击需要延迟补偿,又叫回滚。而对于MMORPG、纸牌、回合、等策略则不需要。
为什么需要回滚,假设在设计游戏中你和另一名玩家同步需要50毫秒,到达服务器需要50毫秒。这里就有100毫秒的时间差。这100毫秒里可能对方发生了位移,可能使你的设计位置不准确。
在这里插入图片描述
滞后补偿分为两部分:

一、独立算法类LagCompensation.cs

在这里插入图片描述在这里插入图片描述
该算法可以记录采样类型任何记录。
换句话说,如果你愿意,您可以根据自己的需要定制它,这是底层代码,使用高级组件会更方便。

二、Log Compensator组件

在这里插入图片描述
只需要添加下面组件,Mirror将会管理指定Collider的历史快照。
当你做为玩家在本地发射子弹时,[Command]将输入发送到服务器,这进我们不检查另一端玩家是否补击中,
而是检查另一端玩家当时的Lag Compensation(滞后补偿)
官方文档中提供了例子。

九、Client Side Prediction(客户端预测)

打开Examples/Billiards例子,选择NetworkManager -> LatencySimulation 增加一些延迟(50ms),构建选择Server Only.
在这里插入图片描述

这是一个桌球游戏,在你击打白球时,由于数据需要发送给服务器再回传我们能明显的感觉到打击感滞后。
因此我们需要要用客户端模拟预测结果,一旦服务端返回状态我们必须立马纠正它。
由于大多数物理引擎,如Unity的PhysX是不确定的。这以为着在客户端和服务端施加的力(浮点数)会有所不同,而差异会逐渐累计。

为什么不使用确定性物理引擎:
一、Unity没有
二、工作量大
三、比常规物理引擎慢

最简单回滚流程说明:
由客户端执行Rigidbody.AddForce() 同时发送给服务器端执行[Command]CmdApplyForce(force)
服务器执行wellRigidbody.AddForce(force)
服务器同步新的刚体位置到客户端,但些修正将有一定时间差,而客户端一直在进行修改。
这也以为着客户端将一直有明显的“后跳”行为。
应当如何解决因时间差带来的后跳问题呢?
由客户端执行Rigidbody.AddForce() 客户端保存刚体位置 每50ms保存一次,以便后面进去比较
在这里插入图片描述
发送给服务器端执行[Command]CmdApplyForce(force)
拿到服务端的位置后与100ms(50+50来回)前的位置进行对比矫正
这部分内容可以了解一下而已,事实上Mirror已经为我们处理完这部分内容
在客户端中使用:Predicted Rigidbody(预测刚体)插件,情况将会简单很多。
预测和修正总是很难应用在刚体上。为了固话效果组件提供了两种模式:
在这里插入图片描述
Smooth(平滑):一般开始移动,所有的物理组件(Rigidbody+Colliders)都会移动到一个不可见的Ghost对象里。
渲染器在原位置并平滑插值到Ghost对像的位置,这将提供非常平滑的结果,但创造和跟随会有更大的额外成本开销。
Fast(快速):物体保留在原来的位置上,渲染器直接移动到结果所在位置,这种方式更节约性能。

关于预测的类型可以在forecast .cs中找到它。
Mirror还可以用于其他类型的预测,但还需要了解后自行补全部分逻辑。

关于Mirror对于大型场景的预测
传统上预测算法并回滚模拟整个场景我们需要Physics.Simulate()
此方法可以最正确的模拟出结果,但性能消耗巨大,不适合用于大型场景。
Mirror经过努力兼容了大型场景的物理同及堆叠物理的同步。

十、History Bounds(历史边界)

优化延迟补偿和客户端预测,为了最小化性能开销,在我们使用的对像先对其强制使用HistoryBounds
使用方式:
将HistoryCollider添加到NetworkIdentity上
确保NetworkIdentity中有碰撞器,并拖至actualCollider中
按下播放键,启动Gizmos,注意橙色的HistoryCollider.
组件以橙色包围盒显示,这以为着您可以使用物理摄像进行物理检测。

当玩家开枪时,对所有的HistoryColliders进行射线检测,反出我们需要检测的玩家。
然后对碰撞器的父级NetworkIdentity使用延迟补偿处理,然后再检查他是否补击中。

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

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

相关文章

Android mLruProcesses的分布结构

AMS中的进程管理 final ArrayList<ProcessRecord> mLruProcesses new ArrayList<ProcessRecord>(); 在AMS的内部属性中使用mLruProcesses集合保存所有的进程信息&#xff0c;AMS将所有进程按照优先级从低到高的顺序保存着对应的ProcessRecord信息&#xff0c;即排…

25、Python之面向对象:私有属性是掩耳盗铃还是恰到好处

引言 声明&#xff0c;今天的文章中没有一行Python代码&#xff0c;更多的是对编程语言设计理念的思考。 上一篇文章中介绍了关于Python面向对象封装特性的私有属性的相关内容&#xff0c;提到了Python中关于私有属性的实现是通过“名称混淆”的方式来实现的&#xff0c;我们…

【Python体验】第五天:目录搜索、数据爬虫(评论区里写作业)

文章目录 目录搜索 os、shutil库数据爬虫 request、re作业&#xff1a;爬取案例的top250电影的关键信息&#xff08;名称、类型、日期&#xff09;&#xff0c;并保存在表格中 目录搜索 os、shutil库 os 模块提供了非常丰富的方法用来处理文件和目录。 os.listdir(path)&#x…

连环画:80、90后的童年记忆与副业项目的AI新玩法

在那个纯真的年代&#xff0c;当80、90后的孩子们还在为学业忙碌之余&#xff0c;一种名为连环画的读物成为了他们心中难以磨灭的记忆。 这些由一幅幅精美插图串联起来的故事&#xff0c;不仅满足了他们对知识的渴望&#xff0c;更在无形中丰富了他们的想象力和审美能力。在那…

智云-一个抓取web流量的轻量级蜜罐

智云-一个抓取web流量的轻量级蜜罐 安装环境要求 apache php7.4 mysql8 github地址 https://github.com/xiaoxiaoranxxx/POT-ZHIYUN 系统演示

Xilinx FPGA:vivado SPI实现FLASH通信

一、实验要求 要求使用SPI协议实现对flash芯片的页编程、读操作、页擦除等功能。 二、模块划分 大概的时序图&#xff1a; 三、程序设计 &#xff08;1&#xff09;接收端模块 timescale 1ns / 1ps module uart_rx(input sys_clk ,input …

ShardingSphere实战(2)- 水平分表

项目环境&#xff1a; JDK11 MySQL 8.0.30 Springboot 2.7.4 Mybatis ShardingSphere HikariCP 连接池 一、Maven 依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><versi…

C++ | string

前言 本篇博客讲解c中的string类的使用(常用接口) &#x1f493; 个人主页&#xff1a;普通young man-CSDN博客 ⏩ 文章专栏&#xff1a;C_普通young man的博客-CSDN博客 ⏩ 本人giee:普通小青年 (pu-tong-young-man) - Gitee.com 若有问题 评论区见&#x1f4dd; &#x1f389…

Redis持久化之RDB和AOF详解

持久化是确保 Redis 数据在服务器重启或崩溃时不丢失的关键功能。由于 Redis 是基于内存的数据库&#xff0c;如果不进行持久化&#xff0c;所有数据都存在于内存中&#xff0c;一旦服务器进程退出&#xff0c;内存中的数据就会丢失。持久化机制可以将 Redis 的数据库状态保存到…

C# Unity 面向对象补全计划 之 访问修饰符

本文仅作学习笔记与交流&#xff0c;不作任何商业用途&#xff0c;作者能力有限&#xff0c;如有不足还请斧正 本系列旨在通过补全学习之后&#xff0c;给出任意类图都能实现并做到逻辑上严丝合缝

vue3项目结构梳理:

总览 1.vscode文件&#xff1a; 通常用于存放Visual Studio Code编辑器的插件的配置 2.node_moudles文件夹&#xff1a; 这个文件夹包含了项目所需的所有npm依赖包。&#xff08;需要在根目录下执行npm i命令安装这个文件夹&#xff09; 或者在项目根目录&#xff08;packa…

postgresql密码复杂度验证和有效期

前言 为了数据库安全以及应对等保测评等要求&#xff0c;我们需要设置密码复杂度。我们通过passwordcheck模块实现复杂度检测功能。 启用密码复杂度验证 找到自己安装pg库的配置文件目录&#xff0c;修改postgresql.conf vim postgresql.conf修改如下内容 shared_preload_…

中国十大顶级哲学家,全球公认的伟大思想家颜廷利:人类为何拥有臀部

人类为何拥有臀部&#xff1f;若众生皆无此部位&#xff0c;又如何能寻得一处真正属于自己的“座位”&#xff1f;在博大精深的中国传统文化中&#xff0c;汉字“座”与“坐”均蕴含“土”字元素。在易经的智慧里&#xff0c;作为五行之一的“土”&#xff0c;象征着人类社会的…

MySQL8--用户与权限管理

原文网址&#xff1a;MySQL8--用户与权限管理_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍MySQL8的用户与权限的管理&#xff0c;包括&#xff1a;用户的创建与删除、授权与撤销权限等。 为什么要管理用户与权限&#xff1f; 目的是保证数据库的安全性&#xff0c;只授…

Unity Shader unity文档学习笔记(十八):unity雾效原理

看很多文章用近平面远平面组成矩阵后转到裁剪空间下通过Z值来解&#xff0c;实际更简单的方式可以直接通过判断距离来实现 FogMgr控制远近面 public class TestFog : MonoBehaviour {public int startDis 0;public int endDis 50;public Vector4 fogParam;public void Awak…

文件未保存后能否恢复?分享实用恢复指南,6个方法

在日常用电脑时文件未保存而导致的数据丢失&#xff0c;是许多人都会遭遇的棘手问题。那么面对这样的情况&#xff0c;文件真的能够恢复吗&#xff1f;本文将深入分析文件恢复的可能性&#xff0c;并提供一系列实用的建议。 一、了解文件恢复的基础 首先我们需要明白文件恢复并…

并发--快速查询死锁信息

使用jstack查看线程堆栈信息 jstack&#xff1a;jdk提供的一个工具&#xff0c;可以查看java进程中线程堆栈信息。 位于&#xff1a;jdk1.8.0_121\bin包下 死锁代码 public class DeadLockDemo {private static String A "A";private static String B "B"…

uniapp微信小程序本地和真机调试文件图片上传成功但体验版不成功

文章目录 导文是因为要添加服务器域名&#xff01; 导文 uniapp微信小程序本地和真机调试文件图片上传成功但体验版不成功 uniapp微信小程序体验版上传图片不成功 微信小程序本地和真机调试文件图片上传成功但体验版不成功 是因为要添加服务器域名&#xff01; 先看一下 你小程…

[Docker][Docker Image]详细讲解

目录 1.Docker镜像是什么&#xff1f;2.Docker镜像加载原理1.bootfs2.rootfs3.为什么CentOS镜像几个G&#xff0c;而Docker CentOS镜像才几百M&#xff1f;1.CentOS2.Docker CentOS 3.镜像分层1.Union FS2.分层理解3.容器层 vs 镜像层 4.镜像命令1.docker images2.docker image…

fusetech_plus项目问题解决(若依魔改系列)

首页一直出现这个问题解决&#xff0c;是因为访问入口都在admin模块&#xff0c;所以必须在admin的pom里 引入blog模块 template might not exist or might not be accessible by any of the configured Template Resolvers 这个问题 类似mapper找不到问题 路径不对&#xf…