繁体   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