Advertisement
Danisuper

A* pathfinding unity

Aug 3rd, 2016
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.47 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Collections;
  5.  
  6. public class AStar : MonoBehaviour
  7. {
  8.  
  9.     public List<GameObject> open_list = new List<GameObject>(); //list of the nodes that have to be taken into account
  10.     public List<GameObject> closed_list = new List<GameObject>(); //list of the nodes that have already been considered
  11.     public List<GameObject> path_nodes = new List<GameObject>(); //the nodes of the final path
  12.  
  13.     public GameObject target;
  14.     public GameObject my_node;
  15.     GetClosestNode targ_node;
  16.     GetClosestNode actual_node;
  17.     NodeManager node_manager;
  18.     EnemyVars en_vars;
  19.     AdjacentNodes my_node_adjacent_nodes;//the nodes adjacent to my_node
  20.     RaycastHit2D ray_dx;
  21.     RaycastHit2D ray_sx;
  22.     RaycastHit2D ray_up;
  23.     RaycastHit2D ray_down;
  24.  
  25.     public Color a;
  26.     public Color b;
  27.     public Color c;
  28.     public Color d;
  29.  
  30.     public bool found_path;
  31.     public bool recalculate_path;
  32.  
  33.     //for path follow
  34.     public bool reached_dest; //if has reached the target
  35.     public int current_node = 0;
  36.     public float node_dist;
  37.     Vector3 dest;
  38.     Vector3 offset;
  39.  
  40.     float start_recalculate_time;
  41.     public float recalculate_time;
  42.     public bool delete_lists;
  43.  
  44.     // Use this for initialization
  45.     void Start()
  46.     {
  47.         targ_node = target.GetComponent<GetClosestNode>();
  48.         actual_node = gameObject.GetComponent<GetClosestNode>();
  49.         node_manager = GameObject.FindGameObjectWithTag("nodes manager").GetComponent<NodeManager>();
  50.         en_vars = gameObject.GetComponent<EnemyVars>();
  51.  
  52.         start_recalculate_time = recalculate_time;
  53.         recalculate_path = true;
  54.  
  55.     }
  56.  
  57.     // Update is called once per frame
  58.     void Update()
  59.     {
  60.         if (Input.GetKeyDown(KeyCode.R))
  61.         {
  62.             ResetPathLists();
  63.             delete_lists = true;
  64.         }
  65.  
  66.         //starts the pathfinding
  67.         if (recalculate_path)
  68.         {
  69.             FindPath(actual_node.my_node, targ_node.my_node);
  70.             recalculate_path = false;
  71.         }
  72.  
  73.         recalculate_time -= Time.deltaTime;
  74.         if (recalculate_time <= 0)
  75.         {
  76.             recalculate_time = start_recalculate_time;
  77.             recalculate_path = true;
  78.         }
  79.  
  80.         //if lines have been spawned recalculate everything
  81.         if (Input.GetKeyDown(KeyCode.Space))
  82.         {
  83.             delete_lists = true;
  84.             ResetPathLists();
  85.             FindPath(actual_node.my_node, targ_node.my_node);
  86.             found_path = false;
  87.         }
  88.  
  89.         if (found_path)
  90.         {
  91.             FollowPath();
  92.         }
  93.     }
  94.  
  95.     public void FindPath(GameObject start_node, GameObject target_node)
  96.     {
  97.         #region DEBUG colors the nodes
  98.         //DEBUG colors the nodes
  99.         if (open_list.Count > 0)
  100.             foreach (GameObject go in open_list)
  101.             {
  102.                 go.GetComponent<SpriteRenderer>().color = a;
  103.             }
  104.  
  105.         if (closed_list.Count > 0)
  106.             foreach (GameObject go in closed_list)
  107.             {
  108.                 if (!path_nodes.Contains(go))
  109.                     go.GetComponent<SpriteRenderer>().color = b;
  110.             }
  111.  
  112.         #endregion
  113.  
  114.         #region A*
  115.         //adds the first node in the open list
  116.         my_node = start_node;
  117.  
  118.         if (!open_list.Contains(my_node))
  119.         {
  120.             open_list.Add(my_node);
  121.         }
  122.  
  123.         if (open_list.Count > 0)
  124.         {
  125.             //sorts by movement cost
  126.             open_list = open_list.OrderBy(x => x.GetComponent<GetNodeMovementCost>().GetMovementCost(gameObject, x, target_node)).ToList();
  127.             my_node = open_list.First();
  128.             my_node_adjacent_nodes = my_node.GetComponent<AdjacentNodes>();
  129.  
  130.             //puts my node in the closed list
  131.             if (!closed_list.Contains(my_node))
  132.             {
  133.                 open_list.Remove(my_node);
  134.                 closed_list.Add(my_node);
  135.             }
  136.             //we found a way!
  137.             if (closed_list.Contains(target_node))
  138.             {
  139.                 BackTracePath();
  140.                 found_path = true;
  141.             }
  142.             else
  143.             {
  144.                 found_path = false;
  145.             }
  146.            
  147.             //finds the adjacent nodes
  148.             foreach (GameObject node in my_node_adjacent_nodes.adjacent_nodes)
  149.             {
  150.                 if (closed_list.Contains(node))
  151.                 {
  152.                     continue;
  153.                 }
  154.                 if (!open_list.Contains(node) && node.GetComponent<GetIfWalkable>().is_node_walkable)
  155.                 {
  156.                     open_list.Add(node);
  157.                     node.GetComponent<NodeParent>().parent = my_node;
  158.                     node.GetComponent<GetNodeMovementCost>().GetMovementCost(gameObject, node, target_node);
  159.                 }
  160.             }
  161.         }
  162.     }
  163.  
  164.     void ResetPathLists()
  165.     {
  166.         if (open_list.Count > 0 && closed_list.Count > 0 && path_nodes.Count > 0 && delete_lists)
  167.         {
  168.             open_list.Clear();
  169.             closed_list.Clear();
  170.             path_nodes.Clear();
  171.  
  172.             foreach (GameObject node in node_manager.nodes)
  173.             {
  174.                 node.GetComponent<SpriteRenderer>().color = Color.black;
  175.             }
  176.         }
  177.         delete_lists = false;
  178.  
  179.     }
  180.  
  181.     //manhattan distance
  182.     static public int Dist(GameObject node1, GameObject node2)
  183.     {
  184.         return Mathf.Abs(node2.GetComponent<GetNodeCoord>().NodeCoordX - node1.GetComponent<GetNodeCoord>().NodeCoordX) +
  185.             Mathf.Abs(node2.GetComponent<GetNodeCoord>().NodeCoordY - node1.GetComponent<GetNodeCoord>().NodeCoordY);
  186.     }
  187.  
  188.     #region path backtracing
  189.     //makes the final path
  190.     void BackTracePath()
  191.     {
  192.         GameObject node = targ_node.my_node;
  193.         //finds the parent
  194.         do
  195.         {
  196.             if (!path_nodes.Contains(node))
  197.             {
  198.                 path_nodes.Add(node);
  199.             }
  200.  
  201.             node.GetComponent<SpriteRenderer>().color = d;
  202.             node = node.GetComponent<NodeParent>().parent;
  203.  
  204.         } while (node != null);
  205.  
  206.         //reverses the list
  207.         path_nodes.Reverse();
  208.  
  209.         //finds the children nodes
  210.         for (int i = path_nodes.Count - 1; i > 0; i--)
  211.         {
  212.             GameObject child_node = path_nodes[i];
  213.             //if the parent isn't null
  214.             if (child_node.GetComponent<NodeParent>().parent != null)
  215.             {
  216.                 GameObject curr = child_node.GetComponent<NodeParent>().parent;
  217.                 curr.GetComponent<NodeParent>().child = child_node;
  218.             }
  219.             else//otherwise stop
  220.             {
  221.                 break;
  222.             }
  223.         }
  224.     }
  225.     #endregion
  226.     #endregion
  227.  
  228.     #region path follow
  229.     //follow the path
  230.     void FollowPath()
  231.     {
  232.         node_dist = Vector2.Distance(transform.position, dest);
  233.  
  234.         GameObject curr = path_nodes[current_node];
  235.         Vector2 dir = curr.transform.position - transform.position;
  236.  
  237.         if (dir.magnitude > 0.2f)
  238.         {
  239.             transform.position = Vector3.MoveTowards(transform.position, curr.transform.position, en_vars.speed * Time.deltaTime);
  240.             transform.rotation = UtilityFunctions.FaceTo(curr.transform.position, transform.position);
  241.         }
  242.         else
  243.         {
  244.             current_node++;
  245.             if (current_node >= path_nodes.Count)
  246.             {
  247.                 current_node = 0;
  248.             }
  249.         }
  250.     }
  251.     #endregion
  252. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement