多个射线广播,只有两个正在工作

时间:2019-02-24 17:42:06

标签: c# unity3d artificial-intelligence

我正在研究ai,我想给它提供玩家(汽车)和(几乎)游戏中其他所有东西(墙壁,街道中间,其他汽车)之间的距离。我正在使用Physics.Raycast。问题在于,只有DistanceToRightSideOfMOTS(MOTS:街道的中部)和DistanceToBackWall在起作用。这是我的代码:

private void FixedUpdate()
{
    RequestDecision();
    RequestAction();

     // Get the distances to the walls

    // Get distance to left wall
    RaycastHit hit;
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.left), out hit, 25, 1 << 11))
    {
        DistanceToLeftWall = hit.distance / 25;
        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.left) * hit.distance, Color.red);
    }
    else
    {
        DistanceToLeftWall = 1;
    }

    // Get distance to right wall
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.right), out hit, 25, 1 << 12))
    {
        DistanceToRightWall = hit.distance / 25;
        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.right) * hit.distance, Color.red);
    }
    else
    {
        DistanceToRightWall = 1;
    }

    // Get distance to front wall (it sees 2x farther because it's hard to turn on the corner)
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, 50, (1 << 11) | (1 << 12)))
    {
        DistanceToFrontWall = hit.distance / 50;
        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.red);
    }
    else
    {
        DistanceToFrontWall = 1;
    }
    // Get distance to back wall
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.back), out hit, 50, (1 << 11) | (1 << 12)))
    {
        DistanceToBackWall = hit.distance / 50;
        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.back) * hit.distance, Color.red);
    }
    else
    {
        DistanceToBackWall = 1;
    }

    //////////////////

    // Get the distance to other cars

    /////////////////

    // Get distance to left car
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.left), out hit, 25, 1 << 13))
    {
        DistanceToLeftCar = hit.distance / 25;
        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.left) * hit.distance, Color.green);
    }
    else
    {
        DistanceToLeftCar = 1;
    }

    // Get distance to right car
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.right), out hit, 25, 1 << 13))
    {
        DistanceToRightCar = hit.distance / 25;
        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.right) * hit.distance, Color.green);
    }
    else
    {
        DistanceToRightCar = 1;
    }

    // Get distance to front car
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, 50, 1 << 13))
    {
        DistanceToFrontCar = hit.distance / 50; // We divide the distance to normalize the input
        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.green);
    }
    else
    {
        DistanceToFrontCar = 1;
    }
    // Get distance to back car
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.back), out hit, 50, 1 << 13))
    {
        DistanceToBackCar = hit.distance / 50;
        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.back) * hit.distance, Color.green);
    }
    else
    {
        DistanceToBackCar = 1;
    }


    //Get distances to the middle of the street


    //Get distance from the left side
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.left), out hit, 10, 1 << 14))
    {
        DistanceToLeftSideOfMOTS = hit.distance / 10;
        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.left) * hit.distance, Color.blue);
    }
    else
    {
        DistanceToLeftSideOfMOTS = 1;
    }
    //Get distance from the right side
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.right), out hit, 10, 1 << 14))
    {
        DistanceToRightSideOfMOTS = hit.distance / 10;
        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.right) * hit.distance, Color.blue);
    }
    else
    {
        DistanceToRightSideOfMOTS = 1;
    }

}

其他距离始终返回1,即使不应返回。为什么不起作用,我该如何解决?

Edit1:我不知道为什么,但是当我将汽车超级靠近右墙时,DistanceToRightWall开始工作,而DistanceToBackCar仅在我离汽车至少15m时起作用。还有其他选择吗?

Edit2:我在墙壁和街道中间使用了平面。当我在Physics Debug Visualization中查看时,我从一侧而不是从另一侧看到平面碰撞器。我是团结的新手,所以也许这可能是问题所在。

Edit3:我在街道中间添加了一个盒式对撞机,DistanceToLeftSideOfMOTS开始起作用,但是我尝试用墙壁来做,但是没有解决。

Edit4:我使盒子对撞机变大了,它起作用了。现在唯一的问题是汽车。

1 个答案:

答案 0 :(得分:3)

我建立了一个示例场景来尝试您的代码,但是找不到任何问题。确保您的汽车对象正确定向,并且墙壁和汽车分配有适当的图层和对撞机。 Unity的Physics Debug Visualization可能会有所帮助。

enter image description here

此外,尝试保留更多DRY也是一个好主意。例如,您可以将所有raycast调用移到一个方法中,以减少重复。这样,如果出现问题,可以减少查找的地方:

private void FixedUpdate()
{
    RequestDecision();
    RequestAction();
    UpdateWallDistances();
}

private void UpdateWallDistances()
{
    int leftWallMask = 1 << 11;
    int rightWallMask = 1 << 12;
    int wallMask = leftWallMask | rightWallMask;
    int carMask = 1 << 13;
    int middleOfStreetMask = 1 << 14;

    // Get the distances to the walls
    DistanceToLeftWall = GetDistance(Vector3.left, 25, leftWallMask, Color.red);
    DistanceToRightWall = GetDistance(Vector3.right, 25, rightWallMask, Color.red);
    DistanceToFrontWall = GetDistance(Vector3.forward, 50, wallMask, Color.red);
    DistanceToBackWall = GetDistance(Vector3.back, 50, wallMask, Color.red);

    // Get the distance to other cars
    DistanceToLeftCar = GetDistance(Vector3.left, 25, carMask, Color.green);
    DistanceToRightCar = GetDistance(Vector3.right, 25, carMask, Color.green);
    DistanceToFrontCar = GetDistance(Vector3.forward, 50, carMask, Color.green);
    DistanceToBackCar = GetDistance(Vector3.back, 50, carMask, Color.green);

    //Get distances to the middle of the street
    DistanceToLeftSideOfMOTS = GetDistance(Vector3.left, 10, middleOfStreetMask, Color.blue);
    DistanceToRightSideOfMOTS = GetDistance(Vector3.right, 10, middleOfStreetMask, Color.blue);
}

private float GetDistance(Vector3 direction, float maxDistance, int layerMask, Color debugColor)
{
    RaycastHit hit;
    if (Physics.Raycast(transform.position, transform.TransformDirection(direction), out hit, maxDistance, layerMask))
    {
        Debug.DrawRay(transform.position, transform.TransformDirection(direction) * hit.distance, debugColor);
        return hit.distance / maxDistance;
    }
    else
    {
        return 1;
    }
}