public void PulsePoint(int index)
 {
     if (AStarHelper.Invalid(sources[index]))
     {
         return;
     }
     DrawHelper.DrawCube(sources[index].Position, Vector3.one * 2.0f, pulseColor);
 }
        static int Closest(List <PathNode> inNodes, Vector3 toPoint)
        {
            int   closestIndex = 0;
            float minDist      = float.MaxValue;

            for (int i = 0; i < inNodes.Count; i++)
            {
                if (AStarHelper.Invalid(inNodes[i]))
                {
                    continue;
                }
                float thisDist = Vector3.Distance(toPoint, inNodes[i].Position);
                if (thisDist > minDist)
                {
                    continue;
                }

                minDist      = thisDist;
                closestIndex = i;
            }

            return(closestIndex);
        }
        // Calculate the A* path
        public static List <T> Calculate <T>(T start, T goal) where T : IPathNode <T>
        {
            List <T> closedset = new List <T>();    // The set of nodes already evaluated.
            List <T> openset   = new List <T>();    // The set of tentative nodes to be evaluated.

            openset.Add(start);
            Dictionary <T, T> came_from = new Dictionary <T, T>();      // The map of navigated nodes.

            Dictionary <T, float> g_score = new Dictionary <T, float>();

            g_score[start] = 0.0f;     // Cost from start along best known path.

            Dictionary <T, float> h_score = new Dictionary <T, float>();

            h_score[start] = HeuristicCostEstimate(start, goal);

            Dictionary <T, float> f_score = new Dictionary <T, float>();

            f_score[start] = h_score[start];     // Estimated total cost from start to goal through y.

            while (openset.Count != 0)
            {
                T x = LowestScore(openset, f_score);
                if (x.Equals(goal))
                {
                    List <T> result = new List <T>();
                    ReconstructPath(came_from, x, ref result);
                    return(result);
                }
                openset.Remove(x);
                closedset.Add(x);
                foreach (T y in x.Connections)
                {
                    if (AStarHelper.Invalid(y) || closedset.Contains(y))
                    {
                        continue;
                    }
                    float tentative_g_score = g_score[x] + Distance(x, y);

                    bool tentative_is_better = false;
                    if (!openset.Contains(y))
                    {
                        openset.Add(y);
                        tentative_is_better = true;
                    }
                    else if (tentative_g_score < g_score[y])
                    {
                        tentative_is_better = true;
                    }

                    if (tentative_is_better)
                    {
                        came_from[y] = x;
                        g_score[y]   = tentative_g_score;
                        h_score[y]   = HeuristicCostEstimate(y, goal);
                        f_score[y]   = g_score[y] + h_score[y];
                    }
                }
            }

            return(null);
        }
        public void Update()
        {
            if (reset)
            {
                donePath = false;
                ArrayFunc.Clear(ref solvedPath);
                reset = false;
            }

            if (start == null || end == null)
            {
                Debug.LogWarning("Need 'start' and or 'end' defined!");
                enabled = false;
                return;
            }

            startIndex = Closest(sources, start.transform.position);

            endIndex = Closest(sources, end.transform.position);


            if (startIndex != lastStartIndex || endIndex != lastEndIndex)
            {
                reset          = true;
                lastStartIndex = startIndex;
                lastEndIndex   = endIndex;
                return;
            }

            for (int i = 0; i < sources.Count; i++)
            {
                if (AStarHelper.Invalid(sources[i]))
                {
                    continue;
                }
                sources[i].nodeColor = nodeColor;
            }

            PulsePoint(lastStartIndex);
            PulsePoint(lastEndIndex);


            if (!donePath)
            {
                solvedPath = AStarHelper.Calculate(sources[lastStartIndex], sources[lastEndIndex]);

                donePath = true;
            }

            // Invalid path
            if (solvedPath == null || solvedPath.Count < 1)
            {
                Debug.LogWarning("Invalid path!");
                reset   = true;
                enabled = false;
                return;
            }


            //Draw path
            for (int i = 0; i < solvedPath.Count - 1; i++)
            {
                if (AStarHelper.Invalid(solvedPath[i]) || AStarHelper.Invalid(solvedPath[i + 1]))
                {
                    reset = true;

                    return;
                }
                Debug.DrawLine(solvedPath[i].Position, solvedPath[i + 1].Position, Color.cyan * new Color(1.0f, 1.0f, 1.0f, 0.5f));
            }
        }
        public static List <PathNode> CreateGrid(Vector3 center, Vector3 spacing, int[] dim, float randomSpace)
        {
            GameObject groupObject = new GameObject("grid");

            Random.seed = 1337;
            int   xCount = dim[0];
            int   yCount = dim[1];
            float xWidth = spacing.x * xCount;
            float yWidth = spacing.z * yCount;

            float xStart = center.x - (xWidth / 2.0f) + (spacing.x / 2.0f);
            float yStart = center.z - (yWidth / 2.0f) + (spacing.z / 2.0f);

            List <PathNode> result = new List <PathNode>();

            for (int x = 0; x < xCount; x++)
            {
                float xPos = (x * spacing.x) + xStart;

                for (int y = 0; y < yCount; y++)
                {
                    if (randomSpace > 0.0f)
                    {
                        if (Random.value <= randomSpace)
                        {
                            result.Add(null);
                            continue;
                        }
                    }
                    float    yPos    = (y * spacing.z) + yStart;
                    PathNode newNode = Spawn(new Vector3(xPos, 0.0f, yPos));

                    result.Add(newNode);
                    newNode.transform.parent = groupObject.transform;
                }
            }

            for (int x = 0; x < xCount; x++)
            {
                for (int y = 0; y < yCount; y++)
                {
                    int        thisIndex         = (x * yCount) + y;
                    List <int> connectedIndicies = new List <int>();
                    PathNode   thisNode          = result[thisIndex];
                    if (AStarHelper.Invalid(thisNode))
                    {
                        continue;
                    }
                    if (x != 0)
                    {
                        connectedIndicies.Add(((x - 1) * yCount) + y);
                    }
                    if (x != xCount - 1)
                    {
                        connectedIndicies.Add(((x + 1) * yCount) + y);
                    }
                    if (y != 0)
                    {
                        connectedIndicies.Add((x * yCount) + (y - 1));
                    }
                    if (y != yCount - 1)
                    {
                        connectedIndicies.Add((x * yCount) + (y + 1));
                    }

                    if (x != 0 && y != 0)
                    {
                        connectedIndicies.Add(((x - 1) * yCount) + (y - 1));
                    }

                    if (x != xCount - 1 && y != yCount - 1)
                    {
                        connectedIndicies.Add(((x + 1) * yCount) + (y + 1));
                    }

                    if (x != 0 && y != yCount - 1)
                    {
                        connectedIndicies.Add(((x - 1) * yCount) + (y + 1));
                    }

                    if (x != xCount - 1 && y != 0)
                    {
                        connectedIndicies.Add(((x + 1) * yCount) + (y - 1));
                    }

                    for (int i = 0; i < connectedIndicies.Count; i++)
                    {
                        PathNode thisConnection = result[connectedIndicies[i]];
                        if (AStarHelper.Invalid(thisConnection))
                        {
                            continue;
                        }
                        thisNode.Connections.Add(thisConnection);
                    }
                }
            }

            return(result);
        }