Exemple #1
0
        private bool HandlePlanning(bool retargetPos, bool retargetGoal)
        {
            /*
             * Design notes:
             *
             * Tries to do a corridor move on the position and/or target.
             * A replan is only triggered if the move(s) fail to reach the desired polygon(s).
             *
             * It is important to note that the replan may fail to reach the goal.  But that is a
             * problem for the AI, not the planner.
             */

            bool needsFullReplan = false;

            // Convenience vars.  Only used for input.  Not updated.
            NavmeshPoint goal = agent.data.plannerGoal;
            NavmeshPoint pos  = agent.data.desiredPosition;

            PathCorridor corridor = agent.corridor;

            if (retargetGoal && retargetPos)
            {
                corridor.Move(pos.point, goal.point);
                retargetGoal = (goal.polyRef != corridor.Target.polyRef ||
                                pos.polyRef != corridor.Position.polyRef);
            }
            else if (retargetPos)
            {
                corridor.MovePosition(pos.point);
                needsFullReplan = (pos.polyRef != corridor.Position.polyRef);
            }
            else if (retargetGoal)
            {
                corridor.MoveTarget(goal.point);
                needsFullReplan = (goal.polyRef != corridor.Target.polyRef);
            }

            if (needsFullReplan)
            {
                // Debug.Log("Full Replan");
                if (agent.PlanCorridor(pos, goal) <= 0)
                {
                    Debug.LogError(agent.transform.name + ": Could not replan corridor.");
                    return(false);
                }
            }
            else if (retargetPos || retargetGoal)
            {
                // Debug.Log("Optimize Only");
                // Any chagnes are likely to be larger than normal.  So force an optimization.
                agent.corridor.OptimizePathTopology(true);
                mOptimizationTimer = OptimizationFrequency;
            }

            agent.data.desiredPosition = agent.corridor.Position;
            agent.data.plannerGoal     = agent.corridor.Target;

            return(true);
        }
Exemple #2
0
        //这个方法是真的移动计划的移动方法
        //根据路线进行移动(注意,这个Agent目标移动数据的修改)
        private bool HandlePlanning(bool retargetPos, bool retargetGoal)
        {
            bool needsFullReplan = false;
            //获取记录下来的这些信息
            NavmeshPoint goal = theAgent.plannerGoal;
            NavmeshPoint pos  = theAgent.desiredPosition;
            //获取路线引用
            PathCorridor corridor = theAgent.corridor;

            if (retargetGoal && retargetPos)
            {
                //此处调用CritterAI的PathCorridor,进而调用PathCorridorEx走recast
                //从当前的位置转移到希望运动到的位置,另外将目标移动到希望移动到的目标
                corridor.Move(pos.point, goal.point);
                retargetGoal = (goal.polyRef != corridor.Target.polyRef || pos.polyRef != corridor.Position.polyRef);
            }
            else if (retargetPos)
            {
                //此处调用CritterAI的PathCorridor,进而调用PathCorridorEx走recast
                //从当前的位置转移到希望运动到的位置
                corridor.MovePosition(pos.point);
                needsFullReplan = (pos.polyRef != corridor.Position.polyRef);
            }
            else if (retargetGoal)
            {
                //此处调用CritterAI的PathCorridor,进而调用PathCorridorEx走recast
                //将目标移动到希望移动到的目标
                corridor.MoveTarget(goal.point);
                needsFullReplan = (goal.polyRef != corridor.Target.polyRef);
            }

            if (needsFullReplan)
            {
                //完全重新计算路径
                if (theAgent.PlanCorridor(pos, goal) <= 0)
                {
                    //Debug.LogError(theAgent.transform.name + ": Could not replan corridor.");
                    SetPathInformation(pos, goal);
                    return(false);
                }
            }
            else if (retargetPos || retargetGoal)
            {
                //CritterAI作者加的强制优化
                theAgent.corridor.OptimizePathTopology(true);
                mOptimizationTimer = OptimizationFrequency;
            }

            //最后重新记录位置就可以了
            theAgent.desiredPosition = theAgent.corridor.Position;
            theAgent.plannerGoal     = theAgent.corridor.Target;


            return(true & SetPathInformation(theAgent.desiredPosition, theAgent.plannerGoal));
        }
        /// <summary>
        /// Finds a path from the start point to the end point and loads it into the corridor.
        /// </summary>
        /// <remarks>
        /// <para>
        /// <b>Warning</b>: The corridor must be available before calling this method.
        /// </para>
        /// <para>
        /// The input points are all expected to be valid. (E.g. polyRef != 0)
        /// </para>
        /// </remarks>
        /// <param name="start">
        /// A valid navigation mesh point representing the start of the path.
        /// </param>
        /// <param name="end">
        /// A valid navigation mesh point representing the end of the path.
        /// </param>
        /// <returns>The length of the path, or -1 on failure.</returns>
        public int PlanCorridor(NavmeshPoint start, NavmeshPoint end)
        {
            // Note: Don't try to re-use the current corridor.  Unlike
            // paths, the corridor is more likely to become malformed
            // over time.

            int pathCount;

            if (start.polyRef == 0 || end.polyRef == 0 || corridor == null)
            {
                return(-1);
            }

            if (start.polyRef == end.polyRef)
            {
                corridor.Reset(start);
                corridor.MoveTarget(end.point);
                data.navStatus = NavStatus.Sucess;
                return(1);
            }
            else
            {
                data.navStatus = navGroup.query.FindPath(start
                                                         , end
                                                         , navGroup.filter
                                                         , agentGroup.pathBuffer
                                                         , out pathCount);
            }

            corridor.Reset(start);

            if (pathCount > 0)
            {
                corridor.SetCorridor(end.point
                                     , agentGroup.pathBuffer
                                     , pathCount);
            }

            return(pathCount);
        }
Exemple #4
0
        //寻找路线:查找从起点到终点的路径,并将其加载到道路中
        public int PlanCorridor(NavmeshPoint start, NavmeshPoint end)
        {
            //原作标识:不要尝试重用corridor,这个东西有更多的可能性变得很畸形

            int pathCount;

            //如果点不可用就会直接失败
            if (start.polyRef == 0 || end.polyRef == 0 || corridor == null)
            {
                return(-1);
            }

            //如果相同点直接结束,navStatus更新
            if (start.polyRef == end.polyRef)
            {
                corridor.Reset(start);
                corridor.MoveTarget(end.point);
                navStatus = NavStatus.Sucess;
                return(1);
            }
            else
            {
                //调用NavmeshQuery的方法进行寻路,然后内部走NavmeshQueryEx类调用dll
                //最后初步猜测调用Detour的DetourNavMeshQuery(有待考证)
                navStatus = navGroup.query.FindPath(start, end, navGroup.filter, agentGroup.pathBuffer, out pathCount);
            }

            corridor.Reset(start);

            if (pathCount > 0)
            {
                corridor.SetCorridor(end.point, agentGroup.pathBuffer, pathCount);
            }

            return(pathCount);
        }
    private void HandleHit(RaycastHit hit)
    {
        if (Input.GetKeyDown(StdButtons.SelectA))
        {
            if (mPathStart.polyRef == 0 || mPathEnd.polyRef == 0)
            {
                NavmeshPoint point = GetNavmeshPoint(hit.point);
                if (point.polyRef == 0)
                {
                    return;
                }

                if (mPathStart.polyRef == 0)
                {
                    mPathStart = point;
                    mCorridor.Reset(mPathStart);
                    return;
                }
                else
                {
                    mPathEnd = point;
                    FindPath();
                    return;
                }
            }
            else if (mPathCount > 0)
            {
                mCorridor.MovePosition(hit.point);
                return;
            }
        }
        else if (mPathCount > 0)
        {
            if (Input.GetKeyDown(StdButtons.SelectB))
            {
                mCorridor.MoveTarget(hit.point);
                return;
            }
            else if (Input.GetKeyDown(StdButtons.SetA))
            {
                NavmeshPoint point = GetNavmeshPoint(hit.point);
                if (point.polyRef != 0)
                {
                    mPathEnd = point;
                    FindPath();
                }
                return;
            }
            else if (Input.GetKeyDown(StdButtons.SetB))
            {
                NavmeshPoint point = GetNavmeshPoint(hit.point);
                if (point.polyRef != 0)
                {
                    mPathStart = point;
                    FindPath();
                }
                return;
            }
            else if (Input.GetKeyDown(StdButtons.SetC))
            {
                NavmeshPoint point = GetNavmeshPoint(hit.point);
                if (point.polyRef != 0)
                {
                    mCorridor.OptimizePathVisibility(point.point, optimizationRange, true);
                    mOptimizeStart = mCorridor.Position.point;
                    mOptimizeEnd   = point.point;
                    mOptimizeTimer = TimerLength;
                }
            }
        }
    }