簡體   English   中英

動態尋路A * Unity3D C#

[英]Dynamic Pathfinding A* Unity3D C#

我正在嘗試在Unity3D中使用A *尋路,如果目標保持靜止,它將起作用。 但是,如果目標移動,單位將仍然遵循相同的路徑。 查找下面每個單元的代碼(附加到搜尋器對象上):

using UnityEngine;
using System.Collections;

public class Unit : MonoBehaviour {

    public Transform target;
    float speed = 20;
    Vector3[] path;
    int targetIndex;

void Start() {
    PathRequestManager.RequestPath(transform.position,target.position, OnPathFound);
}

public void OnPathFound(Vector3[] newPath, bool pathSuccessful) {
    if (pathSuccessful) {
        path = newPath;
        StopCoroutine("FollowPath");
        StartCoroutine("FollowPath");
    }
}

IEnumerator FollowPath() {
    Vector3 currentWaypoint = path[0];

    while (true) {
        if (transform.position == currentWaypoint) {
            targetIndex ++;
            if (targetIndex >= path.Length) {
                yield break;
            }
            currentWaypoint = path[targetIndex];
        }


        transform.position = Vector3.MoveTowards(transform.position,currentWaypoint,speed * Time.deltaTime);
        yield return null;

    }
}

public void OnDrawGizmos() {
    if (path != null) {
        for (int i = targetIndex; i < path.Length; i ++) {
            Gizmos.color = Color.black;
            Gizmos.DrawCube(path[i], Vector3.one);

            if (i == targetIndex) {
                Gizmos.DrawLine(transform.position, path[i]);
            }
            else {
                Gizmos.DrawLine(path[i-1],path[i]);
            }
        }
    }
}

}

現在,如果我嘗試通過將void Start()更改為void Update()來將其用於動態尋路(目標移動和路徑更新),則將無法使用。 響應將導致奇怪的單位行為,一直來回移動或未完成路徑等。現在我不知道確切的原因,可能是因為協程嗎? 無論如何,我該如何更改代碼,以便得到正確的動態尋路?

提前致謝!

PS所有剩余的源代碼都可以在這里找到: http : //bit.ly/pathfindingSource

只要此邏輯的設計不是最優的,請嘗試在到達下一個航路點時重新計算路徑:

IEnumerator FollowPath() {
    Vector3 currentWaypoint = path[0];

    while (true) {
        if (transform.position == currentWaypoint) {

           PathRequestManager.RequestPath(transform.position,target.position, OnPathFound);

targetIndex = 0;
            targetIndex ++;
            if (targetIndex >= path.Length) {
                yield break;
            }
            currentWaypoint = path[targetIndex];
        }


        transform.position = Vector3.MoveTowards(transform.position,currentWaypoint,speed * Time.deltaTime);
        yield return null;

    }

如果要進行動態尋路,則需要重新計算到達下一個航路點的每次到達時間,或者具有其他邏輯,例如在某些對象移動時觸發事件-在處理程序中,您需要重新計算路徑。

我已經通過一個足夠好的解決方案“解決了”這個問題。

首先,我通過在每個航路點請求新路徑來使尋路動態化。 其次,通過某種邏輯,即使到達目標后,尋路仍繼續進行,該邏輯檢查每一幀是否再次足夠遠以重復協程。 如果是這樣,則停止舊的協程並開始新的協程。

這是代碼:

using UnityEngine;
using System.Collections;

public class Unit : MonoBehaviour {

public Transform target;
float speed = 20;
Vector3[] path;
int targetIndex;

bool  newRequestReady;

void Start() {
    PathRequestManager.RequestPath(transform.position,target.position, OnPathFound);

    newRequestReady = false;
}

void Update(){
    float distance = Vector3.Distance (transform.position, target.position);
    Debug.Log(distance);

    if(distance < 5){
        StopCoroutine("FollowPath");
        newRequestReady = true;
    }
    else if(distance >=10 && newRequestReady){
        PathRequestManager.RequestPath(transform.position,target.position, OnPathFound);
        StopCoroutine("FollowPath");
        newRequestReady = false;

    }
}

public void OnPathFound(Vector3[] newPath, bool pathSuccessful) {
    if (pathSuccessful) {
        path = newPath;
        StopCoroutine("FollowPath");
        StartCoroutine("FollowPath");
    }
}

IEnumerator FollowPath() {
    Vector3 currentWaypoint = path[0];

    while (true) {

        if (transform.position == currentWaypoint) {
            PathRequestManager.RequestPath(transform.position,target.position,OnPathFound);
            targetIndex=0;

            targetIndex ++;
            //Debug.Log(currentWaypoint);

            if (targetIndex >= path.Length) {
                targetIndex =0;
                path = new Vector3[0];
            //yield break;
            }
            currentWaypoint = path[targetIndex];
        }
            transform.position = Vector3.MoveTowards(transform.position,currentWaypoint,speed * Time.deltaTime);

        yield return null;
    }
}


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM