用NavMesh找到更近的玩家

时间:2016-11-20 23:40:41

标签: c# unity3d monodevelop path-finding

在我的场景中,我的NavMesh位于中心(黄色),设置了3个立方体进行跟踪。我希望NavMesh从所有立方体中找到距离它最近的最近路径并开始跟踪它。我已经编写了这样的代码,但它行为很奇怪而且我没有看到它有什么问题,但显然有些东西。发生的事情就是当我点击播放并按原样保留立方体时,NavMesh实际上找到了到最近的立方体的路径并开始向它前进(cube3),但是当它几乎到达它时, NavMesh转了一圈并开始前往立方体1,这显然不是最接近的立方体。

enter image description here

这是我的代码。 PathLength工作正常。我认为问题在于CalcPath函数。

float PathLength(Vector3 target){
    NavMeshPath path = new NavMeshPath ();
    myNavMesh.CalculatePath (target, path);
    int i = 1;
    float currentPathLength = 0;
    Vector3 lastCorner;
    Vector3 currentCorner;
    lastCorner = path.corners [0];

    while (i < path.corners.Length) {
        currentCorner = path.corners [i];
        currentPathLength += Vector3.Distance (lastCorner, currentCorner);
        Debug.DrawLine (lastCorner, currentCorner, Color.red,1f);
        lastCorner = currentCorner;
        i++;
    }

    return currentPathLength;
}


void CalcPath(){
    Vector3 closestTarget = Vector3.zero;
    float lastPathLength = Mathf.Infinity;
    float currentPathLength = 0;

    foreach (GameObject player in GameObject.FindGameObjectsWithTag("Player")) {

        currentPathLength = PathLength (player.transform.position);

        if (currentPathLength < lastPathLength) {
            closestTarget = player.transform.position;
        }

        lastPathLength = currentPathLength;
    }

    myNavMesh.SetDestination (closestTarget);
}

2 个答案:

答案 0 :(得分:3)

CalcPath确实存在问题。我会尝试举例说明你的错误。说与玩家的距离如下:[5,20,10]。显然,玩家A最接近,但CalcPath将返回玩家C.我将通过你的循环来说明原因:

第一次迭代:
currentPathLength : 0 -> 5
closestTarget : null -> PlayerA.transform.position
lastPathLength : Mathf.Infinity -> 5

第二次迭代:
currentPathLength : 5 -> 20
closestTarget : PlayerA.transform.position -> PlayerA.transform.position (未更改)
lastPathLength : 5 -> 20

第三次迭代(这就是您的问题所在)
currentPathLength : 20 -> 10 (这是 而不是lastPathLength
closestTarget : PlayerA.transform.position -> PlayerC.transform.position
lastPathLength : 20 -> 10

要解决此问题,请不要存储lastPathLength,而是存储最小路径长度,只有在有新的最小值时才更改closestTarget

答案 1 :(得分:0)

我正在将当前路径长度与最后路径长度进行比较,而不是存储最短路径并进行比较。我设置了一个名为“nearestTargetLength”的新变量,并将其与当前路径长度进行了比较,并且工作正常。

float PathLength(Vector3 target){
    NavMeshPath path = new NavMeshPath ();
    myNav.CalculatePath (target, path);
    int i = 1;
    float currentPathLength = 0;
    Vector3 lastCorner;
    Vector3 currentCorner;

    lastCorner = path.corners [0];
    while (i < path.corners.Length) {
        currentCorner = path.corners [i];
        currentPathLength += Vector3.Distance (lastCorner, currentCorner);
        Debug.DrawLine (lastCorner, currentCorner, Color.red);
        lastCorner = currentCorner;
        i++;
    }

    return currentPathLength;
}


void CalcPath(){
    Vector3 closestTarget = Vector3.zero;
    float closestTargetLength = Mathf.Infinity;
    float lastPathLength = Mathf.Infinity;
    float currentPathLength = 0;

    foreach (GameObject player in GameObject.FindGameObjectsWithTag("Player")) {

        currentPathLength = PathLength (player.transform.position);

        if (currentPathLength < closestTargetLength) {
            closestTarget = player.transform.position;
            closestTargetLength = currentPathLength;
        }
        lastPathLength = currentPathLength;
    }

    myNav.SetDestination (closestTarget);
}