[英]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.