Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System.Collections.Generic;
- using System.Linq;
- using System.Collections;
- public class AStar : MonoBehaviour
- {
- public List<GameObject> open_list = new List<GameObject>(); //list of the nodes that have to be taken into account
- public List<GameObject> closed_list = new List<GameObject>(); //list of the nodes that have already been considered
- public List<GameObject> adjacent_nodes = new List<GameObject>();
- public List<GameObject> path_nodes = new List<GameObject>(); //the nodes of the final path
- public GameObject target;
- public GameObject my_node;
- GetClosestNode targ_node;
- GetClosestNode actual_node;
- NodeManager node_manager;
- EnemyVars en_vars;
- RaycastHit2D ray_dx;
- RaycastHit2D ray_sx;
- RaycastHit2D ray_up;
- RaycastHit2D ray_down;
- public Color a;
- public Color b;
- public Color c;
- public Color d;
- public bool found_path;
- public bool recalculate_path;
- //for the path follow
- public bool reached_dest; //if it reached the target
- public int current_node = 0;
- float node_dist;
- Vector3 dest;
- float start_recalculate_time;
- public float recalculate_time;
- public bool delete_lists;
- // Use this for initialization
- void Start()
- {
- targ_node = target.GetComponent<GetClosestNode>();
- actual_node = gameObject.GetComponent<GetClosestNode>();
- node_manager = GameObject.FindGameObjectWithTag("nodes manager").GetComponent<NodeManager>();
- en_vars = gameObject.GetComponent<EnemyVars>();
- start_recalculate_time = recalculate_time;
- recalculate_path = true;
- FindPath(actual_node.my_node, targ_node.my_node);
- }
- // Update is called once per frame
- void Update()
- {
- //starts the pathfinding
- if (recalculate_path)
- {
- FindPath(actual_node.my_node, targ_node.my_node);
- recalculate_path = false;
- }
- recalculate_time -= Time.deltaTime;
- if (recalculate_time <= 0)
- {
- recalculate_time = start_recalculate_time;
- recalculate_path = true;
- }
- //if lines have been spawned recalculate everything
- if (Input.GetKeyDown(KeyCode.Space))
- {
- delete_lists = true;
- ResetPathLists();
- if (!delete_lists)
- FindPath(actual_node.my_node, targ_node.my_node);
- }
- else
- {
- //if the target has moved (I check it by seeing if it changed node)
- if(targ_node.changed_node)
- {
- found_path = false;
- reached_dest = false;
- FindPath(actual_node.my_node, targ_node.my_node);
- }
- }
- if(path_nodes.Count>0)
- {
- FollowPath();
- }
- if(reached_dest)
- {
- delete_lists = true;
- ResetPathLists();
- }
- }
- public void FindPath(GameObject start_node, GameObject target_node)
- {
- #region DEBUG colors the nodes
- //DEBUG colors the nodes
- if (open_list.Count > 0)
- foreach (GameObject go in open_list)
- {
- go.GetComponent<SpriteRenderer>().color = a;
- }
- if (closed_list.Count > 0)
- foreach (GameObject go in closed_list)
- {
- if (!path_nodes.Contains(go))
- go.GetComponent<SpriteRenderer>().color = b;
- }
- #endregion
- #region A*
- //adds the first node to the open list
- my_node = start_node;
- if (!open_list.Contains(my_node) && !reached_dest)
- {
- open_list.Add(my_node);
- }
- if (open_list.Count > 0 && !found_path && !reached_dest)
- {
- //sorts by movement cost
- open_list = open_list.OrderBy(x => x.GetComponent<GetNodeMovementCost>().GetMovementCost(gameObject, x, target_node)).ToList();
- my_node = open_list.First();
- //puts my node in the closed list
- if (!closed_list.Contains(my_node) && !actual_node.changed_node && !found_path && !reached_dest)
- {
- open_list.Remove(my_node);
- closed_list.Add(my_node);
- }
- //we found a way!
- if (closed_list.Contains(target_node) && !targ_node.changed_node)
- {
- BackTracePath();
- found_path = true;
- }
- //finds the adjacent nodes
- FindAdjacentNodes(my_node);
- if (adjacent_nodes.Count > 0)
- foreach (GameObject node in adjacent_nodes)
- {
- if (closed_list.Contains(node))
- {
- continue;
- }
- if (!open_list.Contains(node))
- {
- open_list.Add(node);
- node.GetComponent<NodeParent>().parent = my_node;
- node.GetComponent<GetNodeMovementCost>().GetMovementCost(gameObject, node, target_node);
- }
- }
- }
- }
- //It makes crash everything
- void ResetPathLists()
- {
- if (adjacent_nodes.Count > 0 && open_list.Count > 0 && closed_list.Count > 0 && path_nodes.Count > 0 && delete_lists)
- {
- adjacent_nodes.Clear();
- open_list.Clear();
- closed_list.Clear();
- path_nodes.Clear();
- foreach (GameObject node in node_manager.nodes)
- {
- node.GetComponent<SpriteRenderer>().color = Color.black;
- }
- }
- delete_lists = false;
- }
- #region adds adjacent nodes
- void FindAdjacentNodes(GameObject node)
- {
- //8 dir raycasting
- RaycastHit2D ray_dx = Physics2D.Raycast(node.transform.position, Vector2.right, node_manager.NodesDistance);
- RaycastHit2D ray_sx = Physics2D.Raycast(node.transform.position, -Vector2.right, node_manager.NodesDistance);
- RaycastHit2D ray_up = Physics2D.Raycast(node.transform.position, Vector2.up, node_manager.NodesDistance);
- RaycastHit2D ray_down = Physics2D.Raycast(node.transform.position, -Vector2.up, node_manager.NodesDistance);
- //multiply for the square of 2 to find the lenght of the diagonal
- RaycastHit2D ray_up_dx = Physics2D.Raycast(node.transform.position, Vector2.right + Vector2.up, node_manager.NodesDistance * Mathf.Sqrt(2));
- RaycastHit2D ray_up_sx = Physics2D.Raycast(node.transform.position, -Vector2.right + Vector2.up, node_manager.NodesDistance * Mathf.Sqrt(2));
- RaycastHit2D ray_down_dx = Physics2D.Raycast(node.transform.position, Vector2.right - Vector2.up, node_manager.NodesDistance * Mathf.Sqrt(2));
- RaycastHit2D ray_down_sx = Physics2D.Raycast(node.transform.position, -Vector2.right - Vector2.up, node_manager.NodesDistance * Mathf.Sqrt(2));
- AddAdjacentNodes(ray_dx);
- AddAdjacentNodes(ray_sx);
- AddAdjacentNodes(ray_up);
- AddAdjacentNodes(ray_down);
- AddAdjacentNodes(ray_up_dx);
- AddAdjacentNodes(ray_up_sx);
- AddAdjacentNodes(ray_down_dx);
- AddAdjacentNodes(ray_down_sx);
- }
- void AddAdjacentNodes(RaycastHit2D ray)
- {
- if (ray.collider != null && ray.collider.gameObject.tag == "node" && !adjacent_nodes.Contains(ray.collider.gameObject) &&
- !closed_list.Contains(ray.collider.gameObject) && ray.collider.gameObject.GetComponent<GetIfWalkable>().is_node_walkable)
- {
- adjacent_nodes.Add(ray.collider.gameObject);
- }
- }
- #endregion
- //finds the manhattan distance
- static public int Dist(GameObject node1, GameObject node2)
- {
- return Mathf.Abs(node2.GetComponent<GetNodeCoord>().NodeCoordX - node1.GetComponent<GetNodeCoord>().NodeCoordX) +
- Mathf.Abs(node2.GetComponent<GetNodeCoord>().NodeCoordY - node1.GetComponent<GetNodeCoord>().NodeCoordY);
- }
- #region path backtracing
- //makes the final path
- void BackTracePath()
- {
- GameObject node = targ_node.my_node;
- do
- {
- if (!path_nodes.Contains(node))
- {
- path_nodes.Add(node);
- }
- node.GetComponent<SpriteRenderer>().color = d;
- node = node.GetComponent<NodeParent>().parent;
- } while (node != null);
- //puts the gameobject's node at the beginning of the list
- if (!path_nodes.Contains(actual_node.my_node))
- {
- path_nodes.Insert(0, actual_node.my_node);
- }
- //reverse the list
- path_nodes.Reverse();
- }
- #endregion
- #endregion
- #region path follow
- //follows the path
- public void FollowPath()
- {
- AssignFollowVars();
- //if we didn't reach the destination
- if (reached_dest == false)
- {
- //if the distance is > than 0.1 move towards the node
- if (node_dist > 0.1f)
- {
- transform.position = Vector3.MoveTowards(transform.position, dest, en_vars.speed * Time.deltaTime);
- transform.rotation = UtilityFunctions.FaceTo(GetNodePos(current_node), transform.position);
- }
- else
- {
- current_node++;
- }
- //if the target isn't moving and the gameobject's node is the last in the list or we reached it
- if ((current_node >= path_nodes.Count && !targ_node.changed_node) || actual_node.my_node == targ_node.my_node)
- {
- reached_dest = true;
- current_node = 0;
- }
- else
- {
- reached_dest = false;
- }
- }
- else
- {
- current_node = 0;
- }
- }
- void AssignFollowVars()
- {
- path_nodes.OrderBy(x => Vector2.Distance(path_nodes.First().transform.position, x.transform.position));
- if (!reached_dest)
- {
- dest = GetNodePos(current_node);
- node_dist = Vector2.Distance(transform.position, dest);
- }
- }
- //gets the node position based on its index
- Vector3 GetNodePos(int n_node)
- {
- if (n_node < path_nodes.Count)
- {
- return path_nodes[n_node].transform.position;
- }
- else
- {
- return Vector3.zero;
- }
- }
- #endregion
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement