【问题标题】:Finding the closer player with NavMesh使用 NavMesh 找到更近的玩家
【发布时间】:2016-11-20 23:40:40
【问题描述】:

在我的场景中,我的 NavMesh 位于中心(黄色的那个),并设置了 3 个要跟踪的立方体。我希望 NavMesh 在所有立方体中找到最近且路径最短的那个并开始跟随它。我已经编写了这样做的代码,但它的行为很奇怪,我看不出它有什么问题,但显然有些问题。发生的事情是,当我单击播放并将立方体保持原样时,NavMesh 实际上会找到到最近的立方体的路径并开始朝它前进(cube3),但是当它几乎到达它时,NavMesh 很难转身开始走向立方体 1,这显然不是更近的那个。

这是我的代码。 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);
}

【问题讨论】:

    标签: c# unity3d monodevelop path-finding


    【解决方案1】:

    CalcPath 确实有问题。我会尝试举一个例子来告诉你什么是错的。假设与玩家的距离如下:[5,20,10]。显然玩家 A 最接近,但 CalcPath 将返回玩家 C。我将通过你的循环来说明原因:

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

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

    第三次迭代(这是你的问题所在)
    currentPathLength : 20 -&gt; 10 (这是 小于 小于lastPathLength)
    closestTarget : PlayerA.transform.position -&gt; PlayerC.transform.position
    lastPathLength : 20 -&gt; 10

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

    【讨论】:

    • 你是绝对正确的。在我的情况下,lastPathLength 没用。我想通了这一点并发布了我的答案,但我会在这里保留我的答案并接受你的答案,因为它解释了正在发生的事情。也许它会帮助某人。谢谢:-D
    【解决方案2】:

    我将当前路径长度与上一个路径长度进行比较,而不是存储最短路径并进行比较。我设置了一个名为“closestTargetLength”的新变量,并将其与当前路径长度进行比较,结果完美。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-17
      • 1970-01-01
      • 2021-02-17
      • 2016-10-10
      • 2019-09-17
      • 1970-01-01
      • 2022-12-19
      相关资源
      最近更新 更多