【发布时间】:2016-11-15 12:18:10
【问题描述】:
我需要将一些带有附加碰撞器的变换移动到特定位置,然后检查其中一个是否被光线投射击中。
我以天真的方式(伪代码)做到了:
foreach(object in objects){
actual_position = object.transform.position
object.transform.position = object.new_position
}
if(Physics.Raycast(...)) objectHit();
// Then I revert each of them them back to their actual_position
在使用相同的上下文(每个对象的测试之间的位置相同)进行多次测试后,光线投射有时会丢失,有时不会 (~50/50)。
做了一些研究,发现在 Raycast 文档页面:
如果您通过脚本或动画移动对撞机,则需要 至少执行一个 FixedUpdate 以便物理库可以 更新它的数据结构,在 Raycast 击中对撞机之前 这是新职位。
于是我平息了自己的怒火,开始寻找解决办法。 该线程有一种使用协程等待下一个滴答声的方法: Raycast doesn't work properly
我担心它对我不起作用,因为我需要这些物体立即回到它们的真实位置。 这个过程每帧可以发生多次(每次玩家开火)
有没有办法强制对撞机更新?
如果不是...我应该自己制作光线投射和对撞机吗? :(
谢谢
【问题讨论】:
-
您是否尝试过使用类似
Bounds.IntersectRay的东西?如果您的对象上有一个简单的碰撞器,(或者您的光线投射不需要 100% 准确)对于像盒子碰撞器这样简单的东西,您可以执行object.GetComponent<Collider>().bounds来获取边界,并将边界对象移动到新的位置,检查它,然后只在没有碰撞的情况下移动对象,这在性能上也比移动两次更好,因为如果它不应该移动它甚至根本不会移动它,docs.unity3d.com/ScriptReference/Bounds.IntersectRay.html -
看起来像一个聪明的解决方案,我的对撞机目前是简单的胶囊,但我想这也适用于更复杂的 MeshCollider。我看到的唯一问题是我必须对每个对象进行测试,并确保它们与射线源之间没有墙。这比仅仅抛出一个光线投射更复杂,但为什么不呢。非常感谢您的帮助。
-
看着你链接的答案,我想也许你可以尝试使用
yield return new WaitForFixedUpdate();,因为它会在每次物理更新之前被调用? -
@FLX 如果这就是您的意思,您不必对每个世界对象进行测试,对于您要移动的每个对象,您只需执行一次
BoxCast检查(或CapsuleCastin你的情况),这两者放在一起仍然比实际使用带有刚体的对撞机效率高很多倍(更不用说实际移动物体两次) -CapsuleCast第一次有点难以掌握,但当你正确理解它们 -
@Kardux 我认为它在这种情况下不起作用:我可以同时进行多次倒带,如果我需要等待下一个刻度,我担心某些位置可能会覆盖另一个位置。我对例程不太满意,所以我可能错了,但设计仍然过于复杂。
标签: unity3d