Unity之NetCode多人网络游戏联机对战教程(6)--NetworkTransform组件

文章目录

    • 前言
    • NetworkTransform是什么
    • 玩家移动脚本
    • NetworkTransform字段讲解
      • Synchronizing ("Syncing")
      • Thresholds
      • Local space
      • Interpolation
      • Slerp Position
      • Use Quaternion Synchronization
      • Use Quaternion Compression
      • Use Half Float Precision
      • Authority modes
        • Server Authoritative Mode
        • Owner Authoritative Mode
      • Additional Virtual Methods of Interest
    • 后话
    • 官方链接

前言

这次教程主要是讲同步两个玩家的位置信息的一个非常重要的组件NetworkTransform,以及这个组件的作用与说明。


NetworkTransform是什么

同步物体的Transform是Netcode当今多人游戏中最常见的任务之一。这个概念似乎很简单:

  • 确定您要同步的变换轴。
  • 序列化这些值。
  • 将序列化的值作为消息发送给所有其他连接的客户端。
  • 处理消息并反序列化值。
  • 将这些值应用到适当的轴上。

乍一看,上面列出的任务似乎相对简单,但当您开始实现每个任务时,几乎任何经验丰富的Netcode软件工程师都会同意:这可能迅速变得复杂。

例如,上面列出的任务并没有考虑以下几点:

  • 谁控制同步(即每个客户端、服务器或者根据要同步的对象而定可能两者都控制)?
  • 以何种频率同步这些值,以及确定何时需要同步这些值的逻辑应该是什么?
  • 如果您有复杂的父子关系层次结构(父变换带有一个或多个子变换),是应该同步世界空间轴值还是本地空间轴值?
  • 如何优化每次变换更新的带宽成本?

幸运的是,Netcode for GameObjects (NGO) 提供了NetworkTransform组件的实现,它处理了一些变换同步的棘手方面,并可以通过在编辑器中的检视面板中访问的属性轻松配置。


玩家移动脚本

Package Manager --> 左上角+号旁边的包 选择Unity Registry, 搜索Cinemachine 下载并导入

PlayerMove移动到Scripts,在预制体Player上添加该脚本



NetworkTransform字段讲解

Synchronizing (“Syncing”)

这个是用来指定同步位置,旋转,缩放的,需要同步哪些值就勾选哪些

一般情况下,不需要同步GameObject的所有变换值。例如,如果GameObject的缩放从不改变,可以在面板中的Syncing Scale禁用。禁用同步可以节省CPU成本和网络带宽。

Thresholds

您可以使用阈值值来设置最小阈值。这可以用来通过只同步大于或等于阈值值的变化(低于阈值的变化不会同步)来降低同步更新的频率。例如:

如果NetworkTransform启用了插值(Interpolate),您可能会发现可以降低位置阈值的分辨率(增加位置阈值值),而不影响对象运动的"平滑度",同时还减少位置更新的频率(减少每个实例的带宽成本)。增加阈值分辨率(降低位置阈值值)会增加对象的位置同步的潜在频率(可能会增加每个实例的带宽成本)。

阈值值不会被同步,但可以在authoritative实例上进行更新。在使用所有者authoritative模式的实例时,应该牢记这一点,因为更改所有权将使用新所有者实例上当前设置的任何值。如果您计划在运行时更改阈值值并计划更改所有权,那么您可能需要同步阈值值。

Local space

默认情况下,NetworkTransform世界空间同步对象的变换。In Local Space配置选项允许您改为在本地空间中同步变换。子对象的本地空间轴值(主要是位置和旋转)始终是相对于父变换的偏移。而子对象的世界空间轴值包括父对象的轴值。

在具有父对象的NetworkTransform上使用本地空间可以改善在对象重新父对象化时的变换同步,因为重新父对象化不会改变对象的本地空间变换,但会改变世界空间位置。

authoritative实例确实会同步对LocalSpace属性的更改。因此,您可以在运行时在authoritative实例上调整此属性,而非authoritative实例将自动更新。

Interpolation

默认情况下启用了插值(·Interpolation·),如果您希望在非authoritative实例上的变换更新之间实现平滑的过渡,这是推荐的设置。插值会缓冲传入的状态更新,这可能会在authoritative实例和非authoritative实例之间引入轻微的延迟。当禁用插值属性时,变换的更改会立即应用到非authoritative实例上,这可能会导致视觉上的"抖动",或者在延迟较高时似乎会"跳跃"到新应用的状态更新。

在权威实例上在运行时更改插值属性将与所有非权威实例同步。

NetworkTransform组件仅在客户端上进行插值。为了在主机或服务器上实现更平滑的移动,用户可能还希望在服务器端实现插值。尽管服务器不会受到网络引起的抖动影响,但仍然可能会在本地出现一些卡顿(例如,在FixedUpdate中进行的低物理更新率的移动)。

Slerp Position

当设置了这个属性并且同时启用了插值(Interpolation),非authoritative实例将通过Slerp而不是Lerp朝着它们的目标位置插值。通常,这可以在对象遵循圆形和/或基于样条的运动路径时使用,以保留该路径的曲线性。由于在两点之间进行"lerp"插值会在两点之间的线上产生线性进展,因此在某些情况下,位置状态更新的频率可能会导致对象运动曲线的损失。

Use Quaternion Synchronization

默认情况下,使用欧拉角值来同步旋转增量。对于许多情况,使用欧拉角值可能就足够了。然而,有些情况下,同步欧拉角增量会产生不希望的结果。一个情况是当您有复杂的嵌套NetworkTransforms,其中父子变换之间的旋转不同。当您将插值结合在一起(记住插值是有缓冲的,在非权威的当前旋转和目标旋转之间存在固有的延迟时),立即发生在Quaternion中的调整会处理更复杂的变换相关问题(例如吉姆巴锁等)。

启用Quaternion同步时,权威实例仍然会根据欧拉轴值与阈值值进行比较,以确定是否需要更新变换的旋转,但是会更新整个Quaternion,而不仅仅是检测到变化的欧拉轴。这意味着可以确保正确的旋转将应用于非权威实例,并且已经考虑到了使用欧拉角时可能出现的更复杂问题。

Quaternion同步是有代价的。它会增加带宽成本,每个实例增加16字节,以处理更复杂的旋转问题,这种问题在使用嵌套的NetworkTransform(一个或多个父变换和一个或多个子变换)时更常见。但是,当您启用Use Quaternion Synchronization属性时,您会注意到在同步轴选择复选框和一个新的Use Quaternion Compression属性会出现:

当启用Use Quaternion Synchronization时,不再提供旋转同步轴复选框(因为同步变换的四元数将始终更新所有旋转轴),而Use Quaternion Compression成为可见选项。

Use Quaternion Compression

由于同步四元数可能会增加NetworkTransform旋转状态更新的带宽成本,因此有两种方法可以减小四元数同步的总体带宽成本:

  • 四元数压缩(Quaternion Compression):这提供了最高的压缩率(每次更新减少到4字节),但精度损失略高于半浮点精度。

  • 半浮点精度(Half Float Precision):当启用并且禁用四元数压缩时,这提供了中等级别的替代压缩(每次更新减少到8字节),比完全浮点值的精度低,但比四元数压缩的精度高。

四元数压缩是基于最小三算法的,当旋转精度不如带宽成本重要时,可以使用它。您可能有需要某种形式的旋转同步的附属对象/抛射物,但在项目的整体方案中不需要完美对齐。

如果带宽成本和精度都是问题,那么备选的推荐压缩方法是半浮点精度。此外,建议尝试不同的压缩选项,您可能会发现精度的部分损失对于项目的需求是完全可以接受的(并且可以减小所有实例的总体带宽成本,最多减少50%的带宽成本,而不使用完全精度时)。

此属性值可以在权威实例在运行时进行更新,并将同步到所有非权威实例。提醒:在authoritative实例上在运行时更新此值将导致NetworkTransform的完全同步,所有非authoritative实例的插值器将被重置。

Use Half Float Precision

启用此属性将会将任何变换轴值从4字节浮点数转换为2字节半浮点数,但会以精度损失为代价。启用此选项时,所有标记为同步的变换轴都将使用半浮点精度。然而,关于位置和旋转,半浮点精度有一些独特的方面。

由于存在精度损失,位置状态更新仅提供相对于上一个已知完整位置的位置增量。NetworkDeltaPosition可序列化结构会跟踪上一个已知完整位置和当前与上一个已知完整位置的当前增量偏移之间的当前增量。此外,NetworkDeltaPosition会在发送更新时自动纠正精度损失。从先前更新的精度损失将包含在下一个位置更新中。换句话说,非authoritative实例可以在1个tick周期的持续时间内或直到接收到下一个变换状态更新之前,潜在地与authoritative实例具有来自每次应用的更新的分数增量。此外,NetworkDeltaPosition填补了半浮点值的最大值与Unity世界空间的最大边界(全局/项目缩放相关)之间的差距。

推荐的Unity世界空间单位每秒:
每个更新的最大增量不应超过64个Unity世界空间单位。如果您使用默认的tick(30),那么对象不应以等于或超过每秒1920个Unity世界空间单位的速度移动(即30 x 64)。作为参考,默认摄像机的远裁剪平面是1000个Unity世界空间单位,这意味着以1920个Unity世界空间单位的速度移动的物体可能不会在渲染视锥体中被视觉检测到,或者会以短暂的"闪烁"出现。

当启用Use Quaternion SynchronizationUse Half Float Precision并且禁用Use Quaternion Compression时,四元数值通过HalfVector4可序列化结构进行同步,其中每个轴值(x、y、z和w)都存储为半浮点值。这意味着每个旋转更新从完全精度的每次16字节减少到每次8字节。对于旋转,使用半浮点精度提供了比四元数压缩更好的精度,带宽成本是其两倍,但是只有完全精度的一半成本。

当启用Use Quaternion SynchronizationUse Half Float PrecisionUse Quaternion Compression时,四元数压缩将用于代替半浮点精度的旋转。

当在authoritative实例上进行更新时,所有这些属性都将同步到非authoritative实例。

Authority modes

Server Authoritative Mode

默认情况下,NetworkTransform在服务器authoritative模式下运行。这意味着服务器端检测到要同步的变换轴(标记为同步),并将其推送给连接的客户端。这也意味着对变换轴值的任何更改都将被authoritative状态(在这种情况下是服务器端的变换状态)覆盖。

还有一个关于轴同步与初始同步的变换值的概念需要牢记。未标记为同步的任何轴在NetworkObject被生成或客户端第一次同步时仍会被更新为authoritative的初始状态。

举个例子:
假设您只标记了位置和旋转轴来同步,但在NetworkTransform组件的网络预制上排除了所有缩放轴。当您生成网络预制的实例时,初始的权威方缩放值将在生成时同步。从那时起,非authoritative实例(在这种情况下是客户端实例)将保持相同的缩放轴值,即使它们不再更新。

Owner Authoritative Mode

(又名:ClientNetworkTransform)

服务器端权威的NetworkTransform在同步转换和在所有连接的客户端上应用更新之间提供了平衡。然而,有时您希望特定NetworkObject(通常是玩家)在客户端上立即更新位置。NetworkTransform的所有者权威由NetworkTransform.OnIsServerAuthoritative方法决定,该方法在首次初始化NetworkTransform组件时调用。如果该方法返回true(默认值),则它将初始化为服务器权威的NetworkTransform。如果返回false,则它将初始化为所有者authoritativeNetworkTransform(也称为ClientNetworkTransform)。这可以通过从NetworkTransform派生,覆写OnIsServerAuthoritative虚拟方法,并像下面的代码示例中一样返回false来实现:

using Unity.Netcode.Components;
using UnityEngine;namespace Unity.Multiplayer.Samples.Utilities.ClientAuthority
{/// <summary>/// 用于同步客户端端的变换更改。这包括主机。不支持纯服务器作为所有者,请使用NetworkTransform。/// 用于那些始终由服务器拥有的Transform。/// </summary>[DisallowMultipleComponent]public class ClientNetworkTransform : NetworkTransform{/// <summary>/// Used to determine who can write to this transform. Owner client only./// This imposes state to the server. This is putting trust on your clients. Make sure no security-sensitive features use this transform./// </summary>protected override bool OnIsServerAuthoritative(){return false;}}
}

ClientNetworkTransform示例:

选择Window --> Package Manager来打开包管理器。

Add(+) --> 从git URL添加…

复制并粘贴以下Git URL:https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop.git?path=/Packages/com.unity.multiplayer.samples.coop#main

或者修改项目的manifest.json,添加

"com.unity.multiplayer.samples.coop": "https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop.git?path=/Packages/com.unity.multiplayer.samples.coop#main"

该Transform将所有者客户端的位置与服务器和所有其他客户端同步,从而实现客户端authoritative的游戏玩法。

Additional Virtual Methods of Interest

NetworkTransform.OnAuthorityPushTransformState: 此虚拟方法在权威实例正在将新的NetworkTransformState推送给非authoritative实例时调用。这可以用于更精确地确定用于预测相关任务的非authoritative实例的更新值。

NetworkTransform.OnNetworkTransformStateUpdated: 此虚拟方法在非权威实例接收来自authoritative实例的推送NetworkTransformState更新时调用。这可以用于更精确地确定用于预测相关任务的非authoritative实例的更新值。

NetworkTransform.Awake: 为了提供自定义初始化的能力,此方法已被设置为虚拟方法。如果您覆盖此方法,建议首先调用base.Awake()

NetworkTransform.OnInitialize: 此虚拟方法在相关的NetworkObject首次生成以及所有权更改时调用。

NetworkTransform.Update: 为了提供您对派生NetworkTransform类进行任何自定义的能力,此方法已被设置为虚拟方法。如果您覆盖此方法,要求所有非authoritative实例调用base.Update(),但对于authoritative实例则不是必须的。


后话

有了NetworkTransform这个组件可以为位置同步省了很多功夫,后面讲NetworkTransform的实战应用

官方链接

https://docs-multiplayer.unity3d.com/netcode/current/components/networktransform/

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

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

相关文章

Excel中截取特殊字符之前、之间、之后的数据

1、第一个数据&#xff0c;“*” 之前的数据&#xff0c; 公式 &#xff1a;LEFT(J2,FIND("*",J2)-1) 2、第二个数据&#xff0c;两个 “*” 之中的数据&#xff0c; 公式 &#xff1a;MID(J2,FIND("*",J2)1,FIND("*",J2,FIND("*",…

ZZULIOJ 1108: 打印数字图形(函数专题) (C/C++)

1108: 打印数字图形&#xff08;函数专题&#xff09; 题目描述 从键盘输入一个整数n(1≤n≤9),打印出指定的数字图形。要求在程序中定义并调用如下函数&#xff1a;PrintSpace(m)用来输出m个空格&#xff1b;PrintDigit(m)来输出一行中的数字串"12…m…21"&#xff…

IP协议汇总

IP协议 1.基本概念 IP协议全称为“网际互连协议&#xff08;Internet Protocol&#xff09;” ,IP协议是TCP/IP体系中的网络层协议。 总的来说&#xff0c;IP协议的最重要功能是提供了一种标准化的方式来路由和传输数据包&#xff0c;以实现全球互联网上的通信。 &#xff…

图的结构模板及遍历

图&#xff1a;由点的集合和边的集合组成。 常用的表示图的方法有两种&#xff1a; 1、邻接表法 将一个点的邻居都列出来。有向图只列出从这个点出发向外发散的点 2、邻接矩阵法 将点集列出一列行&#xff0c;列出一列列&#xff0c;在矩阵中填两点之间的权值&#xff08;距…

SpringBoot集成-阿里云对象存储OSS

文章目录 阿里云 OSS 介绍准备工作SpringBoot 集成 OSS 阿里云 OSS 介绍 阿里云对象存储 OSS &#xff08;Object Storage Service&#xff09;&#xff0c;是一款海量、安全、低成本、高可靠的云存储服务。使用 OSS&#xff0c;你可以通过网络随时存储和调用包括文本、图片、…

【每日OJ题—— 142. 环形链表 II (链表)】

每日OJ题—— 142. 环形链表 II &#xff08;链表&#xff09; 1.题目&#xff1a;142. 环形链表 II 2.方法讲解2.1.解法一&#xff1a;2.1.1.图文解析2.1.2.代码实现2.1.3.提交通过展示 2.2解法二:2.2.1图文解析2.2.2代码实现2.2.3.提交通过展示 1.题目&#xff1a;142. 环形链…

从使用的角度看 ByConity 和 ClickHouse 的差异

自 ClickHouse Inc 宣布其重要新功能仅在 ClickHouse Cloud 上开放以来&#xff0c;一些关注 ByConity 开源的社区小伙伴也来询问 ByConity 后续开源规划。为回答社区疑问&#xff0c;我们将之前分享的关于 ByConity 与 ClickHouse 相关功能对比的 webinar 整理为文章&#xff…

AI 编程界的扛把子

大家好&#xff0c;我是伍六七。 全国最大 AI 社群《AI 破局俱乐部》初创合伙人。8 年 Java 经验&#xff0c;干过开发&#xff0c;也做过管理。目前在某互联网大厂从事 Java 开发&#xff0c;业余时间研究 AI 编程。 我从 2022 年底&#xff0c;ChatGPT 问世&#xff0c;就密…

【第28例】IPD体系进阶 | 需求管理:需求实现过程

目录 简介 内容详解 CSDN学院相关推荐 作者简介 简介 继续 IPD 体系中的需求管理相关的专题。 先来看看整个需求管理涉及的过程内容: 需求管理流程主要包含五个阶段: 需求收集; 需求分析; 需求分发/分配;

【Python报错合集】Python元组tuple、张量tensor(IndexError、TypeError、RuntimeError……)~持续更新

文章目录 IndexError1. tuple index out of rangea. 示例代码b.报错原因c.解决方案 TypeError1. len() of a 0-d tensora. 示例代码b.报错原因c.解决方案 RuntimeError1. output with shape … doesnt match the broadcast shape …a. 示例代码b.报错原因c.解决方案 2. Cant ca…

npm install:sill idealTree buildDeps

执行npm install&#xff0c;卡在 sill idealTree buildDeps PS D:\workspace-groovy\attendance-india-web> npm install -g cnpm --registryhttps://registry.npm.taobao.org [..................] / idealTree:node_global: sill idealTree buildDeps[.................…

Web3游戏的十字路口:沿用传统IP还是另起炉灶?

人们经常问我对 Web3 游戏有什么看法。因此&#xff0c;我想以书面形式概述一下我目前的想法。 让我先澄清一下&#xff1a;我不是专家。这不是一篇深入探讨游戏世界精细指标如 MAU 或 D14 等的全面分析。请把这看作是我根据个人交流和研究&#xff0c;这反映我在游戏领域关注…

响应式建筑房地产开发企业网站模板源码带后台

模板信息&#xff1a; 模板编号&#xff1a;5635 模板编码&#xff1a;UTF8 模板颜色&#xff1a;红色 模板分类&#xff1a;基建、施工、地产、物业 适合行业&#xff1a;房地产类企业 模板介绍&#xff1a; 本模板自带eyoucms内核&#xff0c;无需再下载eyou系统&#xff0…

每天一点python——day61

#第61天 #字符串的驻留机制字符串&#xff1a;python中基本数据类型&#xff0c;是一个不可变的序列【目前我们学了两个&#xff1a;元组、字符串】 可以使用单引号&#xff0c;双引号&#xff0c;三引号来定义#定义字符串 apython#用单引号&#xff0c;双引号&#xff0c;三引…

如何解决msvcp140.dll文件丢失问题,msvcp140.dll丢失的解决方法

在使用电脑时&#xff0c;有时我们可能会遇到一些错误提示&#xff0c;比如“找不到msvcp140.dll文件”。这是因为某些程序需要依赖于msvcp140.dll文件才能正常运行。这个问题是可以解决的,大家不需要担心&#xff0c;而且其解决的方法是有很多种的&#xff0c;今天我们就来给大…

数据库系统原理与实践 笔记 #7

文章目录 数据库系统原理与实践 笔记 #7数据库设计和E-R模型(续)转换为关系模式具有简单属性的实体集的表示复合属性多值属性联系集的表示模式的冗余—合并 实体-联系设计问题设计问题联系属性的布局 扩展的E-R特性特化概化属性继承特化/概化的设计约束聚集E-R图表示方法总结E-…

利用Graviton2和S3免费套餐搭建私人网盘

网盘是一种在线存储服务&#xff0c;提供文件存储&#xff0c;访问&#xff0c;备份&#xff0c;贡献等功能&#xff0c;是我们日常中不可或缺的一种服务。很多互联网公司都为个人和企业提供免费的网盘服务。但这些免费服务都有一些限制&#xff0c;比如限制下载速度&#xff0…

网络运维Day06

文章目录 磁盘空间管理一块硬盘的“艺术”之旅识别磁盘分区规划分区模式MBR(主启动记录模式)GPT分区 使用GPT分区方案分区 格式化与挂载使用格式化挂载使用 实现开机自动挂载实验 光盘挂载交换空间 总结 磁盘空间管理 磁盘空间管理 扇区默认512字节 一块硬盘的“艺术”之旅 …

领星ERP如何无需API开发轻松连接OA、电商、营销、CRM、用户运营、推广、客服等近千款系统

领星ERP&#xff08;LINGXING&#xff09;是一款专业的一站式亚马逊管理系统&#xff0c;帮助卖家构建完整的数据化运营闭环。&#xff0c;致力于为跨境电商卖家提供精细化运营和业财一体化的解决方案。 官网&#xff1a;https://erp.lingxing.com 集简云无代码集成平台&…

[NLP] LlaMa2模型运行在Mac机器

本文将介绍如何使用llama.cpp在MacBook Pro本地部署运行量化版本的Llama2模型推理&#xff0c;并基于LangChain在本地构建一个简单的文档Q&A应用。本文实验环境为Apple M1 芯片 8GB内存。 Llama2和llama.cpp Llama2是Meta AI开发的Llama大语言模型的迭代版本&#xff0c;…