🎮UE5 网络同步入门
type
status
date
slug
summary
tags
category
icon
password
打算新开一个系列,记录一下自己在UE5使用过程中遇到的有价值的点。应该主要是以经验作为导向,个人作总结,不足或者错误之处烦请包涵并指正。
Key Points
在开始之前,我觉得有一些要点需要特别说明,它们是贯穿整个 UE 网络同步框架的基石概念。这篇文章不会涉及具体的代码实现逻辑,而是希望对游戏网络同步这件事情有一个大致的了解。
了解抽象的概念,以及 UE 的设计之后,找到对应的接口并实现自己的设计会变得更加简单自然。
具体的接口以及示例,请移步
UE 最好的学习资料就是官方的文档,里面详细描述了设计的思路及使用案例。
游戏发生在服务器上
刚开始接触网络同步的新人游戏开发者(比如我),通常只对网络同步有模糊的了解,这些了解主要来源于平时自己的游戏经历。比如,我们知道游戏需要服务器来同步一些信息,知道延迟的概念,更进一步的朋友会知道服务器 Tick 的概念。
但是在游戏开发过程中,这些模糊的了解会使得我们对 UE 提供的接口的功能有一些武断且错误的判断。
网络游戏 & 多人游戏
网络游戏经常与多人游戏挂钩。多人游戏当中,多个玩家的不同状态需要同步进行运算。如果游戏发生在本地,我们当然可以让本地机器进行全部的运算。
但如果是网络游戏呢?
我们自然知道,玩家间的状态同步自然由服务器负责。但是哪些运算逻辑需要放到服务器上,哪些运算需要放在本地客户端上,这是我们需要明晰的事情。
游戏发生在服务器上。
这是我们需要理解的核心概念。每个玩家操纵的并不是本地客户端中角色,而是服务器上的角色,只是开发者通常会用一些手段来让玩家认为自己在操纵本地的角色。
在 UE 当中,常常用 Proxy 来指代本地角色和服务器上的角色,他们互为对方的 Proxy(代理)。
举个例子,在射击游戏当中,人物需要进行射击,这其中包括的步骤有:
- 子弹生成
- 子弹沿着路径前行,直到发生碰撞事件(击中)
- 碰撞后进行逻辑处理
请思考,哪些步骤是在客户端进行运算?
答案是全部都在服务器上进行运算,包括子弹的生成。
之前有些朋友认为只有子弹在客户端生成,仅当发生碰撞的时候,客户端才会将碰撞事件上传至服务器进行计算。这是一种错误的看法(如果游戏设计不是这样的话)。
究其原因,是他们将服务器仅仅看作状态同步的信息中转站,认为游戏发生在每个客户端当中。而事实是,真正的游戏发生在服务器上,而客户端仅仅用来显示服务器传达的状态,以及画面。
UE 中的网络同步
UE 所提供的网络同步框架有很多,我也仅仅是简单阅读了一些文档,并对 Replication 系统有简单的使用经验。因此,我仅仅介绍 UE 当中最基础的网络框架,也就是基于 Replication 的网络同步框架。
同步类型
UE 的文档中将同步的方法类型分为两类。而在我看来,分为三类更加合适,即:
- UE 进行自动同步的(Actor、Component 等)
- Replication
- RPC(Server、Client)
自动同步
自动同步,是指 UE 已经替我们完成了这部分信息的同步交换。这包括一些 Character 的变换信息(位置,旋转,缩放),我们也可以在自己设计的 Actor 类中,通过设置相应的组件功能,来开启 UE 提供的网络同步功能。
Replication
Replication 指的是服务器向客户端同步数据或状态的过程。
我们需要明确,没有客户端向服务器的 Replication。
在服务器进行 Replication 的时候,每个需要同步的客户端都对应一个 Connection,而这个Connection 的拥有者通常是一个
PlayerController
对象。我们把这个 Connection 叫做这个 PlayerController
对象的 owning connection。所有需要进行网络同步的对象都需要有其 owning connection 才能进行和服务器的通信,因为这样才能标志一个玩家的行动。
RPC
RPC(Remote Procedure Call)分为两种:
- Server RPC,仅在服务器上运行,通常由客户端发起(比如生成子弹)。
- Client RPC,仅在客户端上运行,通常由服务器发起(比如加载某些特定的特效)。
我们通常希望尽可能少的进行 RPC 的使用,更应该去使用 Replication 进行状态的同步。
UE 通常不建议重度依赖 RPC 进行网络同步。无论是组件还是 Component,我们都需要能够追溯到一个 owning connection 进行消息发送。简而言之,owner 指针的根部必须是
PlayerController
。 同步的游戏框架
了解的同步的分类,我们仍需要了解整个游戏同步的框架是怎样的。
UE 设计的 GamePlay 框架如图所示,我简单介绍下
GameMode
、GameState
以及 PlayerState
。GameMode
GameMode
对象仅存活在服务器上,用于定义游戏的逻辑(如胜利条件,分数等)。GameState
GameState
对象需要同时被复制到客户端当中,用来描述本局游戏的状态(比如吃鸡游戏的毒圈信息)。注意,
GameState
对象也会包含所有玩家的 PlayerState
,通常用数组的形式保存。因此,我们不希望和游戏相关的状态信息被添加到 PlayerState
当中,这会导致不必要的内存空间浪费。PlayerState
PlayerState
对象仅仅用来存放和该玩家有关的信息(不是控制角色)。比如玩家的分数,复活次数,击杀数量等等。
PlayerState
通常和 PlayerController
相关,我们通过 PlayerController
对象修改玩家状态,因此你会发现一些事件(比如碰撞),都会有其 Owner 或者是 Instigator 帮助我们获得事件触发者,进而修改玩家状态。总结
简单了解上述概念,对 UE 网络编程的理解和使用会帮助。
我也是在作业中需要使用网络编程的时候阅读了相关的文档,进行了简单的学习。
尽管如此,还是决定写下来加深理解。
上一篇
GAMES101 作业0
下一篇
本站的搭建过程
- Twikoo