UE5-MPTPS-4
前言
今天完成了教程的 42 - 48 小节,很遗憾没有完成作者一整天的提交,因为动画部分实在是太繁琐了。动画部分打算之后再专门总结一下。今天的教程中依然涉及了网络同步方面的内容,因此还是主要记录这方面的知识点。
Crouch
在 ACharacter
中已经内置了 Crouch
的功能,并且已经设置了自动改变碰撞体以及网络同步,十分方便。想要使用该函数,需要在角色的类中开启如下设置,UnCrouch
功能同理。
1 | GetCharacterMovement()->NavAgentProps.bCanCrouch = true; // 设置了此项才能够蹲下 |
继续探究 Replicate 与 RPC 的关系
为了在客户端与服务器端都同步 “瞄准” 这一动作,需要继续设置网络同步,让我们来思考一下应该如何设计:首先,瞄准这一动作肯定需要改变动画,因此在 AnimInstance
里声明一个新的布尔变量不可避免,并且为了同步,需要把这个变量声明为 Replicated
。
通过之前的文章我们知道:Replication
一般只能从服务器端同步到客户端,这意味着 服务器端操控的角色 的动作能够同步到其他客户端,但按下按键这一行为如果由客户端发起,即使 bAiming
被标记为了 Replicated
,该信息也无法传递给 服务器端的客户端角色,因此会出现客户端进入瞄准姿态,但是服务器端的对应角色并没有进入这个姿态的现象。
为了由客户端传递信息到服务器端,需要使用 ServerRPC
,即写一个 ServerSetAiming
函数,在 SetAiming
中调用,这样一来当客户端调用 SerAiming
进行瞄准时,会自动发送信息到服务器端,使得服务器端的角色进行相同的动作;同时,服务器端操控的角色 动作本身已经由 Replicated
同步到了客户端;这样一来双向的信息传递就不会出现问题。
1 | // CombatComponents.h |
1 | // CombatComponents.cpp |
1 | // BlasterCharacter.cpp |
为了验证这一系列的逻辑,可以分别进行实验。
Test1
注释掉下面三行,这样逻辑就变成了:bAiming
属性本身就不会复制,并且客户端不会向服务器端发送 RPC
。因此,所有的动作都只有本地才能看到。
1 | // UPROPERTY(Replicated) |
服务器端瞄准
仅有服务器端可以看到效果。
客户端瞄准
仅有客户端可以看到效果。
运行的结果确实符合预期。
Test2
将 bAiming
设置为复制,但是依然不调用 ServerRPC
,这样一来服务器端操控角色的信息能够正确同步到客户端,因此在客户端也能看到服务器端操控角色的瞄准动作,但客户端的瞄准动作只有本地可以看到,不会同步到服务器。
1 | UPROPERTY(Replicated) |
服务器端瞄准
服务器与客户端均可以看见效果
客户端瞄准
仅有客户端可以看见效果
运行的结果也符合预期。
其他
排列组合下来可以做很多实验,这里就不一一赘述了。但值得注意的是,在上面的逻辑中,如果是客户端调用 SetAimimg
,会先将本地的 bAiming
状态改变,再调用 ServerRPC
使得服务器上的状态改变,但实际上,由于设置了 Replicate
,因此可以直接调用 ServerRPC
再将状态同步到本地,这样依然可以达到效果。
但是,这就涉及到了一个问题:由于瞄准是玩家按下按键就期望立刻得到反馈的事件,如果不在 SetAimimg
中设置客户端本地的 bAiming
而是等到发送 ServerRPC
再同步给客户端,这样在网络延迟很高的情况下,可能会出现玩家按下按键却没有反馈的情况,这显然是不符合游戏设计的逻辑的。
因此,对于这种需要及时反馈的事件,还是应该先改变玩家本地的状态,再调用 ServerRPC
改变服务器的状态,这样一来即使出现了客户端与服务器端状态不同步的情况也能通过 Replication
来补救。