Search Unity

AStar path finding Sample, 150 lines of code

Discussion in 'Community Learning & Teaching' started by friuns3, Oct 4, 2011.

  1. friuns3

    friuns3

    Joined:
    Oct 30, 2009
    Posts:
    307
    Just read this article http://www.policyalmanac.org/games/aStarTutorial.htm
    and did sample on unity3d based this tutorial, may be helpfull for you :D

    Also i used this script for text gizmo
    http://forum.unity3d.com/threads/27902-Text-Gizmo



    i coded it on fast hand, so there may be bugs, feel free to post them if you find any=)

    Code (csharp):
    1.  
    2. using gui = UnityEngine.GUILayout;
    3. using System.Linq;
    4. using UnityEngine;
    5. using System.Collections;
    6. using System.IO;
    7. using System.Collections.Generic;
    8. public class AStarExample : Bs
    9. {
    10.     const string level = @"
    11. -------
    12. ---x---
    13. -a-x-b-
    14. ---x---
    15. -------";
    16.     public enum NodeType { None, Wall, A, B }
    17.     public Node[,] map;
    18.     private const int width = 7;
    19.     private const int height = 5;
    20.  
    21.     private void InitMap()
    22.     {
    23.         ie = FindPath().GetEnumerator();            
    24.         map = new Node[width, height];
    25.         StringReader sr = new StringReader(level);
    26.         for (int c2 = sr.Read(), x = 0, y = -1; c2 != -1; c2 = sr.Read())
    27.         {
    28.             char c = (char)c2;
    29.             if ("-xab".ToCharArray().Contains(c))
    30.             {
    31.                 map[x, y] = new Node { type = c, pos = new Vector2(x, y) };
    32.                 x++;
    33.             }
    34.             if (c == '\n')
    35.             {
    36.                 y++;
    37.                 x = 0;
    38.             }
    39.         }
    40.     }
    41.     public void OnDrawGizmos()
    42.     {
    43.         if (map == null)
    44.             InitMap();
    45.  
    46.         for (int i = 0; i < width; i++)
    47.             for (int j = 0; j < height; j++)
    48.             {
    49.                 Node node = map[i, j];
    50.                 if (node.type == 'x')
    51.                     DrawCube(node.pos, Color.white);
    52.                 if (node.type == 'a')
    53.                     DrawCube(node.pos, Color.blue);
    54.                 if (node.type == 'b')
    55.                     DrawCube(node.pos, Color.red);
    56.                 if (node.type == '-')
    57.                 {
    58.                     if (node.path)
    59.                         DrawCube(node.pos, Color.yellow);
    60.                     else if (node.Closed)
    61.                         DrawCube(node.pos, Color.cyan);
    62.                     else if (node.Checked)
    63.                         DrawCube(node.pos, Color.green);
    64.                 }
    65.                 DrawCubeWired(node.pos, Color.black * .2f);
    66.                 TextGizmo.DrawText(convert(node.pos) + new Vector3(.3f, 0, -.3f), "G" + node.G);
    67.                 TextGizmo.DrawText(convert(node.pos) + new Vector3(-.3f, 0, -.3f), "H" + node.H);
    68.  
    69.             }
    70.     }
    71.     IEnumerator ie;
    72.     public override void OnEditorGui()
    73.     {
    74.         if (gui.Button("Reset"))
    75.             InitMap();            
    76.         if (gui.Button("Next"))
    77.             ie.MoveNext();
    78.         if (gui.Button("FindPath"))
    79.             foreach (var a in FindPath()) { }
    80.         base.OnEditorGui();
    81.     }
    82.     private IEnumerable FindPath()
    83.     {
    84.         Node startNode = map.Cast<Node>().FirstOrDefault(a => a.type == 'a');
    85.         Node endNode = map.Cast<Node>().FirstOrDefault(a => a.type == 'b');
    86.         Node cur = startNode;
    87.         cur.Closed = true;
    88.         for (; ; )
    89.         {
    90.             SortedList<float, Node> openNodes = new SortedList<float, Node>();
    91.             for (int i = Mathf.Max(cur.x - 1, 0); i < Mathf.Min(cur.x +2, width); i++)
    92.                 for (int j = Mathf.Max(cur.y - 1, 0); j < Mathf.Min(cur.y + 2, height); j++)
    93.                 {
    94.                     Node n = map[i, j];
    95.                     if ((n.type == '-' || n.type == 'b')  !n.Closed)
    96.                     {                            
    97.                         n.G = cur.G + (i == cur.x || j == cur.y ? 10 : 14);
    98.                         n.H = 10 * (Mathf.Abs(endNode.x - i) + Mathf.Abs(endNode.y - j));
    99.                         n.parent = cur;
    100.                         n.Checked = true;
    101.                         openNodes.Add(n.H + n.G + Random.value, n);
    102.                         Debug.Log("i:" + i + " j:" + j);
    103.                         yield return null;
    104.                     }
    105.                 }            
    106.             cur = openNodes.FirstOrDefault().Value;
    107.             if (cur == null || cur == endNode) break;
    108.             cur.Closed = true;
    109.             Debug.Log("CurNode i:" + cur.x + " j:" + cur.y);
    110.             yield return null;
    111.         }
    112.         Debug.Log("Found");
    113.         while (true)
    114.         {            
    115.             cur = cur.parent;
    116.             if (cur == null) break;
    117.             cur.path = true;
    118.         }
    119.         yield return null;
    120.     }
    121.  
    122.     public static void DrawCubeWired(Vector2 pos, Color c)
    123.     {
    124.         Gizmos.color = c;
    125.         Gizmos.DrawWireCube(convert(pos), Vector3.one);
    126.     }
    127.     public static void DrawCube(Vector2 pos, Color c)
    128.     {
    129.         Gizmos.color = c;
    130.         Gizmos.DrawCube(convert(pos), Vector3.one);
    131.     }
    132.     private static Vector3 convert(Vector2 pos)
    133.     {
    134.         return new Vector3(pos.x, 0, -pos.y);
    135.     }
    136.  
    137.     public class Node
    138.     {
    139.         public bool Checked;
    140.         public bool Closed;
    141.         public bool path;
    142.         public Vector2 pos;
    143.         public Node parent;
    144.         public char type;
    145.         public int H;
    146.         public int G;
    147.         public int x { get { return (int)pos.x; } }
    148.         public int y { get { return (int)pos.y; } }
    149.     }
    150. }
    151.  
     
    Last edited: Oct 5, 2011
  2. Atom

    Atom

    Joined:
    Sep 27, 2011
    Posts:
    9
    Thanks man:D
    It's pretty cool to learn more about AI
     
  3. flim

    flim

    Joined:
    Mar 22, 2008
    Posts:
    326
    Cool.
    I got error when I save the script

    Assets/AStarExample.cs(71,26): error CS0115: `AStarExample.OnEditorGui()' is marked as an override but no suitable method found to override

    How I can fix it?
     
  4. JiHyun-LEE

    JiHyun-LEE

    Joined:
    Jan 8, 2016
    Posts:
    1
    Fixed, line 95 >> if((n.type=='-'|| n.type=='b') && !n.Closed)

    Thanks a lot