Advertisement
Guest User

Untitled

a guest
Apr 10th, 2013
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.11 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System;
  5. using System.Net;
  6. using UnityEditor;
  7.  
  8. public class AStarSolver
  9. {
  10.     public Node[,] grid;
  11.     int gridLength;
  12.     int gridWidth;
  13.     float gridSize;
  14.    
  15.     Vector3 startPos;
  16.     Vector3 endPos;
  17.     public Node curNode;
  18.    
  19.     List<Node> openList = new List<Node>();
  20.     List<Node> closedList = new List<Node>();
  21.    
  22.     public Bounds bounds;
  23.    
  24.     List<Node> pathNodes = new List<Node>();
  25.        
  26.     public AStarSolver(GameObject bounds)
  27.     {
  28.         this.bounds = bounds.renderer.bounds;
  29.         GenerateGraph(5);
  30.     }
  31.    
  32.     public void Solve(Vector3 startPos, Vector3 endPos)
  33.     {
  34.         this.startPos = new Vector3(Mathf.FloorToInt(startPos.x),Mathf.FloorToInt(startPos.y),Mathf.FloorToInt(startPos.z));
  35.         this.endPos = new Vector3(Mathf.FloorToInt(endPos.x), Mathf.FloorToInt(endPos.y),Mathf.FloorToInt(endPos.z));
  36.        
  37.         bool canSearch = true;
  38.        
  39.         try
  40.         {
  41.             if(!GetNode(startPos).walkable || !GetNode(endPos).walkable)
  42.                 canSearch = false;
  43.         }catch{}
  44.        
  45.         if(canSearch)
  46.         {
  47.             curNode = GetNode(startPos);
  48.             openList.Add(curNode);
  49.            
  50.             while(openList.Count != 0)
  51.             {
  52.                 curNode = GetNodeWithLowestTotal(openList);
  53.                
  54.                 if(curNode == GetNode(endPos))
  55.                     break; //Path completed;
  56.                 else
  57.                 {
  58.                     openList.Remove(curNode);
  59.                     closedList.Add(curNode);
  60.                    
  61.                     if(openList.Count == 0)
  62.                         break; //Impossible path;
  63.                    
  64.                     List<Node> adjacentNodes = GetAdjacentNodes(curNode);
  65.                    
  66.                     foreach(Node adjNode in adjacentNodes)
  67.                     {
  68.                         if(!openList.Contains(adjNode) && !closedList.Contains(adjNode))
  69.                         {
  70.                             openList.Add(adjNode);
  71.                            
  72.                             Node node = adjNode;
  73.                             node.cost = curNode.cost + 10;
  74.                             node.heuristic = ManhattanDistance(adjNode);
  75.                             node.total = node.cost + node.heuristic;
  76.                         }
  77.                     }
  78.                 }
  79.             }
  80.         }
  81.     }
  82.    
  83.     public int ManhattanDistance(Node adjNode)
  84.     {
  85.         int manhattan = Math.Abs((int)(endPos.x - adjNode.pos.x)) + Math.Abs((int)(endPos.y - adjNode.pos.y));
  86.             return manhattan;
  87.     }
  88.    
  89.     public void TracePath()
  90.     {
  91.         bool startFound = false;
  92.        
  93.         Node currentNode = GetNode(endPos);
  94.         pathNodes = new List<Node>();
  95.        
  96.         while(!startFound)
  97.         {
  98.             List<Node> adjacentNodes = GetAdjacentNodes(currentNode);
  99.            
  100.             foreach(Node adjNode in adjacentNodes)
  101.             {
  102.                 if(adjNode.pos == startPos)
  103.                     startFound = true;
  104.                
  105.                 if(closedList.Contains(adjNode) || openList.Contains(adjNode))
  106.                 {
  107.                     if(adjNode.cost <= currentNode.cost && adjNode.cost > 0)
  108.                     {
  109.                         curNode = adjNode;
  110.                         pathNodes.Add(adjNode);
  111.                         break;
  112.                     }
  113.                 }
  114.             }
  115.         }
  116.     }
  117.    
  118.     public Node GetNodeWithLowestTotal(List<Node> openList)
  119.     {
  120.         Vector3 nodePos = Vector3.zero;
  121.         int lowestTotal = int.MaxValue;
  122.        
  123.        
  124.         foreach(Node openNode in openList)
  125.         {
  126.             if(openNode.total <= lowestTotal)
  127.             {
  128.                 lowestTotal = openNode.total;
  129.                 nodePos = openNode.pos;
  130.             }
  131.         }
  132.         return GetNode(nodePos);
  133.     }
  134.    
  135.     public List<Vector3> GetPath()
  136.     {
  137.         //Returns a list of points for an agent to follow.
  138.         List<Vector3> points = new List<Vector3>();
  139.        
  140.         for(int i = 0; i < pathNodes.Count; i++)
  141.         {
  142.             points[i] = pathNodes[i].pos;
  143.         }
  144.         return points;
  145.     }
  146.    
  147.     public Node GetNode(Vector3 pos)
  148.     {
  149.         //Searches for a node with a specific vector.
  150.         Vector3 roundedPos = new Vector3(Mathf.FloorToInt(pos.x), Mathf.FloorToInt(pos.y), Mathf.FloorToInt(pos.z));
  151.        
  152.         for(int i = 0; i < gridLength; i++)
  153.         {
  154.             for(int j = 0; j < gridWidth; j++)
  155.             {
  156.                 if(grid[i,j].pos == roundedPos)
  157.                     return grid[i,j];
  158.             }
  159.         }
  160.         return null;
  161.     }
  162.    
  163.     public List<Node> GetAdjacentNodes(Node curNode)
  164.     {
  165.         List<Node> adjacentNodes = new List<Node>();
  166.        
  167.         try
  168.         {
  169.             //Node in front
  170.             Vector3 adjacentNode = curNode.pos + new Vector3(0,0,gridSize);
  171.             if(GetNode(adjacentNode).walkable)
  172.                 adjacentNodes.Add(GetNode(adjacentNode));
  173.         }
  174.         catch{}
  175.        
  176.         try
  177.         {
  178.             //Node behind
  179.             Vector3 adjacentNode = curNode.pos + new Vector3(0,0,-gridSize);
  180.             if(GetNode(adjacentNode).walkable)
  181.                 adjacentNodes.Add(GetNode(adjacentNode));
  182.         }
  183.         catch{}
  184.        
  185.         try
  186.         {
  187.             //Node to the left
  188.             Vector3 adjacentNode = curNode.pos + new Vector3(-gridSize,0,0);
  189.             if(GetNode(adjacentNode).walkable)
  190.                 adjacentNodes.Add(GetNode(adjacentNode));
  191.         }
  192.         catch{}
  193.        
  194.         try
  195.         {
  196.             //Node to the right
  197.             Vector3 adjacentNode = curNode.pos + new Vector3(gridSize,0,0);
  198.             if(GetNode(adjacentNode).walkable)
  199.                 adjacentNodes.Add(GetNode(adjacentNode));
  200.         }
  201.         catch{}
  202.        
  203.         return adjacentNodes;
  204.     }
  205.    
  206.     public void GenerateGraph(float gridScale)
  207.     {
  208.         //Generates the node graph used in the grid.
  209.         //Gridsize is how much distance between cells, smaller = more precise
  210.        
  211.         this.gridSize = gridScale;
  212.        
  213.         //top left corner of cube
  214.         Vector3 topLeftCorner = bounds.center - bounds.extents + new Vector3(0, bounds.size.y,0);
  215.         gridWidth = Mathf.RoundToInt(bounds.size.x / gridSize);
  216.         gridLength = Mathf.RoundToInt(bounds.size.z / gridSize);
  217.        
  218.         grid = new Node[gridWidth, gridLength];
  219.        
  220.         for(int x = 0; x < gridWidth; x++)
  221.         {
  222.             for(int z = 0; z < gridLength; z++)
  223.             {
  224.                 Vector3 currentPosition = topLeftCorner + new Vector3(x * gridSize, 0, z * gridSize);
  225.                 RaycastHit hit;
  226.                
  227.                 //create new node for grid
  228.                 grid[x,z] = new Node(new Vector3((int)(topLeftCorner.x + x * gridSize),0,(int)(topLeftCorner.z + z * gridSize)), false, new Vector2(x,z));
  229.                
  230.                 if(Physics.Raycast(currentPosition, -Vector3.up, out hit, bounds.size.y))
  231.                 {
  232.                     grid[x,z].pos.y = hit.point.y;
  233.                     if(Vector3.Angle(hit.normal, currentPosition) < 50)
  234.                     {
  235.                         if(hit.collider.gameObject.tag == "Walkable")
  236.                         {
  237.                             grid[x,z].walkable = true;
  238.                         }
  239.                     }
  240.                 }
  241.             }
  242.         }
  243.     }
  244.    
  245.     public void DrawNodeGraph()
  246.     {
  247.         for(int x = 0; x < gridWidth; x++)
  248.         {
  249.             for(int z = 0; z < gridLength; z++)
  250.             {
  251.                 Gizmos.DrawSphere(grid[x,z].pos, 0.5f);
  252.             }
  253.         }
  254.     }
  255.    
  256.     public void DrawPath()
  257.     {
  258.         List<Vector3> path = GetPath();
  259.        
  260.         for(int i = 0; i < path.Count; i++)
  261.         {
  262.             Gizmos.DrawSphere(path[i], 1f);
  263.             if(i+1 < path.Count)
  264.                 Gizmos.DrawLine(path[i], path[i+1]);
  265.         }
  266.     }
  267. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement