Search Unity

A* Pathfinding help

Discussion in 'Scripting' started by suctioncup, Sep 21, 2014.

  1. suctioncup

    suctioncup

    Joined:
    May 19, 2012
    Posts:
    273
    Hello, I am trying to implement some very basic pathfinding.

    Here is the main excerpt from my code;

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. //Tile class
    7. public class Tile
    8. {
    9.     public TileState tileState;                //The state of the tile - empty, wall, floor etc
    10.    
    11.     public int x;                            //x position (Normalized)
    12.     public int y;                            //y position (Normalized)
    13.    
    14.     public int g;                          //Cost
    15.     public int h;                          //Manhattan Distance
    16.     public int f;                          //Total cost
    17.    
    18.     public Tile parent_tile;
    19. }
    20.  
    21. public class TileValues
    22. {
    23.     public int empty = 0;
    24.     public int wall_persp = 0;
    25.     public int floor = 1;
    26.     public int edge = 1;
    27. }
    28.  
    29. public class pathfinding_test : MonoBehaviour {
    30.  
    31.     //A* corridor pathfinding
    32.     void DigCorridors()
    33.     {
    34.         Debug.Log("Starting DigCorridors()...");
    35.        
    36.         Debug.Log("Calling build_path()...");
    37.         List<Tile> corridor = build_path(grid_list[5], grid_list[15]);
    38.         Debug.Log("Called build_path().");
    39.        
    40.         for(int i = 0; i < corridor.Count; i++)
    41.         {
    42.             grid_list[grid_list.IndexOf(corridor[i])].tileState = TileState.Floor;
    43.         }
    44.  
    45.         Debug.Log("Calling Fill()...");
    46.         Fill();
    47.     }
    48.    
    49.     //City block distance - used in pathfinding
    50.     int manhattanDistance(Tile from, Tile to)
    51.     {
    52.         return Mathf.Abs(from.x - to.x) + Mathf.Abs(from.y - to.y);
    53.     }
    54.    
    55.     List<Tile> DigPath(Tile from, Tile to)
    56.     {
    57.         Debug.Log("Starting DigPath()...");
    58.         //Define the lists of tiles we can reach, and tiles we have explored
    59.         List<Tile> open = new List<Tile>();  
    60.         List<Tile> closed = new List<Tile>();
    61.        
    62.         //Add the from tile to the reachable list
    63.         open.Add(from);
    64.        
    65.         Debug.Log("Starting A* loop at: " + Time.timeSinceLevelLoad    );
    66.        
    67.         while(open.Count > 0)
    68.         {
    69.             Debug.Log("while loop");
    70.             Tile node_current = new Tile();
    71.            
    72.             Debug.Log("Getting lowest F score");
    73.             node_current = GetLowestFScore(open, to);
    74.            
    75.             Debug.Log("Got lowest F score");
    76.            
    77.             if(node_current == to)
    78.             {
    79.                 break;  
    80.             }
    81.            
    82.             Debug.Log("Getting adjacent nodes");
    83.             List<Tile> adjacent_tiles = new List<Tile>();
    84.             adjacent_tiles = get_adjacent_nodes(node_current);
    85.            
    86.             Debug.Log("For loop");
    87.             for(int i = 0; i < adjacent_tiles.Count; i++)
    88.             {
    89.                 if(adjacent_tiles[i] == to)
    90.                 {
    91.                     break;    
    92.                 }
    93.                
    94.                 Tile adjacent_node = new Tile();
    95.                 adjacent_node = adjacent_tiles[i];
    96.                
    97.                 adjacent_node.g = node_current.g + 1;
    98.                 adjacent_node.h = manhattanDistance(adjacent_node, to);
    99.                 adjacent_node.f = adjacent_node.g + adjacent_node.h;
    100.                
    101.                 if(open.Contains(adjacent_node) && node_current.f < adjacent_node.f)
    102.                 {
    103.                     //Discard and continue
    104.                     continue;
    105.                 }
    106.                
    107.                 if(closed.Contains(adjacent_node) && node_current.f < adjacent_node.f)
    108.                 {
    109.                     //Discard and continue
    110.                     continue;
    111.                 }
    112.              
    113.                 adjacent_node.parent_tile = node_current;
    114.                 open.Add(adjacent_node);
    115.             }
    116.                 closed.Add(node_current);
    117.         }
    118.         Debug.Log("Finished A* loop at: " + Time.timeSinceLevelLoad    );
    119.        
    120.         return closed;
    121.        
    122.         Debug.Log("Finished DigPath().");
    123.     }
    124.    
    125.     Tile GetLowestFScore(List<Tile> open_list, Tile to)
    126.     {
    127.         Debug.Log("Starting GetLowestFScore()...");
    128.         int lowest_f = 1000000;
    129.        
    130.         Tile lowest_f_tile = new Tile();
    131.        
    132.         Debug.Log("GetLowestFScore() if statement");
    133.         if(open_list.Count == 1)
    134.         {
    135.             lowest_f_tile = open_list[0];
    136.             Debug.Log("Got lowest f");
    137.         } else {
    138.             Debug.Log("GetLowestFScore() for loop");
    139.             for(int i = 0; i < open_list.Count; i++)
    140.             {
    141.                 if(open_list[i].f < lowest_f)
    142.                 {
    143.                     lowest_f_tile = open_list[i];
    144.                     lowest_f = open_list[i].f;
    145.                 }
    146.             }
    147.         }
    148.        
    149.         Debug.Log("Returning lowest F tile");
    150.        
    151.         return lowest_f_tile;
    152.     }
    153.    
    154.     List<Tile> get_adjacent_nodes(Tile node)
    155.     {
    156.         List<Tile> adjacent = new List<Tile>();
    157.        
    158.         //Add N tile
    159.         if(grid_list.IndexOf(node) - gridSettings.Width > 0)
    160.         {
    161.             adjacent.Add(grid_list[grid_list.IndexOf(node) - gridSettings.Width]);
    162.         }
    163.        
    164.         //Add S tile
    165.         if(grid_list.IndexOf(node) + gridSettings.Width < grid_list.Count)
    166.         {
    167.             adjacent.Add(grid_list[grid_list.IndexOf(node) + gridSettings.Width]);
    168.         }
    169.        
    170.         //Add E tile
    171.         if(grid_list.IndexOf(node) + 1 < grid_list.Count)
    172.         {
    173.             adjacent.Add(grid_list[grid_list.IndexOf(node) + 1]);
    174.         }
    175.        
    176.         //Add W tile
    177.         if(grid_list.IndexOf(node) - 1 > 0)
    178.         {
    179.             adjacent.Add(grid_list[grid_list.IndexOf(node) - 1]);
    180.         }
    181.        
    182.         return adjacent;
    183.     }
    184.    
    185.     List<Tile> build_path(Tile from, Tile to)
    186.     {
    187.         Debug.Log("Starting build_path()...");
    188.        
    189.         List<Tile> path = new List<Tile>();
    190.         path = DigPath(from, to);
    191.        
    192.         while(to != null)
    193.         {
    194.             path.Add(to);
    195.             to = to.parent_tile;
    196.         }
    197.        
    198.         return path;
    199.        
    200.         Debug.Log("Finished build_path().");
    201.     }
    202.    
    203. }
    Currently, when I run this, unity crashes. What am I doing wrong?
     
  2. suctioncup

    suctioncup

    Joined:
    May 19, 2012
    Posts:
    273
    Forgot to say, I should be able to run build_path(), which should return a List of 'tiles' (that list is the path)
     
  3. AustinRichards

    AustinRichards

    Joined:
    Apr 4, 2013
    Posts:
    321
  4. suctioncup

    suctioncup

    Joined:
    May 19, 2012
    Posts:
    273
    I tried this, but it doesn't seem to be logging anything before the editor freezes. I do have to relaunch unity though, which is probably why.