示例#1
0
    /// <summary>
    /// Starts pathfinding task from <paramref name="startPos" /> to <paramref name="targetPos" /> asyncronously.
    /// </summary>
    /// <param name="startPos">Coordinate of the start pathfinding point at space.</param>
    /// <param name="targetPos">Coordinate of the target pathfinding point at space.</param>
    /// <param name="pathfindingLvl">Level of the pathfinding graph, which pathfinding will performed on.</param>
    /// <param name="foundPath">Variable, which found path will puted in.</param>
    /// <param name="usingAlg">Algorithm, that must be using for pathfinding.</param>
    /// <param name="failurePathfindingActions">Instructions, that must be invoked in the case, when pathfinding unsucced.</param>
    /// <param name="succesPathfindingActions">Instructions, that must be invoked in the case, when pathfinding succed.</param>
    /// <param name="inThreadOptimization">Is needed to perform finden path optimization?</param>
    /// <param name="inThreadSmoothing">Is needed to perform finden path smoothing?</param>
    public void FindWay(Vector3 startPos, Vector3 targetPos, int pathfindingLvl, List <Vector3> foundPath,
                        PathfindingAlgorithm usingAlg, Action failurePathfindingActions = null, Action succesPathfindingActions = null,
                        bool inThreadOptimization = false, bool inThreadSmoothing = false)
    {
        if (!spaceManagerInstance.isPrimaryProcessingCompleted)
        {
            throw new GraphNotReadyException();
        }
        if (pathfindingLevel >= spaceManagerInstance.gridDetailLevelsCount || pathfindingLevel < 0)
        {
            throw new PathfindingLevelOutOfRangeException();
        }
        PathfindingParamContainer pathfindingData = new PathfindingParamContainer
        {
            start                = startPos,
            target               = targetPos,
            outPath              = foundPath,
            usingAlg             = selectedPFAlg,
            pathfindingLevel     = pathfindingLvl,
            inThreadOptimizePath = inThreadOptimization,
            inThreadSmoothPath   = inThreadSmoothing,
            failureActions       = failurePathfindingActions,
            succesActions        = succesPathfindingActions,
            generateEvents       = true
        };

        ThreadPool.QueueUserWorkItem(PathfindingThreadMethod, pathfindingData);
    }
示例#2
0
    /// <summary>
    /// Internal method.
    /// Performs pathfinding.
    /// (asynchronous execution is assumed)
    /// </summary>
    /// <param name="inpData"></param>
    void PathfindingThreadMethod(object inpData)
    {
        PathfindingParamContainer paramsData = (PathfindingParamContainer)inpData;

        try
        {
            if (paramsData.generateEvents)
            {
                if (!IsAtConstraintsArea(paramsData.target))
                {
                    lock (actionsQueue)
                        actionsQueue.Enqueue(new Action(() =>
                        {
                            curCond = WaitingForRequest;
                            ThrowUniversalEvent("EventPathfindingToOutwardPointRequested");
                        }));
                    return;
                }

                if (!IsAtConstraintsArea(paramsData.start))
                {
                    actionsQueue.Enqueue(new Action(() =>
                    {
                        curCond = WaitingForRequest;
                        ThrowUniversalEvent("EventPathfindingFromOutwardPointRequested");
                    }));

                    return;
                }

                if (SpaceGraph.IsCellOccStaticOnLevel(paramsData.start, 0))
                {
                    actionsQueue.Enqueue(new Action(() =>
                    {
                        curCond = WaitingForRequest;
                        ThrowUniversalEvent("EventPathfindingFromStaticOccupiedCellRequested");
                    }));
                    return;
                }

                if (SpaceGraph.IsCellOccStaticOnLevel(paramsData.target, 0))
                {
                    actionsQueue.Enqueue(new Action(() =>
                    {
                        curCond = WaitingForRequest;
                        ThrowUniversalEvent("EventPathfindingToStaticOccupiedCellRequested");
                    }));
                    return;
                }
            }

            List <Vector3> foundPath;
            // поиск пути, результат кладется в переменную foundPath
            if (paramsData.usingAlg == PathfindingAlgorithm.AStar)
            {
                Graph graph = new Graph(spaceManagerInstance, cTSInstance.Token, paramsData.start, paramsData.target,
                                        paramsData.pathfindingLevel,
                                        new SpaceConstraints {
                    xMin = xMin, xMax = xMax, yMin = yMin, yMax = yMax, zMin = zMin, zMax = zMax
                },
                                        heuristicFactor
                                        );
                foundPath = graph.GetWay();
            }
            else
            {
                WaveTrace waveTraceInst =
                    new WaveTrace(
                        new SpaceConstraints
                {
                    xMin = xMin,
                    xMax = xMax,
                    yMin = yMin,
                    yMax = yMax,
                    zMin = zMin,
                    zMax = zMax
                }, cTSInstance.Token, paramsData.start, paramsData.target);
                waves     = waveTraceInst.waves;
                foundPath = waveTraceInst.GetWay();
            }

            if (foundPath == null)
            {
                lock (actionsQueue) actionsQueue.Enqueue(paramsData.failureActions);
                return;
            }

            if (paramsData.inThreadOptimizePath)
            {
                foundPath = PathHandler.PathFancification(foundPath, paramsData.pathfindingLevel);
                foundPath = PathHandler.PathOptimization(foundPath, paramsData.pathfindingLevel);
            }

            if (paramsData.inThreadSmoothPath)
            {
                foundPath = PathHandler.PathSmoothing(foundPath, paramsData.pathfindingLevel);
            }
            if (paramsData.inThreadOptimizePath || paramsData.inThreadSmoothPath)
            {
                totalLength = 0;
                for (int i = 0; i < foundPath.Count - 1; i++)
                {
                    totalLength += Vector3.Distance(foundPath[i], foundPath[i + 1]);
                }
            }

            lock (paramsData.outPath)
            {
                paramsData.outPath.Clear();
                paramsData.outPath.AddRange(foundPath);
            }

            lock (actionsQueue) actionsQueue.Enqueue(paramsData.succesActions);
        }
        catch (Exception ex)
        {
            UnityEngine.Debug.Log(ex.Message);
        }
    }