Advertisement
Guest User

Untitled

a guest
Nov 7th, 2016
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.70 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. public class Seeker : MonoBehaviour
  5. {
  6.     public List<NodeElement> path = new List<NodeElement>();
  7.     public NodeElement curNode;
  8.     public NodeElement LastDestination;
  9.     Transform tr;
  10.     public NodeElement LastPathElement()
  11.     {
  12.         return path[path.Count - 1];
  13.     }
  14.  
  15.     protected virtual void Start()
  16.     {
  17.         tr = transform;
  18.         curNode = PathfindingMap.VecToNode(Mathf.RoundToInt(tr.position.x), Mathf.RoundToInt(tr.position.z));
  19.         path.Add(curNode);
  20.         LastDestination = curNode;
  21.         curNode.occupied = this;
  22.     }
  23.     public Animator anim;
  24.     public float Speed = 4;
  25.  
  26.     public Quaternion DesiredRotation;
  27.     protected virtual void Rotate()
  28.     {
  29.         if (path.Count > 1)
  30.         {
  31.             DesiredRotation = Quaternion.LookRotation(path[1].pos() - curNode.pos());
  32.             transform.rotation = Quaternion.Slerp(transform.rotation, DesiredRotation, Time.deltaTime * 4);
  33.         }
  34.     }
  35.     public bool StoppedMoving()
  36.     {
  37.         return path.Count <= 1 && searching == false;
  38.     }
  39.     protected virtual void RecalculatePath() { }
  40.     protected virtual void LateUpdate()
  41.     {
  42.         Rotate();
  43.         if (path.Count > 1)
  44.         {
  45.             Vector3 pos = path[1].pos();
  46.             transform.position = Vector3.Lerp(transform.position, pos, Time.deltaTime * Speed);
  47.             if (Vector3.Distance(transform.position, pos) < 0.4f)
  48.             {
  49.                 path[0].occupied = null;
  50.                 path.RemoveAt(0);
  51.                 path[0].occupied = this;
  52.                 curNode = path[0];
  53.             }
  54.             anim.SetFloat("Speed", 1);
  55.         }
  56.         else
  57.         {
  58.             if (path.Count == 0)
  59.             {
  60.                 path.Add(curNode);
  61.             }
  62.             path[0].occupied = this;
  63.             anim.SetFloat("Speed", 0);
  64.         }
  65.  
  66.     }
  67.  
  68.     public void SetDestination(Vector3 _pos, bool recalculating = false)
  69.     {
  70.  
  71.         int x = Mathf.RoundToInt(_pos.x);
  72.         int y = Mathf.RoundToInt(_pos.z);
  73.         SetDestination(PathfindingMap.VecToNode(x, y), recalculating);
  74.     }
  75.     List<NodeElement> _path = new List<NodeElement>();
  76.     public void SetDestination(NodeElement goal, bool recalculating = false)
  77.     {
  78.         if (goal != null)
  79.             if (SquareGrid.InBounds(goal))
  80.             {
  81.                 if (goal != curNode && (goal != LastDestination || recalculating == true) && searching == false)
  82.                 {
  83.                     LastDestination = goal;
  84.                     goal = FindNearestReachable(goal,false);
  85.                     StartCoroutine(MultiThreadAStar(goal));
  86.                 }
  87.             }
  88.     }
  89.     protected List<NodeElement> searchedNodes = new List<NodeElement>();
  90.     public NodeElement FindNearestReachable(NodeElement nod, bool recalculating)
  91.     {
  92.         searchedNodes = new List<NodeElement>();
  93.         if (recalculating==true?nod.Passable():nod.Passable(this))
  94.         {
  95.             return nod;
  96.         }
  97.         else
  98.         {
  99.             searchedNodes.Add(nod);
  100.             NodeElement cur = nod;
  101.             int i = 0;
  102.             do
  103.             {
  104.                 for (int q = 0; q < SquareGrid.DIRS.Length; q++)
  105.                 {
  106.                     NodeElement node = PathfindingMap.VecToNode(cur.x + SquareGrid.DIRS[q].x, cur.y + SquareGrid.DIRS[q].y);
  107.                     if (!searchedNodes.Contains(node))
  108.                     {
  109.                         i++;
  110.                         searchedNodes.Add(node);
  111.                         if (node.Passable(this))
  112.                         {
  113.                             return node;
  114.                         }
  115.                     }
  116.                 }
  117.                 cur = searchedNodes[i];
  118.             }
  119.             while (cur != null);
  120.             return null;
  121.         }
  122.     }
  123.     static public double Heuristic(NodeElement a, NodeElement b)
  124.     {
  125.         return Mathf.Abs(a.x - b.x) + Mathf.Abs(a.y - b.y);
  126.     }
  127.     public NodeElement _start, _goal, closestPossible;
  128.     PriorityQueue frontier;
  129.     protected bool searching = false;
  130.     public static int MaxNodesPerSearch = 250;
  131.     public Dictionary<NodeElement, NodeElement> camefrom = new Dictionary<NodeElement, NodeElement>();
  132.     public Dictionary<NodeElement, double> costsofar = new Dictionary<NodeElement, double>();
  133.     protected bool unreachableTarget = false;
  134.     static int count = 0;
  135.     public IEnumerator MultiThreadAStar(NodeElement goal)
  136.     {
  137.         searching = true;
  138.         SquareGrid graph = PathfindingMap.grid();
  139.         frontier = new PriorityQueue();
  140.         frontier.Enqueue(curNode, 0);
  141.         _start = curNode;
  142.         _goal = goal;
  143.         camefrom.Clear();
  144.         costsofar.Clear();
  145.         camefrom[_start] = _start;
  146.         costsofar[_start] = 0;
  147.         closestPossible = _start;
  148.         count = 0;
  149.         while (frontier.Count > 0)
  150.         {
  151.             NodeElement current = frontier.Dequeue();
  152.             if (current.Equals(goal))
  153.             {
  154.                 break;
  155.             }
  156.             Debug.DrawLine(current.pos(), current.pos() + Vector3.up * 3, Color.blue, 1);
  157.             foreach (var next in SquareGrid.Neighbors(current, this))
  158.             {
  159.                 double newCost = costsofar[current] + graph.Cost(current, next);
  160.                 if (!costsofar.ContainsKey(next)
  161.                   || newCost < costsofar[next])
  162.                 {
  163.                     count++;
  164.                     if (count > MaxNodesPerSearch)
  165.                     {
  166.                         yield return null;
  167.                         count = 0;
  168.                     }
  169.                     double h = Heuristic(next, goal);
  170.                     double h2 = Heuristic(closestPossible, goal);
  171.                     double priority = newCost + Heuristic(next, goal);
  172.                     frontier.Enqueue(next, priority);
  173.                     camefrom[next] = current;
  174.                     costsofar[next] = newCost;
  175.                     if (h2 > h)
  176.                     {
  177.                         closestPossible = next;
  178.                     }
  179.                 }
  180.             }
  181.         }
  182.         FindShortestPath();
  183.         searching = false;
  184.  
  185.     }
  186.     public void FindShortestPath()
  187.     {
  188.         path.Clear();
  189.         NodeElement next = _goal;
  190.         if (!camefrom.ContainsKey(next))
  191.         {
  192.             next = closestPossible;
  193.         }
  194.         path.Add(next);
  195.         for (int i = 0; i < camefrom.Count; i++)
  196.         {
  197.             next = camefrom[next];
  198.             path.Add(next);
  199.             if (next == _start)
  200.             {
  201.                 path.Reverse();
  202.                 break;
  203.             }
  204.         }
  205.     }
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement