private void Start() { Path_Node temp = this; m_Rank = 0; while (temp.ParentNode != null) { m_Rank++; temp = temp.ParentNode; } m_Material = Resources.Load <Material>("Materials/PathingVisualiserMat"); m_Marker = GameObject.CreatePrimitive(PrimitiveType.Cube); m_Marker.transform.parent = transform; m_MarkerOrigin = new Vector3(transform.position.x, transform.position.y + 5.0f, transform.position.z); m_Marker.transform.position = m_MarkerOrigin; m_Marker.transform.localScale = new Vector3(5.0f, 5.0f, 5.0f); m_MarkerRend = m_Marker.GetComponent <Renderer>(); m_MarkerRend.enabled = m_IsRendered = false; m_MarkerRend.material = m_Material; float ratio = Mathf.Min(m_Rank / 5.0f, 1.0f); m_Colour = Color.Lerp(m_Colours[0], m_Colours[1], ratio); m_MarkerRend.material.color = m_Colour; m_MarkerRend.material.EnableKeyword("_EMISSION"); m_MarkerRend.material.SetColor("_EmissionColor", m_Colour * (1.3f - ratio)); }
/// <summary> /// Calculate the "euclidean distance" (shortest lenght from A to B) /// </summary> /// <param name="start">Beginning point</param> /// <param name="goal">Ending point</param> /// <returns>Euclidean distance between start & goal</returns> float Heuristic_Cost_Estimate(Path_Node <Tile> start, Path_Node <Tile> goal) { // Pythagorean theorem return(Mathf.Sqrt( Mathf.Pow(start.data.X - goal.data.X, 2) + Mathf.Pow(start.data.Y - goal.data.Y, 2))); }
private void Awake() { if (ParentNode == null && uniqueID != "CenterCamp") { ParentNode = transform.parent.gameObject.GetComponent <Path_Node>(); } }
float heuristic_cost_estimate(Path_Node <Tile> a, Path_Node <Tile> b) { return(Mathf.Sqrt( Mathf.Pow(a.data.X - b.data.X, 2) + Mathf.Pow(a.data.Y - b.data.Y, 2) )); }
private void Reconstruct_path( Dictionary <Path_Node <Tile>, Path_Node <Tile> > came_From, Path_Node <Tile> current) { // So at this point, current IS the goal. // So what we want to do is walk backwards through the Came_From // map, until we reach the "end" of that map...which will be // our starting node! Queue <Tile> total_path = new Queue <Tile>(); total_path.Enqueue(current.data); // This "final" step is the path is the goal! while (came_From.ContainsKey(current)) { /* Came_From is a map, where the * key => value relation is real saying * some_node => we_got_there_from_this_node */ current = came_From[current]; total_path.Enqueue(current.data); } // At this point, total_path is a queue that is running // backwards from the END tile to the START tile, so let's reverse it. path = new Queue <Tile>(total_path.Reverse()); }
private float Dist_between(Path_Node <Tile> a, Path_Node <Tile> b) { // We can make assumptions because we know we're working // on a grid at this point. // Hori/Vert neighbours have a distance of 1 if (Mathf.Abs(a.data.X - b.data.X) + Mathf.Abs(a.data.Y - b.data.Y) == 1 && a.data.Z == b.data.Z) { return(1f); } // Diag neighbours have a distance of 1.41421356237 if (Mathf.Abs(a.data.X - b.data.X) == 1 && Mathf.Abs(a.data.Y - b.data.Y) == 1 && a.data.Z == b.data.Z) { return(1.41421356237f); } // Up/Down neighbors have a distance of 1 if (a.data.X == b.data.X && a.data.Y == b.data.Y && Mathf.Abs(a.data.Z - b.data.Z) == 1) { return(1f); } // Otherwise, do the actual math. return(Mathf.Sqrt( Mathf.Pow(a.data.X - b.data.X, 2) + Mathf.Pow(a.data.Y - b.data.Y, 2) + Mathf.Pow(a.data.Z - b.data.Z, 2))); }
void reconstruct_Path(Dictionary <Path_Node <Tile>, Path_Node <Tile> > Came_From, Path_Node <Tile> current) { // So at this point, current IS the goal // So what we want to do is walk backwards through the Came_From map //, until we reach the "end" of that map .. which will be our // starting node! Queue <Tile> total_path = new Queue <Tile>(); total_path.Enqueue(current.data); //This "final" step in the path is the goal! while (Came_From.ContainsKey(current)) { //Came_From is a map, where the key => value relation is really saying // some_node => we_got_there_from_this_node current = Came_From[current]; total_path.Enqueue(current.data); } // At this point, total_path is a queue that is running backwards from END tile to the START tile, so lets reverse it! path = new Queue <Tile>(total_path.Reverse()); path.Dequeue(); // Remove the first tile(and don't put it anywhere) as we don't need to know the start - we are standing there after all }
public Path_TileGraph(World world) { Debug.ULogChannel("Path_TileGraph", "Entered Path_TileGraph"); /* * Loop through all tiles of the world * For each tile, create a node * Do we create nodes for non-floor tiles? NO! * Do we create nodes for tiles that are completely unwalkable (i.e. walls)? NO! */ nodes = new Dictionary <Tile, Path_Node <Tile> >(); for (int x = 0; x < world.Width; x++) { for (int y = 0; y < world.Height; y++) { Tile t = world.GetTileAt(x, y); ////if(t.movementCost > 0) { // Tiles with a move cost of 0 are unwalkable Path_Node <Tile> n = new Path_Node <Tile>(); n.data = t; nodes.Add(t, n); ////} } } Debug.ULogChannel("Path_TileGraph", "Created " + nodes.Count + " nodes."); // Now loop through all nodes again // Create edges for neighbours foreach (Tile t in nodes.Keys) { GenerateEdgesByTile(t); } }
void reconstruct_Path( Dictionary <Path_Node <Tile>, Path_Node <Tile> > Came_From, Path_Node <Tile> current ) { //at this point, current IS the goal //so what whe want to do is walk backwards through the Came_From map //until we reach the "end" of that map... which will be our starting node Queue <Tile> total_path = new Queue <Tile>(); total_path.Enqueue(current.data); // the "final" step in the path is the goal while (Came_From.ContainsKey(current)) { //came from is a map, where the key => value relation is real //saying some node => we_got_there_from_thius_node current = Came_From [current]; total_path.Enqueue(current.data); } // at this point, total_path is a queue that is running backwards from the EN tile to the Start tile, // so let's reverse it path = new Queue <Tile>(total_path.Reverse()); }
private void CreateEdgesForNode(Block block) { Path_Node <Block> n = nodes[block]; List <Path_Edge <Block> > edges = new List <Path_Edge <Block> >(); // Get a list of neighbors // if the neighbor is walkable, create an edge // if the block is a ramp, then blocks that are // either at the ramp's height or one up from there // are walkable neighbors // TODO: Implement the part about ramps working for (int i = 0; i < 4; i++) { SquareDirection dir = SquareDirectionExtensions.ReturnOrthogonal(i); Block nBlock = block.GetNeighbor(dir); if (nBlock != null) { Path_Edge <Block> e = new Path_Edge <Block>(); e.cost = nBlock.MoveCost; e.node = nodes[nBlock]; edges.Add(e); } } n.edges = edges.ToArray(); }
private void CreateNode(Block block) { Path_Node <Block> n = new Path_Node <Block>(); n.data = block; nodes.Add(block, n); }
private void GenerateEdgesByTile(Tile t) { if (t == null) { return; } Path_Node <Tile> n = nodes[t]; List <Path_Edge <Tile> > edges = new List <Path_Edge <Tile> >(); // Get a list of neighbours for the tile Tile[] neighbours = t.GetNeighbours(true, true); // NOTE: Some of the array spots could be null. // If neighbour is walkable, create an edge to the relevant node. for (int i = 0; i < neighbours.Length; i++) { if (neighbours[i] != null && neighbours[i].PathfindingCost > 0 && t.IsClippingCorner(neighbours[i]) == false) { // This neighbour exists, is walkable, and doesn't requiring clipping a corner --> so create an edge. Path_Edge <Tile> e = new Path_Edge <Tile>(); e.cost = neighbours[i].PathfindingCost; e.node = nodes[neighbours[i]]; // Add the edge to our temporary (and growable!) list edges.Add(e); } } n.edges = edges.ToArray(); }
// Adds new dynamically made nodes to known nodes public void AddNode(Path_Node newNode) { if (!AllNodes.ContainsKey(newNode.uniqueID)) { AllNodes.Add(newNode.uniqueID, newNode); } }
private void GenerateEdgesByRoom(Room room) { if (room.IsOutsideRoom()) { // We don't want to loop over all the tiles in the outside room as this would be expensive return; } Path_Node <Room> node = nodes[room]; List <Path_Edge <Room> > edges = new List <Path_Edge <Room> >(); Dictionary <Tile, Room> neighbours = room.GetNeighbours(); foreach (Tile tile in neighbours.Keys) { // We have found a different room to ourselves add an edge from us to them Path_Edge <Room> edge = new Path_Edge <Room>(); edge.cost = 1; edge.tile = tile; edge.node = nodes[neighbours[tile]]; edges.Add(edge); } node.edges = edges.ToArray(); }
float HeuristicCostEstimate(Path_Node<Tile> a, Path_Node<Tile> b) { return Mathf.Sqrt( Mathf.Pow(a.data.X - b.data.X, 2) + Mathf.Pow(a.data.Y - b.data.Y, 2) ); }
/// <summary> /// 重建路径 /// </summary> /// <param name="Came_From"></param> /// <param name="current"></param> void Reconstruct_path( Dictionary <Path_Node <Tile>, Path_Node <Tile> > Came_From, Path_Node <Tile> current ) { //所以在这一点上,目前是目标。 //所以我们想要做的是向后走过Came_From // map,直到我们到达那张地图的“结尾”......这将是 //我们的起始节点! Queue <Tile> total_path = new Queue <Tile>(); total_path.Enqueue(current.data); //这个“最后”步骤是路径是目标! while (Came_From.ContainsKey(current)) { // Came_From是一张地图,其中 // key =>价值关系是真实的说法 // some_node => we_got_there_from_this_node current = Came_From[current]; total_path.Enqueue(current.data); } //此时,total_path是一个正在运行的队列 //从END磁贴向后转到START磁贴,让我们反转它。 path = new Queue <Tile>(total_path.Reverse()); }
/// <summary> /// 启发式成本估算 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> float Heuristic_Cost_Estimate(Path_Node <Tile> a, Path_Node <Tile> b) { return(Mathf.Sqrt( Mathf.Pow(a.data.x - b.data.x, 2) + Mathf.Pow(a.data.y - b.data.y, 2) )); }
// Adds a path node at the start of the path public virtual void AddNodeAtStart( Path_Node pathNode ) { // Adds path node to list m_PathNodes.Insert( 0, pathNode ); // Recalculate the length of the path CalculateLength(); }
public Path_TileGraph(World world) { // Loop through all tiles of the world // For each tile, create a node // Do we create nodes for non-floor tiles? NO! // Do we create nodes for tiles that are completely unwalkable (i.e. walls)? NO! nodes = new Dictionary <Tile, Path_Node <Tile> >(); for (int x = 0; x < world.Width; x++) { for (int y = 0; y < world.Height; y++) { Tile t = world.GetTileAt(x, y); //if(t.movementCost > 0) { // Tiles with a move cost of 0 are unwalkable Path_Node <Tile> n = new Path_Node <Tile>(); n.data = t; nodes.Add(t, n); //} } } // Now loop through all nodes again // Create edges for neighbours int edgeCount = 0; foreach (Tile t in nodes.Keys) { Path_Node <Tile> n = nodes[t]; List <Path_Edge <Tile> > edges = new List <Path_Edge <Tile> >(); // Get a list of neighbours for the tile Tile[] neighbours = t.GetNeighbours(false); // NOTE: Some of the array spots could be null. // If neighbour is walkable, create an edge to the relevant node. for (int i = 0; i < neighbours.Length; i++) { if (neighbours[i] != null && neighbours[i].MovementCost > 0 && IsClippingCorner(t, neighbours[i]) == false) { // This neighbour exists, is walkable, and doesn't requiring clipping a corner --> so create an edge. Path_Edge <Tile> e = new Path_Edge <Tile>(); e.cost = neighbours[i].MovementCost; e.node = nodes[neighbours[i]]; // Add the edge to our temporary (and growable!) list edges.Add(e); edgeCount++; } } n.edges = edges.ToArray(); } }
public Path_TileGraph(World world) { Debug.Log("Path_TileGraph Constructor"); nodes = new Dictionary <Tile, Path_Node <Tile> >(); // loop through all tiles and create nodes; // do we create nodes for non walkable tiles? NO! for (int x = 0; x < world.width; x++) { for (int y = 0; y < world.height; y++) { Tile t = world.GetTileAt(x, y); //if(t.MoveCost > 0 && t.Type != TileType.Mountain && t.Type != TileType.Water && t.building == null) //{ Path_Node <Tile> n = new Path_Node <Tile>(); n.data = t; nodes.Add(t, n); //} } } // loop through all nodes again, // create edges for neighbors foreach (Tile t in nodes.Keys) { Path_Node <Tile> n = nodes[t]; List <Path_Edge <Tile> > edges = new List <Path_Edge <Tile> >(); // get a list of neighbors for the tile Tile[] neighbors = t.GetNeighbours(true); // NOTE some of the array may be null. // if neighbor is walkable, create an edge to relevant node for (int i = 0; i < neighbors.Length; i++) { if (neighbors[i] == null) // Breakout of loop if at the edge of the map { continue; } //if( IsClippingCorner ( t, neighbors[i])) //{ // continue; //} if (neighbors[i] != null && neighbors[i].MoveCost > 0) { Path_Edge <Tile> e = new Path_Edge <Tile>(); e.cost = neighbors[i].MoveCost; e.node = nodes[neighbors[i]]; // Add the edges to our temporary (and growable!) list edges.Add(e); } } n.edges = edges.ToArray(); } Debug.Log(" Created " + nodes.Count + " nodes"); }
private float HeuristicCostEstimate(Path_Node <Block> start, Path_Node <Block> end) { Block startBlock = start.data; Block endBlock = end.data; float xDistance = Mathf.Abs(startBlock.Point.x - endBlock.Point.x); float yDistance = Mathf.Abs(startBlock.Point.y - endBlock.Point.y); float zDistance = Mathf.Abs(startBlock.Point.y - endBlock.Point.z); return(xDistance + yDistance + zDistance); }
static void Main(string[] args) { IPath_Node n1 = new Path_Node(1, 1); IPath_Node n2 = new Path_Node(2, 2); IPath path = new SPath(n1, n2); Console.WriteLine(Directory.GetCurrentDirectory()); Santasearch santasearch = new Santasearch(); Console.WriteLine("Pause"); }
public Path_TileGraph(World world) { nodes = new Dictionary <Vector3Int, Path_Node <Vector3Int> > (); //Loop through all tiles of the world, build a node for each tile //Not creating nodes for tiles that are NON walkable(i.e walls, water, windows, etc) for (int x = 0; x < world.Width; x++) { for (int y = 0; y < world.Height; y++) { Vector3Int tilePos = new Vector3Int(x, y, 0); //Creates nodes FOR EVERY tile on the map Path_Node <Vector3Int> node = new Path_Node <Vector3Int> (); node.data = tilePos; nodes.Add(tilePos, node); } } int edgesCount = 0; //Now loop through all the nodes, and create the edges foreach (Vector3Int t in nodes.Keys) { //Get a list of neighbors of the tile, if neighbor is walkable create an edge to the relevant node Path_Node <Vector3Int> node = nodes[t]; List <Path_Edge <Vector3Int> > edges = new List <Path_Edge <Vector3Int> > (); Vector3Int[] neighbors = world.GetNeighbors(t, true); for (int i = 0; i < neighbors.Length; i++) { float movementSpeed = 1f; //Get movement Speed based on the tile on tilemap Walkable layer if (WorldController.Instance.World.foundationGameMap.ContainsKey(neighbors[i]) == true) { movementSpeed = WorldController.Instance.World.foundationGameMap[neighbors[i]].movementCost; } if (WorldController.Instance.World.foundationGameMap.ContainsKey(neighbors[i]) == false || (WorldController.Instance.World.foundationGameMap.ContainsKey(neighbors[i]) == true && movementSpeed > 0)) { if (isClippingCorner(nodes[t].data, neighbors[i])) { continue; } Path_Edge <Vector3Int> e = new Path_Edge <Vector3Int> (); e.cost = movementSpeed; if (nodes.ContainsKey(neighbors[i]) == true) { e.node = nodes[neighbors[i]]; edges.Add(e); edgesCount++; } } } node.edges = edges.ToArray(); } }
// Adds a node at the end of the path public virtual void AddNodeAtEnd( Path_Node pathNode ) { // parent the path node to this path pathNode.transform.parent = transform; // Add node to the list m_PathNodes.Add( pathNode ); // Recalculate the length of the path CalculateLength(); }
} // End of Update() function // Returns the character to a pathable position and rotation, at the correct node // Some parts of this method may be redundant at times, but it's easier than checking each time private void ResetCharacterTransform() { m_Mesh.ResetMesh(); // Return mesh to default /**/ Path_Node currentNode = m_PathFinder.GetCurrentNode(); // Get the current node as Path_Node transform.position = currentNode.transform.position; // Set character position to current node position Vector3 lookPoint = currentNode.ParentNode.transform.position; // Get the position of the parent node to current node lookPoint.y = transform.position.y; // Change the y component of it to character's transform.LookAt(lookPoint); // then look at it; prevents the character looking at an angle other than 90 degrees which is how I want it }
float distanceBetween(Path_Node <Tile> a, Path_Node <Tile> b) { if (Mathf.Abs(a.data.X - b.data.X) + Mathf.Abs(a.data.Y - b.data.Y) == 1) { return(1f); } if (Mathf.Abs(a.data.X - b.data.X) == 1 && Mathf.Abs(a.data.Y - b.data.Y) == 1) { return(1.41421356237f); } return(Mathf.Sqrt(Mathf.Pow(a.data.X - b.data.X, 2) + Mathf.Pow(a.data.Y - b.data.Y, 2))); }
public Path_TileGraph(Area area) { nodes = new Dictionary <Tile, Path_Node <Tile> >(); int edgeCount = 0; // Use the World Grid to create Nodes from Tile data // NODES will contain ONLY tiles that are WALKABLE for (int x = 0; x < area.Width; x++) { for (int y = 0; y < area.Height; y++) { Tile t = area.GetTile(x, y); if (t != null && t.MovementCost > 0) { Path_Node <Tile> n = new Path_Node <Tile>(); n.data = t; nodes.Add(t, n); } } } //Debug.Log("Path_TileGraph -- created " + nodes.Count + " Nodes."); // Now loop through nodes to create Edges between them foreach (Tile t in nodes.Keys) { Path_Node <Tile> n = nodes[t]; Tile[] neighbors = t.GetNeighbors(true); List <Path_Edge <Tile> > edges = new List <Path_Edge <Tile> >(); for (int i = 0; i < neighbors.Length; i++) { if (neighbors[i] != null && neighbors[i].MovementCost > 0) { // Is walkable Path_Edge <Tile> edge = new Path_Edge <Tile>(); edge.cost = neighbors[i].MovementCost; edge.node = nodes[neighbors[i]]; edges.Add(edge); edgeCount++; } } n.edges = edges.ToArray(); } //Debug.Log("Path_TileGraph -- created " + edgeCount + " Edges."); }
Dictionary <Tile, Path_Node <Tile> > nodes; // Maps from tiles to nodes // Public constructor // This class creates a tile compatible graph of the world, each tile is a graph, each walkable neighbour from a tile is linked via an edge public Tile_Graph(World world) { Debug.Log("Tile Graph initialised"); nodes = new Dictionary <Tile, Path_Node <Tile> >(); // Loop through all tiles of the world, for each tile that is wallkable create a node, create a node for (int x = 0; x < world.Width; x++) { for (int y = 0; y < world.Height; y++) { Tile t = world.GetTileAt(x, y); // Fetch the tile at the looped x and y - values if (t.MovementCost > 0) // if the tiles are walkable { // Create a node Path_Node <Tile> n = new Path_Node <Tile>(); n.data = t; nodes.Add(t, n); // Dictionary will now have a corresponding node for any tile in the world that is walkable } } } Debug.Log("Created" + nodes.Count + "Nodes"); int EdgeCount = 0; foreach (Tile t in nodes.Keys) // For each tile (Key) in the dictionary { Path_Node <Tile> n = nodes[t]; // Get the corresponding node List <Path_Edge <Tile> > edges = new List <Path_Edge <Tile> >(); // List of edges that come out of a node // Get a list of neighbours Tile[] neighbours = t.getNeighbours(true); // Note: Some tiles in this array could be null // loop through the array of neighbouring tiles for each walkable tile for (int i = 0; i < neighbours.Length; i++) { if (neighbours[i] != null && neighbours[i].MovementCost > 0) { // The nighbouring tile exists and is walkable so create an edge for that neighbour tile Path_Edge <Tile> e = new Path_Edge <Tile>(); e.cost = neighbours[i].MovementCost; // feeds the neighbouring tile to the edge constructor e.path_Node = nodes[neighbours[i]]; // the node fed to the path_edge is the neighbouring tile that is being processed // Returns the node for the neighbouring tile ? // edges.Add(e); // Add the edge to temp and throwable list EdgeCount++; } } n.edges = edges.ToArray(); // Casts the List of Edges to an array that is stored in the node // so that the node is aware of how many edges it has } Debug.Log(EdgeCount + " Edges created"); }
float dist_between(Path_Node <Tile> a, Path_Node <Tile> b) { if (Mathf.Abs(a.data.X - b.data.X) + Mathf.Abs(a.data.Y - b.data.Y) == 1) { return(1f); } if (Mathf.Abs(a.data.X - b.data.X) == 1 && Mathf.Abs(a.data.Y - b.data.Y) == 1) { return(Mathf.Sqrt(2)); } return(heuristic_cost_estimate(a, b)); }
void ReconstructPath(Dictionary <Path_Node <Tile>, Path_Node <Tile> > cameFrom, Path_Node <Tile> current) { Queue <Tile> totalPath = new Queue <Tile>(); totalPath.Enqueue(current.Data); while (cameFrom.ContainsKey(current)) { current = cameFrom[current]; totalPath.Enqueue(current.Data); } _path = new Queue <Tile>(totalPath.Reverse()); }
private float Heuristic_cost_estimate(Path_Node <Tile> a, Path_Node <Tile> b) { if (b == null) { // We have no fixed destination (i.e. probably looking for an inventory item) // so just return 0 for the cost estimate (i.e. all directions as just as good) return(0f); } return(Mathf.Sqrt( Mathf.Pow(a.data.X - b.data.X, 2) + Mathf.Pow(a.data.Y - b.data.Y, 2))); }
public Path_TileGraph(World world) { // Create all nodes via tiles. this.nodes = new Dictionary <Tile, Path_Node <Tile> >(); for (int x = 0; x < world.Width; x++) { for (int y = 0; y < world.Height; y++) { Tile t = world.GetTileAt(x, y); // Can actually move through the tile... Path_Node <Tile> n = new Path_Node <Tile>(); n.data = t; this.nodes.Add(t, n); } } // Create edges. foreach (Tile t in this.nodes.Keys) { Path_Node <Tile> n = this.nodes[t]; List <Path_Edge <Tile> > edges = new List <Path_Edge <Tile> >(); Tile[] neighbours = t.GetNeighbours(true); // Can walk diagonal. for (int i = 0; i < neighbours.Length; i++) { if (neighbours[i] != null && neighbours[i].movementCost > 0) { // Ensure no corners can be clipped. if (this.IsClippingCorner(t, neighbours[i])) { continue; } Path_Edge <Tile> e = new Path_Edge <Tile>(); e.cost = neighbours[i].movementCost; e.node = this.nodes[neighbours[i]]; edges.Add(e); } } n.edges = edges.ToArray(); } }
public Path_TileGraph(World world) { Debug.Log("Path_TileGraph"); // Loop through all tiles of the world // For each tile, create a node // Do we create nodes for non-floor tiles? NO! // Do we create nodes for tiles that are completely unwalkable (i.e. walls)? NO! nodes = new Dictionary<Tile, Path_Node<Tile>>(); for (int x = 0; x < world.Width; x++) { for (int y = 0; y < world.Height; y++) { Tile t = world.GetTileAt(x,y); //if(t.movementCost > 0) { // Tiles with a move cost of 0 are unwalkable Path_Node<Tile> n = new Path_Node<Tile>(); n.data = t; nodes.Add(t, n); //} } } Debug.Log("Path_TileGraph: Created "+nodes.Count+" nodes."); // Now loop through all nodes again // Create edges for neighbours int edgeCount = 0; foreach(Tile t in nodes.Keys) { Path_Node<Tile> n = nodes[t]; List<Path_Edge<Tile>> edges = new List<Path_Edge<Tile>>(); // Get a list of neighbours for the tile Tile[] neighbours = t.GetNeighbours(true); // NOTE: Some of the array spots could be null. // If neighbour is walkable, create an edge to the relevant node. for (int i = 0; i < neighbours.Length; i++) { if(neighbours[i] != null && neighbours[i].movementCost > 0 && IsClippingCorner( t, neighbours[i] ) == false) { // This neighbour exists, is walkable, and doesn't requiring clipping a corner --> so create an edge. Path_Edge<Tile> e = new Path_Edge<Tile>(); e.cost = neighbours[i].movementCost; e.node = nodes[ neighbours[i] ]; // Add the edge to our temporary (and growable!) list edges.Add(e); edgeCount++; } } n.edges = edges.ToArray(); } Debug.Log("Path_TileGraph: Created "+edgeCount+" edges."); }
float dist_between( Path_Node<Tile> a, Path_Node<Tile> b ) { // We can make assumptions because we know we're working // on a grid at this point. // Hori/Vert neighbours have a distance of 1 if( Mathf.Abs( a.data.X - b.data.X ) + Mathf.Abs( a.data.Y - b.data.Y ) == 1 ) { return 1f; } // Diag neighbours have a distance of 1.41421356237 if( Mathf.Abs( a.data.X - b.data.X ) == 1 && Mathf.Abs( a.data.Y - b.data.Y ) == 1 ) { return 1.41421356237f; } // Otherwise, do the actual math. return Mathf.Sqrt( Mathf.Pow(a.data.X - b.data.X, 2) + Mathf.Pow(a.data.Y - b.data.Y, 2) ); }
float heuristic_cost_estimate( Path_Node<Tile> a, Path_Node<Tile> b ) { return Mathf.Sqrt( Mathf.Pow(a.data.X - b.data.X, 2) + Mathf.Pow(a.data.Y - b.data.Y, 2) ); }
void reconstruct_path( Dictionary<Path_Node<Tile>, Path_Node<Tile>> Came_From, Path_Node<Tile> current ) { // So at this point, current IS the goal. // So what we want to do is walk backwards through the Came_From // map, until we reach the "end" of that map...which will be // our starting node! Queue<Tile> total_path = new Queue<Tile>(); total_path.Enqueue(current.data); // This "final" step is the path is the goal! while( Came_From.ContainsKey(current) ) { // Came_From is a map, where the // key => value relation is real saying // some_node => we_got_there_from_this_node current = Came_From[current]; total_path.Enqueue(current.data); } // At this point, total_path is a queue that is running // backwards from the END tile to the START tile, so let's reverse it. path = new Queue<Tile>( total_path.Reverse() ); }