使用BoxCastAll检测两个对象之间是否存在任何对象 [英] Detect if there is any object between two objects with BoxCastAll

查看:3155
本文介绍了使用BoxCastAll检测两个对象之间是否存在任何对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我想检查我的玩家和他的目标之间的路径,以避免他穿过环境物体(他没有附加刚体,只能在特定点之间移动)。



这是我用来检查的代码:

  private bool CheckPath(Vector3 position,Vector3 target)
{
Vector3 center = Vector3.Lerp(transform目标,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);

返回结果;
}

此代码适用于大多数情况:



为了可视化box-cast,我使用了

然后你可以使用下面的脚本测试它。运行它并在玩家和目标之间移动障碍物,它应该按预期工作。

  public GameObject playerObject; 
public GameObject targetObject;

void Update()
{
Debug.Log(Path cleared:+ CheckPath(playerObject.transform.position,targetObject.transform.position));
}

您会在下面得到类似的结果:


I ran into an issue with box-casts while developing a 3D game for mobile.

I want to check the path between my player and his target, to avoid him passing through environmental objects (he doesn't have a rigidbody attached and movement is only possible between specific points).

This is the code that I used to check:

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 code works for the most situations:

But fails, for example for this situation:

To visualize the box-cast I used the script from this Unity Answers link.

I am not sure where the problem lies, although the most likely cause would be a flaw in the debugging script mentioned above, which made me believe that my box-cast call was correct.

I am grateful for every solution, although a simple one would be more appreciated.

Some further information (if needed):

  • The objects that I want to make impassable are marked with a Environment tag.
  • I was not the one that wrote the debugging script, it seemed to work at first, so I was fine with it.

解决方案

Three problems in your code

1.The position variable from the unction parameter is not used. You are instead using transform.position which means that the starting point may be wrong.

Replace all your transform.position with position.

2.You are performing the raycast backwards. It should not be transform.position - target. That should be target - transform.position.

3.Your Physics.BoxCastAll will not work properly since there is no ending to the raycast. Objects behind the starting will be detected by the raycast. Now, if you fix problem #2, the problem will reverse. Now, all the objects in behind the target will also be detected since you did not provide the raycast distance. You can provide the distance with Vector3.Distance(position, target) in the last parameter of the Physics.BoxCastAll function.

Fixed 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;
}

It's worth setting up 3 objects (Cubes) in order to easily test this function. The first one is from Object (Player). The middle one should be the obstacle with the "Environment" tag. The last one should be the target Object where player is moving to.

Then you can use the script below to test it. Run it and move the obstacle away between the player and the target and it should work as expected.

public GameObject playerObject;
public GameObject targetObject;

void Update()
{
    Debug.Log("Path cleared: " + CheckPath(playerObject.transform.position, targetObject.transform.position));
}

You will get the similar result below:

这篇关于使用BoxCastAll检测两个对象之间是否存在任何对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆