UE 高Ping状态模拟
- Config/DefaultEngine.ini中添加设置如下内容
1
2[PacketSimulationSettings]
PktLag = 100客户端预测算法产生的核心问题
- 客户端先去执行,服务器用于验证客户端执行的代码是否正确,由于通信的延迟问题,服务器不能强行将客户端强行拉回当前位置,会出现瞬移卡顿的问题。
- 玩家射击过程中,武器特效”不跟手“(即需要进行两次服务器RTT之后才能获取到特效以及子弹发射等,如果网不好会很卡的问题)。
武器特效不跟手的问题
在文章《散弹枪思路——服务器客户端随机数同步》中有写到,
角色移动部分的算法总结
- 思路:就是客户端根据RTT时间预测提前发送给服务器收到时预测客户端落点数据。流程:
- 客户端移动。
- 客户端将数据通过RPC发送给服务器,并保存下来。
- 收到从服务器的回复。
- 验证服务器当前的数据是否对应客户端。
- 丢弃 旧的 从服务器接收的回复。
- 重新在客户端应用服务器还未处理的移动。
弹药计算部分的算法总结
- 核心:客户端提前执行,服务器端验证逻辑
- 验证成功,客户端不变;
- 验证失败,客户端更改;(PS:一般不会验证失败,除非被外挂之类的修改了)。
- 开火时失去弹药的流程:
- 1、服务器执行多播将Fire函数在所有客户端以及服务器中执行。
- 其中,所属Client与Server都调用SpendRound函数进行弹药计算。
- 2_Client、执行SpendRound函数在客户端本地调用设置Ammo以及对应的HUD,并通过 Sequence 变量存储用于验证。
- 2_Server、SpendRound()在服务器调用时执行ClientUpdateAmmo客户端RPC函数对客户端提前的内容进行验证,验证函数流程ClientUpdateAmmo_Implementation:
- (1)、获取到当前的服务器发送并客户端收到的弹药数量,赋值到客户端Ammo中(因为以服务器作为权威)
- (2)、由于已经收到一个回传的包,一次开火已经验证完毕,因此 Sequence 减一
- (3)、Ammo 在减去正在验证的服务器 Sequence 数量。
- 1、服务器执行多播将Fire函数在所有客户端以及服务器中执行。
- 加入算法后的重新换弹的流程,还是核心不变:
- 1、服务器以及客户端调用UCombatComponent::HandleReload(),播放Montage
- 播放后,Montage调用UCombatComponent::FinishReloading()
- FinishReloading函数调用UCombatComponent::UpdateAmmoValues()处理主要换弹的逻辑
- UpdateAmmoValues函数调用AWeapon::AddAmmo进行子弹的更换
- 2、AWeapon::AddAmmo服务器调用AWeapon::ClientAddAmmo_Implementation进行换弹逻辑。
- 1、服务器以及客户端调用UCombatComponent::HandleReload(),播放Montage