我有一个使用A *的探路者程序,该程序是我按照教程制作的。在我尝试使用异步Task使其成为多线程之前,它工作正常。线程可以工作,并且可以计算路径,但是当将路径结果传递给Unit对象时,由于某种原因,只有一个或两个Unit可以接收路径数组。我在哪里做错了?
RequestManager:
public class ThreadRequestManager : MonoBehaviour {
Queue<PathResult> results = new Queue<PathResult>();
static ThreadRequestManager instance;
ThreadPathfinding pathfinding;
private void Awake()
{
instance = this;
pathfinding = GetComponent<ThreadPathfinding>();
}
private void Update()
{
if (results.Count > 0)
{
int itemsInQueue = results.Count;
lock (results)
{
for(int i = 0; i < itemsInQueue; i++)
{
PathResult result = results.Dequeue();
result.callback(result.path, result.success);
}
}
}
}
public static async Task RequestPath(PathRequest request)
{
await Task.Run(() => instance.pathfinding.FindPath(request, instance.FinishedProcessingPath));
}
public void FinishedProcessingPath(PathResult result)
{
lock(results)
{
results.Enqueue(result);
}
}
}
public struct PathResult
{
public Vector3[] path;
public bool success;
public Action<Vector3[], bool> callback;
public PathResult(Vector3[] path, bool success, Action<Vector3[], bool> callback)
{
this.path = path;
this.success = success;
this.callback = callback;
}
}
public struct PathRequest
{
public Vector3 pathStart;
public Vector3 pathEnd;
public Action<Vector3[], bool> callback;
public PathRequest(Vector3 _start, Vector3 _end, Action<Vector3[], bool> _callback)
{
pathStart = _start;
pathEnd = _end;
callback = _callback;
}
}
单位:
public class ThreadUnits : MonoBehaviour {
public Transform target;
float speed = .5f;
public Vector3[] path;
int targetIndex;
// Use this for initialization
void Start()
{
ThreadRequestManager.RequestPath(new PathRequest(transform.position, target.position, OnPathFound));
}
public void OnPathFound(Vector3[] newPath, bool pathSuccess)
{
if (pathSuccess)
{
path = newPath;
// FollowPath();
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);
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]);
}
}
}
}
}