public PathingResult FindPath(object fromObject, object toObject, bool drawDebug = false) { PathingResult result = new PathingResult(); result.isValid = false; float debugDelay = 0f; const float debugTime = 20000000f; if (drawDebug) { DebugDrawers.Clear(); } if ( fromObject == null || toObject == null || fromObject == toObject ) { return(result); } // Result node variables. foreach (DictionaryEntry entry in this.nodes) { Node node = (Node)entry.Value; node.isQueued = false; node.minDistance = Mathf.Infinity; } Node fromNode = (Node)this.nodes[fromObject]; Node toNode = (Node)this.nodes[toObject]; if (fromNode == null || toNode == null || !fromNode.isEnabled || !toNode.isEnabled) { return(result); } fromNode.minDistance = 0f; Queue <Node> nodesToTest = new Queue <Node>(); nodesToTest.Enqueue(fromNode); Node currentNode; while (true) { // Tested all nodes we can reach. if (nodesToTest.Count == 0) { break; } currentNode = nodesToTest.Dequeue(); foreach (Connection connection in currentNode.connections) { Node node = connection.node; if (node.isEnabled == false) { continue; } node.minDistance = Mathf.Min( node.minDistance, currentNode.minDistance + connection.distance ); if (node.isQueued == false) { nodesToTest.Enqueue(node); node.isQueued = true; } if (drawDebug) { DebugDrawers.SpawnLine( currentNode.pos, node.pos, Color.blue, debugTime - debugDelay, debugDelay ); debugDelay += 0.02f; } } if (currentNode == toNode) { break; } } // No path. if (toNode.isQueued == false) { return(result); } result.distance = toNode.minDistance; result.isValid = true; result.nodes = new List <object>(); result.nodes.Add(toNode.o); // Trace toNode to fromNode, following the shortest path. currentNode = toNode; Node lastNode = null; while (true) { float minMinDistance = Mathf.Infinity; Node bestNode = null; foreach (Connection connection in currentNode.connections) { if (connection.node.isEnabled == false) { continue; } if (connection.node.minDistance < minMinDistance) { minMinDistance = connection.node.minDistance; bestNode = connection.node; } } if (drawDebug) { foreach (Connection connection in currentNode.connections) { if (connection.node.isEnabled == false) { continue; } if (connection.node != bestNode && connection.node != lastNode) { DebugDrawers.SpawnLine( currentNode.pos, connection.node.pos, Color.yellow, debugTime - debugDelay, debugDelay ); } } DebugDrawers.SpawnLine( currentNode.pos, bestNode.pos, Color.green, debugTime - debugDelay, debugDelay ); debugDelay += 0.33f; } lastNode = currentNode; result.nodes.Add(bestNode.o); if (bestNode == fromNode) { break; } else { currentNode = bestNode; } } result.nodes.Reverse(); return(result); }
void Update() { if (hardInput.GetKeyDown("Test LOS")) { // Draw a LOS test line from the selected tile to all other tiles. Debug.Log("Testing LOS"); if (this.selectedTile == null) { return; } foreach (BattleTile tile in this.tiles) { bool canSee = this.TestLOS(this.selectedTile, tile); DebugDrawers.SpawnLine( this.selectedTile.transform.position, tile.transform.position, canSee ? Color.green : Color.red, 2f ); } } else if (hardInput.GetKeyDown("Test pathing")) { Debug.Log("Testing pathing"); if (this.selectedTile == null || this.hoveredTile == null) { return; } if (this.selectedTile.mech) { this.pathNetwork.SetNodeEnabled(this.selectedTile, true); } PathingResult result = this.pathNetwork.FindPath( this.selectedTile, this.hoveredTile, true ); if (this.selectedTile.mech) { this.pathNetwork.SetNodeEnabled(this.selectedTile, false); } if (result.isValid) { Debug.Log(result.nodes.Count + " nodes in path " + result.distance + " units long."); } else { Debug.Log("Invalid path!"); } } else if (hardInput.GetKeyDown("Test saving")) { Debug.Log("Testing saving"); string jsonText = this.history.ToJSON(); string path = "TestSave.json"; using (StreamWriter sw = new StreamWriter(path)){ sw.WriteLine(jsonText); } Debug.Log("Wrote save to " + path); } }