123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- using UnityEngine;
- using System.Collections;
- namespace Pathfinding {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [HelpURL("http://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_procedural_grid_mover.php")]
- public class ProceduralGridMover : VersionedMonoBehaviour {
-
-
-
-
-
-
- public float updateDistance = 10;
-
- public Transform target;
-
- GridNodeBase[] buffer;
-
- public bool updatingGraph { get; private set; }
-
-
-
-
-
- public GridGraph graph;
-
-
-
-
-
-
- [HideInInspector]
- public int graphIndex;
- void Start () {
- if (AstarPath.active == null) throw new System.Exception("There is no AstarPath object in the scene");
-
-
- if (graph == null) {
- if (graphIndex < 0) throw new System.Exception("Graph index should not be negative");
- if (graphIndex >= AstarPath.active.data.graphs.Length) throw new System.Exception("The ProceduralGridMover was configured to use graph index " + graphIndex + ", but only " + AstarPath.active.data.graphs.Length + " graphs exist");
- graph = AstarPath.active.data.graphs[graphIndex] as GridGraph;
- if (graph == null) throw new System.Exception("The ProceduralGridMover was configured to use graph index " + graphIndex + " but that graph either does not exist or is not a GridGraph or LayerGridGraph");
- }
- UpdateGraph();
- }
-
- void Update () {
- if (graph == null) return;
-
- var graphCenterInGraphSpace = PointToGraphSpace(graph.center);
- var targetPositionInGraphSpace = PointToGraphSpace(target.position);
-
-
-
- if (VectorMath.SqrDistanceXZ(graphCenterInGraphSpace, targetPositionInGraphSpace) > updateDistance*updateDistance) {
- UpdateGraph();
- }
- }
-
-
-
-
-
-
- Vector3 PointToGraphSpace (Vector3 p) {
-
-
- return graph.transform.InverseTransform(p);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public void UpdateGraph () {
- if (updatingGraph) {
-
-
- return;
- }
- updatingGraph = true;
-
-
-
-
-
-
- IEnumerator ie = UpdateGraphCoroutine();
- AstarPath.active.AddWorkItem(new AstarWorkItem(
- (context, force) => {
-
- if (force) while (ie.MoveNext()) {}
-
- bool done;
- try {
- done = !ie.MoveNext();
- } catch (System.Exception e) {
-
-
-
- Debug.LogException(e, this);
- done = true;
- }
- if (done) {
- updatingGraph = false;
- }
- return done;
- }));
- }
-
- IEnumerator UpdateGraphCoroutine () {
-
-
- Vector3 dir = PointToGraphSpace(target.position) - PointToGraphSpace(graph.center);
-
- dir.x = Mathf.Round(dir.x);
- dir.z = Mathf.Round(dir.z);
- dir.y = 0;
-
- if (dir == Vector3.zero) yield break;
-
- Int2 offset = new Int2(-Mathf.RoundToInt(dir.x), -Mathf.RoundToInt(dir.z));
-
- graph.center += graph.transform.TransformVector(dir);
- graph.UpdateTransform();
-
- int width = graph.width;
- int depth = graph.depth;
- GridNodeBase[] nodes;
-
- int layers = graph.LayerCount;
- var layeredGraph = graph as LayerGridGraph;
- if (layeredGraph != null) {
- nodes = layeredGraph.nodes;
- } else {
- nodes = graph.nodes;
- }
-
- if (buffer == null || buffer.Length != width*depth) {
- buffer = new GridNodeBase[width*depth];
- }
-
-
- if (Mathf.Abs(offset.x) <= width && Mathf.Abs(offset.y) <= depth) {
- IntRect recalculateRect = new IntRect(0, 0, offset.x, offset.y);
-
- if (recalculateRect.xmin > recalculateRect.xmax) {
- int tmp2 = recalculateRect.xmax;
- recalculateRect.xmax = width + recalculateRect.xmin;
- recalculateRect.xmin = width + tmp2;
- }
-
- if (recalculateRect.ymin > recalculateRect.ymax) {
- int tmp2 = recalculateRect.ymax;
- recalculateRect.ymax = depth + recalculateRect.ymin;
- recalculateRect.ymin = depth + tmp2;
- }
-
- var connectionRect = recalculateRect.Expand(1);
-
- connectionRect = IntRect.Intersection(connectionRect, new IntRect(0, 0, width, depth));
-
-
-
- for (int l = 0; l < layers; l++) {
- int layerOffset = l*width*depth;
- for (int z = 0; z < depth; z++) {
- int pz = z*width;
- int tz = ((z+offset.y + depth)%depth)*width;
- for (int x = 0; x < width; x++) {
- buffer[tz + ((x+offset.x + width) % width)] = nodes[layerOffset + pz + x];
- }
- }
- yield return null;
-
-
- for (int z = 0; z < depth; z++) {
- int pz = z*width;
- for (int x = 0; x < width; x++) {
- int newIndex = pz + x;
- var node = buffer[newIndex];
- if (node != null) node.NodeInGridIndex = newIndex;
- nodes[layerOffset + newIndex] = node;
- }
-
-
- int xmin, xmax;
- if (z >= recalculateRect.ymin && z < recalculateRect.ymax) {
- xmin = 0;
- xmax = depth;
- } else {
- xmin = recalculateRect.xmin;
- xmax = recalculateRect.xmax;
- }
- for (int x = xmin; x < xmax; x++) {
- var node = buffer[pz + x];
- if (node != null) {
-
-
-
-
- node.ClearConnections(false);
- }
- }
- }
- yield return null;
- }
-
-
- int yieldEvery = 1000;
-
- int approxNumNodesToUpdate = Mathf.Max(Mathf.Abs(offset.x), Mathf.Abs(offset.y)) * Mathf.Max(width, depth);
- yieldEvery = Mathf.Max(yieldEvery, approxNumNodesToUpdate/10);
- int counter = 0;
-
-
-
- for (int z = 0; z < depth; z++) {
- int xmin, xmax;
- if (z >= recalculateRect.ymin && z < recalculateRect.ymax) {
- xmin = 0;
- xmax = width;
- } else {
- xmin = recalculateRect.xmin;
- xmax = recalculateRect.xmax;
- }
- for (int x = xmin; x < xmax; x++) {
- graph.RecalculateCell(x, z, false, false);
- }
- counter += (xmax - xmin);
- if (counter > yieldEvery) {
- counter = 0;
- yield return null;
- }
- }
- for (int z = 0; z < depth; z++) {
- int xmin, xmax;
- if (z >= connectionRect.ymin && z < connectionRect.ymax) {
- xmin = 0;
- xmax = width;
- } else {
- xmin = connectionRect.xmin;
- xmax = connectionRect.xmax;
- }
- for (int x = xmin; x < xmax; x++) {
- graph.CalculateConnections(x, z);
- }
- counter += (xmax - xmin);
- if (counter > yieldEvery) {
- counter = 0;
- yield return null;
- }
- }
- yield return null;
-
-
-
- for (int z = 0; z < depth; z++) {
- for (int x = 0; x < width; x++) {
- if (x == 0 || z == 0 || x == width-1 || z == depth-1) graph.CalculateConnections(x, z);
- }
- }
- } else {
-
-
- int yieldEvery = Mathf.Max(depth*width / 20, 1000);
- int counter = 0;
-
- for (int z = 0; z < depth; z++) {
- for (int x = 0; x < width; x++) {
- graph.RecalculateCell(x, z);
- }
- counter += width;
- if (counter > yieldEvery) {
- counter = 0;
- yield return null;
- }
- }
-
- for (int z = 0; z < depth; z++) {
- for (int x = 0; x < width; x++) {
- graph.CalculateConnections(x, z);
- }
- counter += width;
- if (counter > yieldEvery) {
- counter = 0;
- yield return null;
- }
- }
- }
- }
- }
- }
|