我在开发移动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;
}
此代码适用于大多数情况:
但是失败了,例如对于这种情况:
为了可视化框播,我使用了this Unity Answers链接中的脚本。
我不确定问题出在哪里,虽然最可能的原因是上面提到的调试脚本中的一个缺陷,这让我相信我的盒子投注是正确的。
我很感激每一个解决方案,虽然一个简单的解决方案会更受欢迎。
一些进一步的信息(如果需要):
Environment
标记。 答案 0 :(得分:1)
代码中的三个问题
1 。未使用unction参数中的position
变量。您改为使用transform.position
,这意味着起点可能是错误的。
将所有transform.position
替换为position
。
2 。您正在向后执行光线投射。它不应该是transform.position - target
。那应该是target - transform.position
。
3 。由于光线投射没有结束,您的Physics.BoxCastAll
将无法正常工作。启动后面的对象将由光线投射检测到。现在,如果您修复问题#2 ,问题将会逆转。现在,由于您没有提供光线投射距离,因此也会检测目标后面的所有对象。您可以在Vector3.Distance(position, target)
函数的最后一个参数中提供Physics.BoxCastAll
的距离。
固定功能:
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个对象(立方体)以便轻松测试此功能。第一个来自Object(Player)。中间的应该是" Environment" 标签的障碍。最后一个应该是玩家移动到的目标对象。
然后您可以使用下面的脚本来测试它。运行它并将障碍物移动到玩家和目标之间,它应该按预期工作。
public GameObject playerObject;
public GameObject targetObject;
void Update()
{
Debug.Log("Path cleared: " + CheckPath(playerObject.transform.position, targetObject.transform.position));
}
您将在下面得到类似的结果: