//额外辅助的一些方法 public bool IsAtDestiontion() { if (mNavAgent == null) { Debug.Log("NavAgent == null , can not check IsAtDestiontion"); return(true); } return(mNavAgent.IsAtDestination()); }
//只要没有结束就会一直更新 //这些更新是在NavManager里的更新方法进行统一更新的 public override bool Update() { try { //检测位置和目标变化,并约束到导航网格 bool newPos = (theAgent.flags & NavFlag.HasNewPosition) != 0; bool newGoal = (theAgent.flags & NavFlag.HasNewGoal) != 0; NavmeshPoint pt; if (newPos) { //和critterai的dll交互,然后调到recast的dll //获得当前的navmesh上面的点位置 pt = theAgent.GetPointSearch(theAgent.position); //如果点无效就报个错 if (pt.polyRef == 0) { // Debug.LogWarning(string.Format("{0}: Could not constrain position to navigation mesh. Ignoring: {1}", // theAgent.transform.name, pt.ToString())); newPos = false; } else { theAgent.desiredPosition = pt; } } if (newGoal) { //和critterai的dll交互,然后调到recast的dll //获得当前的navmesh上面的点位置 pt = theAgent.GetPointSearch(theAgent.goal); if (pt.polyRef == 0) { // Ignore new goal. // Debug.LogWarning(string.Format("{0}: Could not constrain goal to navigation mesh. Ignoring: {1}" // , theAgent.transform.name, pt.ToString())); newGoal = false; } else { theAgent.plannerGoal = pt; } } theAgent.flags &= ~(NavFlag.HasNewPosition | NavFlag.HasNewGoal); if (newGoal || newPos) { //重新制定移动计划 if (!HandlePlanning(newPos, newGoal)) { return(false); } } //是否需要进行移动的判定 if (theAgent.IsAtDestination()) { //在目标就不用移动了 mSpeed = 0; theAgent.desiredPosition = theAgent.plannerGoal; theAgent.desiredVelocity = Vector3.zero; theAgent.desiredSpeedSq = 0; return(true); } //在这里调整速度(这理由可以非常任性地修改的空间) float maxDelta = theAgent.crowdConfig.maxAcceleration * 0.02f; //float desiredSpeed = theAgent.crowdConfig.maxSpeed; float desiredSpeed = theAgent.moveSpeed; if (Vector3Util.GetDistance2D(theAgent.desiredPosition.point, theAgent.plannerGoal.point) < theAgent.crowdConfig.radius * 3) { //如果已经很贴近目标,就做了个减速,这个还是根据具体需求来搞吧 //这个效果目前还不用,感觉略显魔性 desiredSpeed = Mathf.Max(mSpeed - maxDelta, desiredSpeed * 0.2f); } else { //正常飚速度 desiredSpeed = Mathf.Min(mSpeed + maxDelta, desiredSpeed); } //运行到这里,终于,开始真正正正的移动了 //每个间隔几次,来一次优化 if (--mOptimizationTimer < 1) { theAgent.corridor.OptimizePathTopology(true); mOptimizationTimer = OptimizationFrequency; } //desiredSpeed *= 10;//用于测试速度 Vector3 movePos = Vector3.MoveTowards(theAgent.desiredPosition.point, theAgent.corridor.Corners.verts[0], desiredSpeed * NavManager.threadUpdateTimer); //运行底层的move进行移动(这句话是无比关键的关键) theAgent.corridor.MovePosition(movePos); //获取移动之后的位置 movePos = theAgent.corridor.Position.point; //更新agent的数组记录 theAgent.desiredVelocity = (movePos - theAgent.desiredPosition.point).normalized * desiredSpeed; theAgent.desiredSpeedSq = desiredSpeed * desiredSpeed; theAgent.desiredPosition = theAgent.corridor.Position; mSpeed = desiredSpeed; return(true); } catch (Exception X) { Debug.Log("Error:" + X.ToString()); return(false); } }
public override bool Update() { if (mAtGoalState == StateNormal) { theAgent.SyncCrowdToDesired(); } //这一块的套路和Simple的套路是差不多的 bool newPos = (theAgent.flags & NavFlag.HasNewPosition) != 0; bool newGoal = (theAgent.flags & NavFlag.HasNewGoal) != 0; NavmeshPoint pt; if (newPos) { //和critterai的dll交互,然后调到recast的dll //获得当前的navmesh上面的点位置 pt = theAgent.GetPointSearch(theAgent.position); if (pt.polyRef == 0) { Debug.LogWarning(string.Format( "{0}: Could not constrain new position to the navigation mesh. Ignoring: {1}" , theAgent.transform.name, pt.ToString())); newPos = false; } else { theAgent.desiredPosition = pt; } } if (newGoal) { pt = theAgent.GetPointSearch(theAgent.goal); if (pt.polyRef == 0) { Debug.LogWarning(string.Format( "{0}: Could not constrain new goal to the navigation mesh. Ignoring: {1}" , theAgent.transform.name, pt.ToString())); newGoal = false; } else { theAgent.plannerGoal = pt; } } if (mAtGoalState != StateNormal && newGoal || newPos) { TransitionToNormalGoalState(); } theAgent.flags &= ~(NavFlag.HasNewPosition | NavFlag.HasNewGoal); //如果有新坐标,就走这个feedback,这里与SimpleMove不同 if (newPos) { return(HandlePositionFeedback()); } if (!HandleNormalPlanning(newGoal)) { return(false); } if ((theAgent.flags & NavFlag.CrowdConfigUpdated) != 0) { CrowdAgentParams config = theAgent.crowdConfig; if (mAtGoalState != StateNormal) { config.maxSpeed = 0; } theAgent.crowdAgent.SetConfig(config); theAgent.flags &= ~NavFlag.CrowdConfigUpdated; } if (mAtGoalState == StateInRange) { //手工移动agent到目标 if (theAgent.IsAtDestination()) { //到达目标之后,将自身转化为idle mAtGoalState = StateIdle; theAgent.desiredPosition = theAgent.plannerGoal; theAgent.desiredSpeedSq = 0; theAgent.desiredVelocity = Vector3.zero; } else { Vector3 pos = theAgent.desiredPosition.point; Vector3 goal = theAgent.plannerGoal.point; //手动移动agent到目标 float desiredSpeed = Mathf.Sqrt(theAgent.desiredSpeedSq); theAgent.desiredPosition.point = Vector3.MoveTowards(pos, goal, desiredSpeed * NavManager.threadUpdateTimer); theAgent.desiredPosition.polyRef = 0; theAgent.desiredVelocity = (theAgent.desiredPosition.point - pos).normalized * desiredSpeed; } } return(true); }