Mirror从入门到入神

Mirror从入门到成神

文章目录

  • Mirror从入门到成神
    • 简介
    • NetworkClient
      • RegisterPrefab
      • Connect (string address)
      • Disconnect ()
      • active
      • activeHost
    • NetworkServer
      • Spawn

简介

Mirror是一个unity网络同步框架,基于MonoBehaviour生命周期的回调的基础上进行数值的同步,将通讯方式和协议剥离,顶层业务只需关注写入读取流,具体传输协议由底层不同协议实现模块完成,使用Mirror编写网络联网游戏,需要掌握分布式编程,要习惯异步的思维,一个方法执行之后无法立刻拿到结果,可以利用协程来检查或者依托特定对象生命周期,也可以使用服务器回调的形式来做,先来看看unity原本的生命周期,关键是easy to use,国外倒是挺火的,国内没啥声响,我们团队在鉴于自己的实际情况,看重的就是一套代码管理,无需额外专职后端开发(项目小)

Unity的MonoBehavior生命周期事件包括Awake、Start、FixedUpdate、Update、LateUpdate、OnEnable、OnDisable和OnDestroy。
Mirror的NetworkManager,NetworkBehavior 图片来源于官网
在这里插入图片描述

在这里插入图片描述

在Mirror中相对本身的生命周期会多几个,可以在Mirror的官网查看详情NetworkBehaviour Callbacks

为了方便理解这里我们首先抽离一个概念,客户端(Client)和服务器(Server),在mirror中他们都是同一个项目的编译产物,在源头上是共生的,内部通过一些特定的标志来判定对应的逻辑代码是否应该执行,比如扣减用户血量,这种安全性要求较高的逻辑内容理应放置到服务器中执行,也有叫前端,后端的,我们选择mirror的原因是因为可以同项目管理,不需要额外的项目和开发人员来支撑服务端,大部分的游戏逻辑都可以公用,比如游戏功能道具啊,Server发布的时候非特殊要求的情况下使用Dedicated Server的方式进行发布,如果形象的形容是Headless无头,如果接触过爬虫的就会知道 无头浏览器的概念。及没有渲染能力的游戏客户端。

启动游戏服务端的时候有几个模式,分别是Host,Server Only,Client Only。主机模式,仅启动服务端,仅启动客户端,说白了我们把游戏逻辑写道一起,如果要完成的进行游戏,就必须同时具备Server,Client 都在线的情况。Host 启动后运行服务器代码,也运行客户端代码。Server Only仅运行服务端代码,Client仅运行客户端代码,下图为Host模式的结构性说明

在这里插入图片描述

RemoteClient表示通过网络通讯协议接入的其他客户端,Local Client在Mirror中做了特殊处理,并不会走网络协议,而是直接将数据写入一个本地队列,另外还有一些执行差异,后面会提到。这里总结下能运行完整游戏的方式

  1. 以HOST模式启动
  2. 连接其他HOST模型启动的程序
  3. 连接其他Server模式启动的程序

下图展示的是数据流的流动方向,对应Spawn出来的单位,服务器和所有客户端都会存在一个实例,由Mirror控制并将对应的数据分发给这些实例对象,其中通过NetworkIdentity的NetId来区分作为全网的唯一标识(全网指的是本局游戏类,连进Server的Client组成的网络)

在这里插入图片描述

下图展示的是Mirror 的层级构成,这个图上包含的类就是Mirror的核心类,这个图最好能背下来,有利于后续的Mirror学习, 对于只是利用Mirror完成联网游戏的改造和编写只需要知道NetworkClient向下的内容,现在来介绍下这些核心组件
在这里插入图片描述

NetworkClient

负责客户端上的和服务端的网络通讯,通常对于开发人员是不需要关注的,除非有定制化的需求

完整的api文档 这里介绍下几个可能会用到的

RegisterPrefab

该函数用于注册预制体,所有需要利用Mirror进行动态生成单位,都需要完成预制体的注册,有两种方式一种是在NetworkManager中RegisteredSpawnablePrefabs列表中添加对应的预制体,要添加成功需要该预制体存在NetworkIdentify组件,否则无法添加,也可以点击Inspector界面的PopulateSpawnablePrefabs,该功能可以自动扫描当前项目中所有添加了NetworkIdentify的预制体,能够自动将预制体添加到列表中,这里很容易犯一个小错误,如果预制体的名字一致,但是错误提示没有注册,可以检查是否是名字一样实则不同的预制体,方式二就是点在运行期间通过

RegisterPrefab (GameObject prefab, Guid newAssetId, SpawnHandlerDelegate spawnHandler, UnSpawnDelegate unspawnHandler)

该方法进行注册,需要注意的是注册的预制体需要在各个端都存在,否则注册之后会出问题。后面的SpawnHander UnSpawnDelegate 可以拦截系统的Spawn 和UnSpawn事件,找一个很容易理解的例子 Instantiate (实例化)Desotry (销毁)。客户端在收到UnSpawn默认的行为是Desotry掉,如果想要池化联网对象,就需要依靠上面的SpawnHander方法,另外该方法一个AssetId只能调用一次,不可以重复调用,如果需要替换请使用其他方法,该方法还有其他的重载,想要细致了解的化可以查看官方文档

Connect (string address)

链接远程服务器,address地址通过是一个ip,具体的端口信息在Transport.active中持有,通过这种方式可以修改端口,也就说明了Transport.active是单例的

    if (Transport.active is PortTransport portTransport)
    {
        // use TryParse in case someone tries to enter non-numeric characters
        portTransport.Port = ushort.Parse(port);
    }

根据源码具体看看这部分是怎么做的

     public static void Connect(string address)
     {
         Initialize(false);

         AddTransportHandlers();//
         connectState = ConnectState.Connecting;
         Transport.active.ClientConnect(address);
         connection = new NetworkConnectionToServer();
     }

Transport是一个接口interface,不同的传续协议都会实现,这里我们抽一个KcpTransport看一下

在这里插入图片描述

//KcpTransport.cs#ClientConnect

public override void ClientConnect(string address)
{
    client.Connect(address, Port);
}
//KcpConnect.cs#ClientConnect
 public void Connect(string address, ushort port)
 {
     if (connected)
     {
         Log.Warning("[KCP] Client: already connected!");
         return;
     }

     // resolve host name before creating peer.
     // fixes: https://github.com/MirrorNetworking/Mirror/issues/3361
     if (!Common.ResolveHostname(address, out IPAddress[] addresses))
     {
         // pass error to user callback. no need to log it manually.
         OnError(ErrorCode.DnsResolve, $"Failed to resolve host: {address}");
         OnDisconnectedCallback();
         return;
     }

     // create fresh peer for each new session
     // client doesn't need secure cookie.
     Reset(config);

     Log.Info($"[KCP] Client: connect to {address}:{port}");

     // create socket
     remoteEndPoint = new IPEndPoint(addresses[0], port);
     socket = new Socket(remoteEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
     active = true;

     // recv & send are called from main thread.
     // need to ensure this never blocks.
     // even a 1ms block per connection would stop us from scaling.
     socket.Blocking = false;

     // configure buffer sizes
     Common.ConfigureSocketBuffers(socket, config.RecvBufferSize, config.SendBufferSize);

     // bind to endpoint so we can use send/recv instead of sendto/recvfrom.
     socket.Connect(remoteEndPoint);

     // immediately send a hello message to the server.
     // server will call OnMessage and add the new connection.
     // note that this still has cookie=0 until we receive the server's hello.
     SendHello();
 }

当然也可以调用Connect的其他重载

// 	Connect client to a NetworkServer by address. More...
static void 	Connect (string address)
//Connect client to a NetworkServer by Uri. More...
static void 	Connect (Uri uri)
//字如其名
static void 	ConnectHost ()

Disconnect ()

断开连接

active

在不想将MonoBehavior 改成NetworkBehavior时非常有用,使用NetworkBehavior可以在对象内使用isServer,IsClient来判断是否是服务器,还是客户端,但是这会增加带宽的负担,及时一个变量都不需要同步,所以该静态变量在全局判断时非常有用

activeHost

联网游戏存在单机模式,我们用Mirror变成完成之后使用Host模式即可将游戏变为单机模式,这里有一个技巧即可以使用 NetworkServer.dontListen = true;来不启动端口监听。因为Host模式调用远程ClientRpc时,时不会执行的,还有Spawn事件也不会执行,所以需要依靠这些判断该字段来附加执行属于Host的业务逻辑

NetworkServer

接下来看看NetworkServer,听名字就知道这个东西适合服务器相关的,这个普通开发人员也不需要关注,但是任然需要对他有所了解,如果是在不想管,那就记一个方法就行Spawn

Spawn

// 	Spawn the given game object on all clients which are ready. More...
static void 	Spawn (GameObject obj, NetworkConnection ownerConnection=null)
// 	Spawns an object and also assigns Client Authority to the specified client. More... 
static void 	Spawn (GameObject obj, GameObject ownerPlayer)
// 	Spawns an object and also assigns Client Authority to the specified client. More... 
static void 	Spawn (GameObject obj, Guid assetId, NetworkConnection ownerConnection=null)

一般使用他的流程是,在服务端上执行,首先实例化某个Prefab,Instantiate创建好GameObject obj = Instantiate(Prefab),在设置好属性位置啥的(除了transform以外其他都需要是同步属性,否则需要在客户端自行设置)然后调用NetworkServer.Spawn(obj)这样就可以把obj同步给所有端了。第二个 第三个参数是为了标识当前这个obj是属于那个客户端的,该逻辑会在Client2Server的传输模式非常有用,客户端会自行判断如果自己是owner就会同步数据给服务器,否则会直接跳过数据传输部分,服务器也会校验该对象是否允许客户端进行修改。服务器具有权威性,从游戏的数据安全角度考虑,Mirror设计了自己的鉴权逻辑,后面会说到。

Client2Server是数据传输的方向,该方向仅仅对 OwnerClient与Server之间有影响,其他关系都是客户端接收服务器的同步

ClientRpc 是一种注解,可以明确告知Mirror这是一个存在与客户端上的远程方法,Mirror会自动根据方法名调用所有客户端 对应对象的obj执行

未完待续…

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

刷题之找到字符串所有字母异位词

找到字符串所有字母异位词 滑动窗口。滑动窗口大小为待比较数组的大小。 class Solution { public:vector<int> findAnagrams(string s, string p) {//滑动窗口vector<int>result;if(s.size()<p.size())return result;vector<int>pnum(26,0);//记录p的字…

[第五空间 2021]WebFTP

目录扫描git泄露phpinfo.php 一开始想到是sql注入&#xff0c;但是不行。目录扫描&#xff0c;发现 .git 和 phpinfo.php 访问phpinfo.php&#xff0c;ctrlf 搜索 flag&#xff0c;找到 flag。

【风变】Python爬虫精进复习-20240430

参考笔记 下面给出一个巨佬学习风变pyhton基础语法和爬虫精进的笔记&#xff08;链接&#xff09; 风变编程笔记(一)-Python基础语法 风变编程笔记(二)-Python爬虫精进 技术总结 request BeautifulSoup selenium BeautifulSoup 练习0-1&#xff1a;文章下载 import requ…

TypeScript学习日志-第二十六天(weakMap,weakSet,set,map)

weakMap,weakSet,set,map 一、set set 的基本用法如下&#xff1a; 二、map map 与 set 的 区别 就是 map 的 key 可以是引用类型 object array , map 的添加时使用 set 三、weakmap weakset weakmap和weakset 都是弱项 弱引用 其键必须是引用类型&#xff0c;不能是其它类…

【C/C++笔试练习】DNS劫持、三次握手、TCP协议、HTTPS、四次挥手、HTTP报文、拥塞窗口、POP3协议、UDP协议、收件人列表、养兔子

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;DNS劫持&#xff08;2&#xff09;三次握手&#xff08;3&#xff09;TCP协议&#xff08;4&#xff09;HTTPS&#xff08;5&#xff09;四次挥手&#xff08;6&#xff09;HTTP报文&#xff08;7&#xff09;拥塞窗口&a…

网优干货:ACP交付详解版(3)

1. 全局指标分析 点击GIS页面左侧的 按钮&#xff0c;展开指标树&#xff0c;可查看各项优化目标的当前值、预测值和差值。 拖动指标树中的某个指标到GIS页面&#xff0c;可呈现该指标的整体分布。GIS页面共有两个半屏&#xff0c;用户可以做优化前后相同指标的对比&#xff0c…

从CSDN搬家到微信公众号

博主将会在微信公众号里不断输出精品内容&#xff0c;陪伴大家共同成长。 如果你对博主的经历感兴趣&#xff0c;或者对博主的IT技术感兴趣&#xff0c;欢迎关注我的微信公众号&#xff0c;阅读我的技术文章&#xff0c;免费获取各种IT资源。也可以加我的微信成为我的好友&…

【Javaer学习Python】 1、Django安装

安装 Python 和 PyCharm 的方法就略过了&#xff0c;附一个有效激活PyCharm的链接&#xff1a;https://www.quanxiaoha.com/pycharm-pojie/pycharm-pojie-20241.html 1、安装Django # 安装Django pip install Django# 查看当前版本 python -m django --version 5.0.62、创建项…

ollama离线部署llama3(window系统)

首先介绍下ollama是什么&#xff1f;Ollama是一个开源的大型语言模型服务工具&#xff0c;旨在为用户提供本地化的运行环境&#xff0c;满足个性化的需求。具体来说&#xff0c;Ollama是一个功能强大的开源框架&#xff0c;可以简化在Docker容器中部署和管理大型语言模型&a…

24深圳杯C题18页高质量论文+可执行代码+图表

比赛题目的完整版思路可执行代码数据参考论文都会在第一时间更新上传的&#xff0c;大家可以参考我往期的资料&#xff0c;所有的资料数据以及到最后更新的参考论文都是一次付费后续免费的。注意&#xff1a;&#xff08;建议先下单占坑&#xff0c;因为随着后续我们更新资料数…

2024年5月中,AITOP100平台活动专区迎来六场AI大赛盛事!

AITOP100平台的活动专区在2024年5月中旬更新的6场AI大赛来了&#xff01; 随着人工智能技术的飞速发展&#xff0c;AI设计已经成为了创新与创意的新领域。2024年5月中旬&#xff0c;由腾讯研究院、剪映、站酷等互联网大厂主办的6场AI设计大赛震撼来袭&#xff0c;为广大AI设计…

文本到语音的学习笔记:从Docker开始

1.docker 是什么意思&#xff1f; Docker 是一种开源的容器化平台&#xff0c;它允许开发者将应用及其依赖打包到一个轻量级、可移植的容器中&#xff0c;然后可以在任何支持Docker的系统上运行这个应用&#xff0c;而不必担心环境差异导致的问题。 以下是Docker的一些关键特…

【接口测试_03课_-接口自动化思维梳理及Requests库应用】

一、通过代码&#xff0c;实现Jmeter 1、项目要放在虚拟环境里面&#xff0c;解释器要使用虚拟环境的 上面是虚拟环境&#xff0c;下面是系统环境。2选一 venv目录 查看当前虚拟环境已存在的依赖包 2、安装Requests依赖包 1&#xff09;安装命令 pip install requests 如果…

Windows Server 2022 环境下WEB和DNS服务器配置方法

目录 实验名称&#xff1a;WEB和DNS服务器配置实验目的实验原理&#xff1a;主要设备、器材&#xff1a;实验内容&#xff1a;配置本地WEB站点配置本地DNS服务器 实验名称&#xff1a;WEB和DNS服务器配置 实验目的 掌握 Windows Server 2022 环境下WEB服务器配置方法 掌握 Wi…

RT Thread + CLion环境搭建

RT Thread CLion环境搭建 0.前言一、准备工具1. Env RT Thread v5.12.CLion安装3.编译及下载工具 二、新建Env工程三、CLion配置四、运行测试 0.前言 事情的起因是最近在使用RT Thread Studio时&#xff0c;发现默认的 rtt 内核版本及交叉编译链版本都过于陈旧&#xff0c;于…

【科研】常用的实验结果评价指标(2) —— MAE 是什么? !

了解MAE 提示&#xff1a;先说概念&#xff0c;后续再陆续上代码 文章目录 了解MAE前言一、MAE 基本概念1. MAE 是什么&#xff1f;2. MAE 的起源3. MAE 的计算公式 二、MAE的适用场景是什么&#xff1f;三、MAE 的劣势&#xff0c;或 不适用于那些场景或者数据&#xff1f;四、…

2024成都现代职业教育及装备展6月1日举办 免费参观

2024成都现代职业教育及装备展6月1日举办 免费参观 同期举办&#xff1a;中国西部职业教育产教融合高峰论坛 主办单位&#xff1a; 中国西部教体融合博览会组委会 承办单位&#xff1a;重庆港华展览有限公司 博览会主题&#xff1a;责任教育 职教兴邦 组委会&#xff1a;…

ssti学习(1)

一、成因&#xff1a; 渲染模板时&#xff0c;没有严格控制对用户的输入。&#xff08;使用了危险的模板&#xff0c;导致用户可以和flask程序进行交互&#xff09; flask是一种基于web开发的web服务器&#xff0c;如果用户可以和flask交互&#xff0c;则可以执行eval、syste…

嵌入式学习-通用定时器

简介 框图介绍 时钟选择 计数器部分 输入捕获和输出比较框图 嵌入式学习全文参考&#xff08;小向是个der&#xff09;做笔记&#xff1a;https://blog.csdn.net/qq_41954556/article/details/129735708

Runes 生态一周要览 ▣ 2024.5.06-5.12

1、香港「Runes Asia 2024」符文峰会之行圆满结束。 2、BEVM 宣布首次大规模 RUNES 空投现已结束&#xff01;符文桥即将上线。 3、来自 Book of Blob 的交互式视听信息铭刻了第一个 Epic Sat 在 coinex 上市交易。 4、 Binance Research 发布了对 Runes 的报告。 5、HOPE•…