/// <summary>
        /// Creates the nodes in the space of the grid size.
        /// </summary>
        public void CreateNode(Vector3 vertPoint, TerrainData data, int x, int z, bool accessableRegion)
        {
            newData = data;

            if (nodes.Count == 0)
            {
                grid = new PathingNode[newData.heightmapWidth, newData.heightmapHeight];
            }

            Vector3 nodeOffset   = new Vector3(0, nodeRadius, 0);
            Vector3 newNodePoint = vertPoint;

            bool walkable = !(Physics.CheckSphere(newNodePoint, nodeRadius, unwalkableMask));

            if (!accessableRegion)
            {
                walkable = false;
            }

            grid[x, z] = new PathingNode(walkable, newNodePoint, x, z);

            nodes.Add(grid[x, z]);

            // Debug.Log(grid[x, z].gridX + ", " + grid[x, z].gridY );
        }
        public List <PathingNode> GetNeigbours(PathingNode node)
        {
            StatusUpdate("Now trying to get a list of neigbours");

            List <PathingNode> neigbours = new List <PathingNode>();

            for (int x = -1; x <= 1; x++)
            {
                for (int y = -1; y <= 1; y++)
                {
                    if (x == 0 && y == 0)
                    {
                        continue;
                    }

                    int checkX = node.gridX + x;
                    int checkY = node.gridY + y;

                    if (checkX >= 0 && checkX < gridSizeX && checkY >= 0 && checkY < gridSizeZ)
                    {
                        neigbours.Add(grid[checkX, checkY]);
                    }
                }
            }
            return(neigbours);
        }
        /// <summary>
        /// essenially returns a huristic cost
        /// </summary>
        /// <param name="nodeA"></param>
        /// <param name="nodeB"></param>
        /// <returns></returns>
        static float GetDistance(PathingNode nodeA, PathingNode nodeB)
        {
            int distanceX = Mathf.Abs(nodeA.gridX - nodeB.gridX);
            int distanceY = Mathf.Abs(nodeA.gridY - nodeB.gridY);

            if (distanceX > distanceY)
            {
                return(14 * distanceY + 10 * (distanceX - distanceY));
            }

            return(14 * distanceX + 10 * (distanceY - distanceX));
        }
        /// <summary>
        /// Returns a list of the path taken to find the "Goal".
        /// </summary>
        /// <param name="startNode"></param>
        /// <param name="endNode"></param>
        /// <returns></returns>
        static List <PathingNode> RetacePath(PathingNode startNode, PathingNode endNode)
        {
            NodeManager.instance.StatusUpdate("Now running a retrace path to return the path to target");

            List <PathingNode> path     = new List <PathingNode>();
            PathingNode        currNode = endNode;

            while (currNode != startNode)
            {
                path.Add(currNode);
                currNode = currNode.parent;
            }


            path.Reverse();
            return(path);
        }
        public void CalulateLighting(Torch source)
        {
            PathingNode sourceNode = NodeFromWorldPoint(source.transform.position);

            sourceNode.AssignField(null, source);
        }
        /// <summary>
        /// Uses the astar algorithim to return a path.
        /// Turns the passed in positions and turns them into nodes.
        ///
        /// </summary>
        /// <param name="startPoint"></param>
        /// <param name="endPoint"></param>
        public static List <PathingNode> FindPath(Vector3 startPoint, Vector3 endPoint)
        {
            PathingNode startNode = grid.NodeFromWorldPoint(startPoint);
            PathingNode endNode   = grid.NodeFromWorldPoint(endPoint);

            Heaping <PathingNode> openList   = new Heaping <PathingNode>(grid.MaxSize);
            HashSet <PathingNode> closedList = new HashSet <PathingNode>();

            openList.Add(startNode);

            Stopwatch sw = new Stopwatch();

            sw.Start();


            NodeManager.instance.StatusUpdate("Now starting A* pathing");
            //  Debug.Log(startNode.node.spacialInfo + " : " + endNode.node.spacialInfo);
            while (openList.Count > 0)
            {
                NodeManager.instance.StatusUpdate("Now running A* pathing");

                //Hack: Un-preforment
                PathingNode currentNode = openList.RemoveFirst();
                closedList.Add(currentNode);

                if (currentNode == endNode)
                {
                    grid.path = RetacePath(startNode, endNode);
                    sw.Stop();
                    // UnityEngine.Debug.Log("Path successful. Time Taken: " + sw.ElapsedMilliseconds + "ms");
                    return(RetacePath(startNode, endNode));
                }



                foreach (PathingNode neigbouringNode in grid.GetNeigbours(currentNode))
                {
                    NodeManager.instance.StatusUpdate("Now running neigbouring checks");
                    if (!neigbouringNode.traverable || closedList.Contains(neigbouringNode))
                    {
                        continue;
                    }

                    float newNeighbourCost = currentNode.costG + GetDistance(currentNode, neigbouringNode);

                    if (newNeighbourCost < neigbouringNode.costG || !openList.Contains(neigbouringNode))
                    {
                        neigbouringNode.parent = currentNode;

                        neigbouringNode.costG = newNeighbourCost;
                        neigbouringNode.costH = GetDistance(neigbouringNode, endNode);

                        if (!openList.Contains(neigbouringNode))
                        {
                            openList.Add(neigbouringNode);
                        }
                        else
                        {
                            //openList.UpdateItem(neigbouringNode);
                        }
                    }
                }
            }
            UnityEngine.Debug.LogError("Path Not Found! Couldn't path from: " + startNode.node.spacialInfo + " -> " + endNode.node.spacialInfo);
            return(null);
        }