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); }
//这个方法是真的移动计划的移动方法 //根据路线进行移动(注意,这个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)); }
//回收这个通道(目前都是在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); }
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); }
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); }
//从池子里面获取通道,如果没有就需要建立一个(目前都是在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)); }
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); } }
//设置道路资源,目前来看是一个必要的过程 //主要是为了操作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; } }
/// <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; } }
/// <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); }