BlueRoseNote/03-UnrealEngine/Gameplay/Online/在帧同步战斗上加入UE4的DS(专有服务器)的简单尝试.md
2023-06-29 11:55:02 +08:00

51 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 在帧同步战斗上加入UE4的DS(专有服务器)的简单尝试
date: 2022-12-09 15:10:14
excerpt:
tags: Online
rating: ⭐
---
## 原文地址
帧同步框架下添加状态同步记录
https://zhuanlan.zhihu.com/p/399047125
在帧同步战斗上加入UE4的DS(专有服务器)的简单尝试
https://zhuanlan.zhihu.com/p/480154978
## 其他工程
https://github.com/HiganFish/UE4SpaceShipBattleOL
## 实现细节
DS本质上使用的是状态同步那么大思路是参考我之前的一个文章参考帧同步框架下添加状态同步记录。
下面主要讲下实现的一些细节:
分离服务器和客户端逻辑
这个工作主要是把战斗中只需要在服务器执行的逻辑分离出来比如属性数值计算相关攻击碰撞检测技能buff释放逻辑子弹释放逻辑怪物AI等。大思路是服务器只下发角色属性和状态信息客户端根据逻辑进行相应的状态切换(包括技能释放)但不会执行和真实逻辑有关的计算。
服务器和客户端通信方式
这里使用UE4提供的RPC调用。使用UStruct定义的结构作为协议。省去了自己实现序列化和反序列化的工作。
调整框架
因为使用DS后GameModeBattle只存在于服务端。固客户端上的BaseBattle就需要另外找个地方可以更新。一番研究后选择了NetPlayerController(继承自PlayerController)。
根据Replication客户端的NetPlayerController是由客户端连上服务器后服务器创建然后复制给客户端的。RPC调用也是写在NetPlayerController里不管是服务器调用客户端还是客户端调用服务器。
调整单位创建流程
之前文章里的服务器其实只要跑逻辑部分不需要Native层相关的资源。现在因为要使用CharacterMovementComponent和移动预测服务器上的单位也必须把GameActor创建出来。创建后是由Replication复制到客户端并且同时复制这个单位的逻辑唯一ID属性(PID)。
原本逻辑上是由BeActor创建GeActor并且创建GameActor。现在需要改成客户端收到服务器创建单位的消息后创建BeActor(也会设置PID)并且创建GeActor但是不创建GameActor。等GameActor从服务器复制到客户端后在GameActor的StartPlay里启动绑定流程把这个GameActor绑定到相同PID的BeActor的GeActor上。PID是服务器和客户端标识同一单位的属性。
删除的时候也是同理。客户端收到删除消息后把BeActor以及GeActor删除GameActor由Replication同步来删除。
这里顺便提下子弹 的做法。子弹因为一般都是以一定速度沿特定轨迹移动所以没有继承CharacterMovementComponent。为了优化流量消耗子弹的位置可以不需要服务器每帧更新。只需在创建信息把速度创建轨迹等参数下发客户端就可以自行创建这个子弹以及轨迹移动做表现。
使用UE4 CharacterMovementComponent
要使用CharacterMovementComponent需要使用Character。于是原本的基于Actor的GameActor改为继承Character并且设置相关的参数调整碰撞胶囊体的大小。
修改逻辑自带的移动组件主要是每帧把逻辑层的速度设置给MovementComponent的Velocity。并且每帧取得组件Location反设给自带移动组件。因为逻辑上层还是通过访问自带移动组件来进行位置的判断。
服务器上也需要每帧把逻辑的信息更新给CharacterMovementComponent包括位置旋转和缩放
使用移动预测
拥有CharacterMovementComponent的Character需要是ROLE_AutonomousProxy才可以进行预测。而且现在的框架上NetPlayerController是先创建然后才会创建GameActor因此需要在服务器上执行PlayerController的Posses函数来设置控制的Actor。
本地客户端对于ROLE_AutonomousProxy的GameActor需要在Run和Idle对CharacterMovementComponent设置Velocity来驱动组件移动。这样对于移动和停止的Idle本地客户端不会等服务器的Replication就会立马进行。 而对于其他玩家和怪物则是ROLE_SimulatedProxy全程由Replication来进行位置变化
怪物寻路
使用navmesh直接在服务器端调用navmesh寻路接口返回得到路径点在原来的AI移动逻辑上调整代码沿着路径点行走即可。