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)); }
/// <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); }
//寻找路线:查找从起点到终点的路径,并将其加载到道路中 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; } } } }