最有效的方法来确定一个实体是否在玩家的视野?

所以我正在创建一个实时的多人游戏..我只希望实体数据发送给用户,如果它在他们的视野+多一点。 (这是第三人,所以这将是一个人的巨大框)

什么是最有效的方法来做到这一点? 我唯一能想到的是在玩家周围有一个巨大的盒子,然后循环遍历每个实体,看看它是否在盒子里,以及是否把数据发送给玩家,但是这样做对于很多玩家来说是可行的在服务器端太广泛了。

那么有什么解决方法呢?

Quake是第一个处理这个问题的游戏之一,即使在今天,它所使用的许多技术仍然是有效的。

它的源代码是免费的 ,可以研究(这也是相当严酷的地方阅读)。

总结一些技巧:

  • 已经预先计算了每个地图的可视性,以便能够快速检查每个玩家可以看到哪些实体,只有可见的实体需要被发送。

  • 由于客户端和服务器可能以不同速率打勾,因此发送所有可能显示的内容,而不管视野。

  • 使用基线状态和增量,以便只发送实际改变的数据。 客户可以从任何不变的任何东西的本地副本工作。

这些在20世纪90年代后期的低带宽拨号连接上是有效的,因此可以成为今天的一个很好的起点,也可以用来说明你可能不需要担心的领域。 后者的一个例子是服务器发送实体而不考虑视野:使用基线和增量意味着发送的实际数据可以保持相当小,这可能不是问题。

生病分解给你…

你的目标是find一个实体是否在摄像机视野中可见的三维空间。 请记住,您的实体存在于世界空间(模型空间)中,并且您的相机表示屏幕空间(或剪辑空间)。 所以,你的目标是将你的对象三维坐标变换到屏幕位置(二维)。 这被称为世界到屏幕。

脚步:

1)计算视图投影matrix。

vec4 viewProjectionMatrix = projectionMatrix * viewMatrix; 

2)计算剪辑空间坐标。

 vec3 clipSpacePos = entityPos * viewProjectionMatrix; 

3)计算屏幕上的坐标。

 vec2 windowPos = ((clipSpacePos.xy + 1) / 2) * viewSize; 

编辑1

如果你的y轴是从上到下,那么做1 - clipSpacePos.y

编辑2

服务器的源代码中可以应用相同的概念。

你可以把地图分成大盒子。 喜欢这个:

在这里输入图像说明

然后,对于每个框,保持内部实体的更新列表。

所以当你想知道国王的视野(让我们假设他看到一个领域很远)时,只需发送绿色框中的所有实体。

您可以通过select基于关卡devise的智能盒布局进一步改进。