如何检查一个游戏对象是不是可以看到另一个?
Posted
技术标签:
【中文标题】如何检查一个游戏对象是不是可以看到另一个?【英文标题】:How can I check if one game object can see another?如何检查一个游戏对象是否可以看到另一个? 【发布时间】:2010-09-17 06:08:42 【问题描述】:我有一个对象,它面向特定方向,具有(例如)45 度视野和极限视野范围。我已经完成了所有初始检查(四叉树节点和距离),但现在我需要检查特定对象是否在该视锥内,(在这种情况下,如果我们能看到它,则决定只跟随该对象)。
除了为从Direction - (FieldOfView / 2)
到Direction + (FieldOfView / 2)
的每个度数投射一条射线(我现在正在这样做,这太可怕了),进行这种可见性检查的最佳方法是什么?
【问题讨论】:
【参考方案1】:我曾在视频游戏行业工作过,我可以说像 arccos 这样的三角函数每帧都不太理想。相反,您预先计算锥角的余弦:
float cos_angle = cos(PI/4); // 45 degrees, for example
然后,您可以通过将每一帧与圆锥和 . 的点积进行比较来快速检查一个点是否落在该圆锥内。
vector test_point_vector = normalize(test_point_loc - cone_origin);
float dot_product = dot(normalized_cone_vector, text_point_vector);
bool inside_code = dot_product > cos_angle;
没有三角函数,只有一些乘法、除法和加法。大多数游戏引擎都为向量优化了 normalize() 函数。
这是因为这个等式有效:
A · B = |A| * |B| * cos(Θ)
如果对向量 (A -> An) 进行归一化,则方程会简化:
An · Bn = cos(Θ)
【讨论】:
谢谢。我喜欢限制每帧触发函数数量的想法。我一定会考虑试试这个(遗憾的是,只有在考试结束后)。 我喜欢这个答案。请注意,此解决方案只会进行“平截头体检查”,不会处理墙壁和其他物体的遮挡。【参考方案2】:计算您的视图方向(理解为向量)与从您开始到对象结束的向量之间的角度。如果它属于 FieldOfView/2,您可以查看该对象。
那个角度是:
arccos(scalarProduct(viewDirection, (object - you)) / (norm(viewDirection)*norm(object - you))).
【讨论】:
谢谢,正是我想要的。根据我已有的,我认为这可能是实现这一目标的最简单方法。【参考方案3】:获取查看器的航向矢量与查看器到目标的矢量之间的角度。如果该角度小于 (FieldOfView/2),则目标位于观察者的视野中。
如果您的向量是 2d 或 3d,则其工作方式相同。 (在 3D 中,如果你有一个视锥体而不是圆锥体,那么你需要将角度分成两个分量。)你只需要找到两个向量之间的角度。
如果要测试大于单个点的目标,则每个目标都需要多个点,例如边界框的角。如果从观察者到这些点的向量给出了视野内的一个角度,那么盒子的那个角是可见的。
【讨论】:
【参考方案4】:如果您正在制作 3D 并且可以将查看范围定义为视锥体,那么您可以使用类似于 Frustrum Culling 技术的东西。
【讨论】:
【参考方案5】:已经有了很好的答案,但我只是想给你一个 Wolfire 博客的链接,他们最近开始了一个代数系列,以“视野”方程为例。 Go read it,写得很好,很容易。
【讨论】:
以上是关于如何检查一个游戏对象是不是可以看到另一个?的主要内容,如果未能解决你的问题,请参考以下文章