コード例 #1
0
 public static void ComputePath(MovementController movingElement, Vector2Int goal, PathReadyFunc onComplete)
 {
     movingElement.StartCoroutine(ComputePathAsync(movingElement, goal, onComplete));
 }
コード例 #2
0
    private static IEnumerator ComputePathAsync(MovementController movingElement, Vector2Int goal, PathReadyFunc onComplete)
    {
        Vector2Int start = movingElement.gridElement.position;

        Vector2Int?closestGoal = FindClosestToGoal(goal);

        if (closestGoal.HasValue)
        {
            goal = closestGoal.Value;
        }
        else
        {
            onComplete.Invoke(null);
            yield break;
        }

        List <Vector2Int> openSet = new List <Vector2Int> {
            start
        };

        Dictionary <Vector2Int, Vector2Int> cameFrom = new Dictionary <Vector2Int, Vector2Int>();

        Dictionary <Vector2Int, float> gScore = new Dictionary <Vector2Int, float> {
            [start] = 0
        };

        Dictionary <Vector2Int, float> fScore = new Dictionary <Vector2Int, float> {
            [start] = H(start, goal)
        };

        float lastFrameTime = Time.realtimeSinceStartup;

        while (openSet.Count > 0)
        {
            Vector2Int current = openSet[0];
            foreach (Vector2Int i in openSet)
            {
                if (fScore[i] < fScore[current])
                {
                    current = i;
                }
            }

            if (current == goal)
            {
                onComplete.Invoke(ReconstructPath(cameFrom, current));
                yield break;
            }

            openSet.Remove(current);

            foreach (Vector2Int neighbor in AvailableNeighbors(movingElement, current))
            {
                if (!gScore.ContainsKey(neighbor))
                {
                    gScore[neighbor] = Mathf.Infinity;
                }
                float tentativeScore = gScore[current] + Vector2Int.Distance(current, neighbor);
                if (tentativeScore < gScore[neighbor])
                {
                    cameFrom[neighbor] = current;
                    gScore[neighbor]   = tentativeScore;
                    fScore[neighbor]   = gScore[neighbor] + H(neighbor, goal);
                    if (!openSet.Contains(neighbor))
                    {
                        openSet.Add(neighbor);
                    }
                }
            }

            float frameRate = Application.targetFrameRate == -1 ? 60.0f : Application.targetFrameRate;
            if (Time.realtimeSinceStartup - lastFrameTime >= 1 / frameRate)
            {
                lastFrameTime = Time.realtimeSinceStartup;
                yield return(null);
            }
        }

        onComplete.Invoke(null);
    }