Advertisement
jn327

Unity Character pathfinding

Jun 20th, 2014
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.41 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5.  
  6. public class CharacterControls : MonoBehaviour {
  7.  
  8.     public bool moveDestSet = false;
  9.  
  10.  
  11.     public int moveDistance = 3; //How far can the character move
  12.  
  13.  
  14.     public List<PathNode> direction = new List<PathNode>();
  15.  
  16.     float moveSpeed = 1.0f;
  17.     public int currentlyOccupiedNodeIndex = 0;
  18.     public GameObject endPoint;
  19.     public PathNode occupiedNode;
  20.     RaycastHit obj_ray_hit;
  21.     Ray obj_ray;
  22.    
  23.     void Update ()
  24.     {
  25.         if (!occupiedNode)
  26.         {
  27.             foreach(GameObject tile in GameManager.FloorTiles)
  28.             {
  29.                 if (tile.transform.position.x == transform.position.x && tile.transform.position.z == transform.position.z)
  30.                 {
  31.                     occupiedNode = tile.GetComponent<PathNode>();
  32.                 }
  33.             }
  34.         }
  35.         if (!moveDestSet)
  36.         {
  37.             obj_ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  38.             if (Physics.Raycast(obj_ray, out obj_ray_hit, 1000))
  39.             {
  40.                 if (endPoint == obj_ray_hit.collider.gameObject)
  41.                 {
  42.                     Debug.Log("End point(" +endPoint.transform.position.x +"," +endPoint.transform.position.z +") is same as hit gO (" +obj_ray_hit.collider.gameObject.transform.position.x +"," +obj_ray_hit.collider.gameObject.transform.position.z);
  43.                 }
  44.                 else
  45.                 {
  46.                     //Now is when Unity Freezes (as long as player has moved once).
  47.                     Debug.Log("End point is not the same as hit gO");
  48.                 }
  49.                 if (obj_ray_hit.collider.gameObject.tag == "Floor" && obj_ray_hit.collider.gameObject != endPoint)
  50.                 {
  51.                     Debug.Log("Ray hit new floor tile, cleaning tiles & setting new endPoint");
  52.                     endPoint = obj_ray_hit.collider.gameObject;
  53.  
  54.                     foreach(GameObject tile in GameManager.FloorTiles)
  55.                     {
  56.                         tile.renderer.material.color = Color.white;
  57.                     }
  58.  
  59.                     Debug.Log("Setting new direction from ("+occupiedNode.transform.position.x +"," +occupiedNode.transform.position.z +") to (" +endPoint.transform.position.x +"," +endPoint.transform.position.z);
  60.  
  61.                     direction.Clear();
  62.                     direction = GetPath(occupiedNode,endPoint.GetComponent<PathNode>());
  63.  
  64.                     if (direction.Count <= moveDistance)
  65.                     {
  66.                         foreach(PathNode tile in direction)
  67.                         {
  68.                             tile.renderer.material.color = Color.green;
  69.                         }
  70.                     }
  71.                     else
  72.                     {
  73.                         foreach(PathNode tile in direction)
  74.                         {
  75.                             tile.renderer.material.color = Color.red;
  76.                         }
  77.                     }
  78.                     Debug.Log("Got new endpoint " +endPoint +" & colored path");
  79.                 }
  80.             }
  81.             //If the user inputs a mouse button then we can start moving.
  82.             if (Input.GetMouseButtonDown(0))
  83.             {
  84.                 if (direction.Count <= moveDistance && endPoint.GetComponent<PathNode>() != occupiedNode)
  85.                 {
  86.                     moveDestSet = true;
  87.                     currentlyOccupiedNodeIndex = direction.Count-1;
  88.                 }
  89.                 else
  90.                 {
  91.                     Debug.Log("Can't move here");
  92.                 }
  93.             }
  94.            
  95.         }
  96.         else //moveDestSet == true (Move destination has been set)
  97.         {
  98.             Debug.Log("Move destination has been set, checking if we have reached it, if not moving to it.");
  99.             if (currentlyOccupiedNodeIndex >= 0)
  100.             {
  101.                 Debug.Log("Moving to node " +currentlyOccupiedNodeIndex);
  102.                 if (transform.position.x != direction[currentlyOccupiedNodeIndex].transform.position.x || transform.position.z != direction[currentlyOccupiedNodeIndex].transform.position.z)
  103.                 {
  104.                     transform.position = Vector3.MoveTowards(transform.position, new Vector3(direction[currentlyOccupiedNodeIndex].transform.position.x, transform.position.y, direction[currentlyOccupiedNodeIndex].transform.position.z), Time.deltaTime * moveSpeed);
  105.                 }
  106.                 if (transform.position.x == direction[currentlyOccupiedNodeIndex].transform.position.x && transform.position.z == direction[currentlyOccupiedNodeIndex].transform.position.z)
  107.                 {
  108.                     Debug.Log("Arrived at node ("+transform.position.x +", " +transform.position.z +") "+currentlyOccupiedNodeIndex +" :"  +direction[currentlyOccupiedNodeIndex] +" (" +direction[currentlyOccupiedNodeIndex].transform.position.x +"," +direction[currentlyOccupiedNodeIndex].transform.position.z +") Moving on to next node");
  109.                     currentlyOccupiedNodeIndex --;
  110.                 }
  111.             }
  112.             else
  113.             {
  114.                 Debug.Log("You have arrived at your destination " +currentlyOccupiedNodeIndex +" (" +transform.position.x +"," +transform.position.z +")");
  115.                 endPoint = null;
  116.                 occupiedNode = direction[currentlyOccupiedNodeIndex+1]; //so that next point the occupied node does not have to be set.
  117.                 moveDestSet = false;
  118.             }
  119.         }
  120.     }
  121.  
  122.  
  123.     List<PathNode> GetPath(PathNode startNode, PathNode endNode)
  124.     {
  125.         List<PathNode> openList = new List<PathNode>();
  126.         List<PathNode> closedList = new List<PathNode>();
  127.         PathNode currentNode = startNode;
  128.         bool foundTarget = false;
  129.         int movementCost = 1;
  130.         List<PathNode> PathToTake = new List<PathNode>();
  131.        
  132.         while (!foundTarget)
  133.         {
  134.             if (startNode == endNode || currentNode == endNode)
  135.             {
  136.                 foundTarget = true;
  137.                 continue;
  138.             }
  139.             foreach (PathNode nextNode in currentNode.neighbors)
  140.             {
  141.                 if (nextNode != null) {
  142.                     if (nextNode == endNode)
  143.                     {
  144.                         endNode.Parent = currentNode;
  145.                         foundTarget = true;
  146.                         continue;
  147.                     }
  148.                     if (!closedList.Contains (nextNode))
  149.                     {
  150.                         checkNext(nextNode,currentNode,openList,movementCost,endNode);
  151.                     }
  152.                 }
  153.             }
  154.  
  155.            
  156.             if (!foundTarget) {
  157.                 closedList.Add (currentNode);
  158.                 openList.Remove (currentNode);
  159.                 //Get smallest f node.
  160.                 int smallestF = 10000;
  161.                 PathNode smallestNode = null;
  162.                 foreach (PathNode node in openList)
  163.                 {
  164.                     if (node.heuristicValue < smallestF)
  165.                     {
  166.                         smallestNode = node;
  167.                         smallestF = node.heuristicValue;
  168.                     }
  169.                 }
  170.                 currentNode = smallestNode;
  171.             }
  172.         }
  173.         PathNode endPathNode = endNode;
  174.         while (endPathNode != null)
  175.         {
  176.             if (!PathToTake.Contains(endPathNode))
  177.             {
  178.                 PathToTake.Add(endPathNode);
  179.             }
  180.             endPathNode = endPathNode.Parent;
  181.         }
  182.         return PathToTake;
  183.     }
  184.  
  185.  
  186.  
  187.     void checkNext (PathNode NextNode, PathNode currentNode, List<PathNode> openList, int movementCost, PathNode endNode)
  188.     {
  189.         if (openList.Contains (NextNode))
  190.         {
  191.             int newMovementCost = currentNode.movementCost + movementCost;
  192.             if (newMovementCost < NextNode.movementCost)
  193.             {
  194.                 NextNode.Parent = currentNode;
  195.                 NextNode.movementCost = newMovementCost;
  196.                 NextNode.calculateFValue (endNode);
  197.             }
  198.         }
  199.         else
  200.         {
  201.             NextNode.Parent = currentNode;
  202.             NextNode.movementCost = currentNode.movementCost + movementCost;
  203.             NextNode.calculateFValue(endNode);
  204.             openList.Add(NextNode);
  205.         }
  206.     }
  207. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement