Esempio n. 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);
        }
Esempio n. 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));
        }
Esempio n. 3
0
        //回收这个通道(目前都是在NavAgent里面处理的)
        public void ReturnCorridor(PathCorridor corridor)
        {
            if (mCorridors.Count >= mMaxCorridors || corridor == null || corridor.IsDisposed ||
                corridor.MaxPathSize != mMaxPathSize ||
                corridor.MaxCorners != mMaxStraightPathSize)
            {
                return;
            }

            PathCorridor.ReleaseLocals(corridor);
            mCorridors.Push(corridor);
        }
Esempio n. 4
0
        public Pathfinder(Navmesh navMesh)
        {
            _navMesh = navMesh;
            _filter  = new NavmeshQueryFilter();

            if (NavUtil.Failed(NavmeshQuery.Create(_navMesh, 1000, out _query)))
            {
                throw new Exception("NavQuery failed");
            }

            _pathCorridor = new PathCorridor(1000, 1000, _query, _filter);
        }
Esempio n. 5
0
        public static PathCorridor CreateAgent(int maxPathSize = 10, int maxCorners = 10, NavmeshQueryFilter filter = null)
        {
            if (m_Map == null)
            {
                return(null);
            }
            if (filter == null)
            {
                filter = m_Map.DefaultQueryFilter;
            }
            PathCorridor ret = new PathCorridor(maxPathSize, maxCorners, m_Map.Query, filter);

            return(ret);
        }
Esempio n. 6
0
        //从池子里面获取通道,如果没有就需要建立一个(目前都是在NavAgent里面处理的)
        public PathCorridor GetCorridor(NavmeshPoint position, NavmeshQuery query, NavmeshQueryFilter filter)
        {
            if (mCorridors.Count > 0)
            {
                PathCorridor corr = mCorridors.Pop();

                if (PathCorridor.LoadLocals(corr, position, query, filter))
                {
                    return(corr);
                }

                return(null);
            }
            return(new PathCorridor(mMaxPathSize, mMaxStraightPathSize, query, filter));
        }
Esempio n. 7
0
    private void HandlePathBufferResize()
    {
        mCorridor = new PathCorridor(
            mPath.MaxElementCount, mCornerPolys.MaxElementCount, mGroup.query, mGroup.filter);

        mCorridorData = new PathCorridorData(mPath.MaxElementCount);

        if (mPathEnd.polyRef != 0)
        {
            FindPath();
        }
        else if (mPathStart.polyRef != 0)
        {
            mCorridor.Reset(mPathStart);
        }
    }
Esempio n. 8
0
 //设置道路资源,目前来看是一个必要的过程
 //主要是为了操作group
 public void SetCorridorAssets(bool enabled)
 {
     if (enabled)
     {
         if (corridor == null)
         {
             corridor = agentGroup.GetCorridor(position, navGroup.query, navGroup.filter);
         }
         flags |= NavFlag.CorridorInUse;
     }
     else
     {
         agentGroup.ReturnCorridor(corridor);
         corridor = null;
         flags   &= ~NavFlag.CorridorInUse;
     }
 }
Esempio n. 9
0
 /// <summary>
 /// Sets up the corridor assets.
 /// </summary>
 /// <remarks>
 /// <para>
 /// Notes: Resets the corridor to the current navigation position.  So the position
 /// should be valid before getting the corridor.
 /// </para>
 /// <ul>
 /// <li>This operation sets/unsets the corridor in-use flag as appropriate.</li>
 /// <li>Re-uses existing assests as appropriate.</li>
 /// <li>Utilizes the agent group pool.</li>
 /// </ul>
 /// </remarks>
 /// <param name="enabled">
 /// True if the corridor assets should be made ready to use.  False to release all corridor 
 /// assets.
 /// </param>
 public void SetCorridorAssets(bool enabled)
 {
     if (enabled)
     {
         if (corridor == null)
         {
             corridor = 
                 agentGroup.GetCorridor(data.position, navGroup.query, navGroup.filter);
         }
         data.flags |= NavFlag.CorridorInUse;
     }
     else
     {
         agentGroup.ReturnCorridor(corridor);
         corridor = null;
         data.flags &= ~NavFlag.CorridorInUse;
     }
 }
Esempio n. 10
0
        /// <summary>
        /// Returns a corridor to the pool. (If there is room.)
        /// </summary>
        /// <remarks>
        /// <para>
        /// Invalid corridors are rejected. (E.g. Disposed or the wrong size.)
        /// </para>
        /// </remarks>
        /// <param name="corridor">The corridor to add to the pool.</param>
        public void ReturnCorridor(PathCorridor corridor)
        {
            if (mCorridors.Count >= mMaxCorridors || corridor == null || corridor.IsDisposed
                || corridor.MaxPathSize != mMaxPathSize
                || corridor.MaxCorners != mMaxStraightPathSize)
            {
                return;
            }

            PathCorridor.ReleaseLocals(corridor);
            mCorridors.Push(corridor);
        }