为什么要滞后补偿?
考虑一下《反恐精英》这样的第一人称射击游戏。
服务器上有两个玩家:你和你的朋友。
服务器会将你朋友的位置同步给你。这需要 50 毫秒。
您使用镜像 [指令] CmdFire(Vector3 direction) 向您的朋友开火。
命令到达服务器还需要 50 毫秒。
然后服务器会检查你是否击中了你的朋友,并造成伤害。
在这 100 毫秒内(返回还需要50ms),你的朋友已经向左移动了两步。
因此,你总是打不中。
这就是高节奏/第一人称射击游戏需要延迟补偿的原因。
否则,玩家总是需要提前瞄准目标。
LagCompensation.cs
1.首先是独立于 Unity 的 C# LagCompensation.cs 算法,该算法具有完整的测试覆盖范围:
该算法可以记录和采样 类型的任何历史记录。
换句话说,你可以根据自己的需要定制算法。
请记住,这是非常低级的,使用高级组件会更容易!
它将所有神奇功能都隐藏在一个组件中,可自动记录对撞机在 3D 中的快照历史。只需将其添加到玩家对象中,它就会为你处理一切!
接下来,找到玩家在本地发射武器的位置。这里应该有一个类似于 CmdFireWeapon() 的 [命令],可以将输入发送到服务器。在这里,我们不是检查玩家是否击中了其他玩家,而是先向 Lag Compensation 询问玩家射击时其他玩家的位置。
[Client]
void FireWeapon()
{
// show muzzle flash, play sound etc. locally
// ...
// check if anything was hit
if (Physics.Raycast(camera.position, camera.position + camera.forward, out RaycastHit hit))
{
Player target = hit.collider.GetComponent<Player>();
// notify the server
CmdFiredWeapon(target, camera.position, hit.position);
}
}
[Command]
void CmdFiredWeapon(Player target, Vector3 originPoint, Vector3 hitPoint)
{
// check ammo etc.
// ...
// 'this' fired at 'target'.
// we need to grab 'target's LagCompensator to find out where it was.
LagCompensator compensator = target.GetComponent<LagCompensator>();
// next, we can use either of the compensator's 'Check...' functions.
// viewer is the one who fired, so it's 'this' object.
// Lag Compensator checks 'this' object's latency and then rewinds 'target's history by that time.
if (compensator.RaycastCheck(this.connectionToClient, originPoint, hitPoint))
{
// valid hit!
}
}
请注意,上述代码略有简化,但除了在 LagCompensator 的 "检查 "函数中增加了几个可选的配置参数外,实际上就只有这些了。