使用BoxCastAll检测两个对象之间是否有任何对象
在开发移动3D游戏的过程中,我遇到了一个盒子投射问题。
我想检查我的玩家和他的目标之间的路径,以避免他穿过环境物体(他没有附着刚体并且只能在特定点之间移动)。
这是我用来检查的代码:
private bool CheckPath (Vector3 position, Vector3 target) { Vector3 center = Vector3.Lerp(transform.position, target, 0.5f); Vector3 halfExtents = new Vector3(1, 1, (transform.position - target).magnitude) / 2; Quaternion rotation = Quaternion.LookRotation((transform.position - target).normalized); RaycastHit[] rhit = Physics.BoxCastAll(center, halfExtents, (transform.position - target).normalized, rotation); bool result = rhit.All(r => r.collider.tag != "Environment"); DebugUtilities.BoxCastDebug.DrawBox(center, halfExtents, rotation, result ? Color.green : Color.red, 3); return result; }
此代码适用于大多数情况:
但是失败了,例如这种情况:
为了可视化盒子播放,我使用了Unity Answers链接中的脚本。
我不确定问题出在哪里,虽然最可能的原因是上面提到的调试脚本中的一个缺陷,这让我相信我的盒子投注是正确的。
我很感激每一个解决方案,虽然一个简单的解决方案会更受欢迎。
一些进一步的信息(如果需要):
- 我想要无法通过的对象标有
Environment
标记。 - 我不是那个编写调试脚本的人,它起初似乎起作用,所以我对它很好。
你的代码中有三个问题
1.未使用来自unction参数的position
变量。 您使用的是transform.position
,这意味着起点可能是错误的。
用position
替换所有transform.position
。
你正在向后进行射线投射。 它不应该是transform.position - target
。 那应该是target - transform.position
。
3.你的 Physics.BoxCastAll
将无法正常工作,因为没有光线投射结束。 启动后面的对象将由光线投射检测到。 现在,如果您解决问题#2 ,问题将会逆转。 现在,由于您没有提供光线投射距离,因此也会检测目标后面的所有对象。 您可以在Physics.BoxCastAll
函数的最后一个参数中提供Vector3.Distance(position, target)
的距离。
固定function:
private bool CheckPath(Vector3 position, Vector3 target) { Vector3 halfExtents = Vector3.one; Quaternion rotation = Quaternion.LookRotation(target - position); Vector3 direction = target - position; float distance = Vector3.Distance(position, target); RaycastHit[] rhit = Physics.BoxCastAll(position, halfExtents, direction, rotation, distance); bool result = rhit.All(r => r.collider.tag != "Environment"); Vector3 center = Vector3.Lerp(position, target, 0.5f); halfExtents = new Vector3(1, 1, (target - position).magnitude) / 2; DebugUtilities.DrawBox(center, halfExtents, rotation, result ? Color.green : Color.red); // Debug.DrawRay(position, direction, result ? Color.green : Color.red); return result; }
值得设置3个对象(立方体)以便轻松测试此function。 第一个来自Object(Player)。 中间的应该是“环境”标签的障碍。 最后一个应该是玩家移动到的目标对象。
然后您可以使用下面的脚本来测试它。 运行它并将障碍物移动到玩家和目标之间,它应该按预期工作。
public GameObject playerObject; public GameObject targetObject; void Update() { Debug.Log("Path cleared: " + CheckPath(playerObject.transform.position, targetObject.transform.position)); }
您将在下面得到类似的结果: