/// <summary> /// Updates the planner. /// </summary> /// <returns>True on success.</returns> public bool Update() { // Note: Will never return false. Vector3 pos = agent.data.position.point; Vector3 goal = agent.data.goal.point; // Uses a more accurate than normal location check // in order to prevent snapping at the end of movement. if (Vector3Util.SloppyEquals(pos, goal, NavAgent.ExactTolerance)) { mSpeed = 0; agent.data.desiredPosition = agent.data.goal; agent.data.desiredVelocity = Vector3.zero; agent.data.desiredSpeedSq = 0; return(true); } float maxDelta = agent.crowdConfig.maxAcceleration * Time.deltaTime; float desiredSpeed = agent.crowdConfig.maxSpeed; // This test assumes the agent can halt in less than the given number of radii. if (Vector3Util.GetDistance2D(pos, goal) < agent.crowdConfig.radius * 3) { desiredSpeed = Mathf.Max(mSpeed - maxDelta, desiredSpeed * 0.2f); } else { desiredSpeed = Mathf.Min(mSpeed + maxDelta, desiredSpeed); } Vector3 result = Vector3.MoveTowards(pos, goal, desiredSpeed * Time.deltaTime); agent.data.desiredPosition.point = result; agent.data.desiredPosition.polyRef = 0; agent.data.desiredVelocity = (result - pos).normalized * desiredSpeed; agent.data.desiredSpeedSq = desiredSpeed * desiredSpeed; mSpeed = desiredSpeed; return(true); }
//只要没有结束就会一直更新 //这些更新是在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); } }
/// <summary> /// Updates the planner. /// </summary> /// <returns>True on success.</returns> public bool Update() { // Detect position and goal changes, and constrain to navmesh. bool newPos = (agent.data.flags & NavFlag.HasNewPosition) != 0; bool newGoal = (agent.data.flags & NavFlag.HasNewGoal) != 0; NavmeshPoint pt; if (newPos) { pt = agent.GetPointSearch(agent.data.position); if (pt.polyRef == 0) { // Ignore new position. Debug.LogWarning(string.Format( "{0}: Could not constrain position to navigation mesh. Ignoring: {1}" , agent.transform.name, pt.ToString())); newPos = false; } else { agent.data.desiredPosition = pt; } } if (newGoal) { pt = agent.GetPointSearch(agent.data.goal); if (pt.polyRef == 0) { // Ignore new goal. Debug.LogWarning(string.Format( "{0}: Could not constrain goal to navigation mesh. Ignoring: {1}" , agent.transform.name, pt.ToString())); newGoal = false; } else { agent.data.plannerGoal = pt; } } agent.data.flags &= ~(NavFlag.HasNewPosition | NavFlag.HasNewGoal); // Handle planning. if (newGoal || newPos) { // Replanning needed. if (!HandlePlanning(newPos, newGoal)) { // Critical failure. return(false); } } // Is any movement needed? if (Vector3Util.SloppyEquals(agent.data.desiredPosition.point , agent.data.plannerGoal.point , NavAgent.ExactTolerance)) { // At goal. Don't need to do anything. mSpeed = 0; agent.data.desiredPosition = agent.data.plannerGoal; agent.data.desiredVelocity = Vector3.zero; agent.data.desiredSpeedSq = 0; return(true); } // Handle speed adjustments. float maxDelta = agent.crowdConfig.maxAcceleration * Time.deltaTime; float desiredSpeed = agent.crowdConfig.maxSpeed; // This shortcut test assumes the agent can halt in less than the // specified number of radii. if (Vector3Util.GetDistance2D(agent.data.desiredPosition.point , agent.data.plannerGoal.point) < agent.crowdConfig.radius * 3) { // Slow down to as low of 20% of maximum speed. desiredSpeed = Mathf.Max(mSpeed - maxDelta, desiredSpeed * 0.2f); } else { // Speed up to as high as maximum speed. desiredSpeed = Mathf.Min(mSpeed + maxDelta, desiredSpeed); } // Perform the move. if (--mOptimizationTimer < 1) { agent.corridor.OptimizePathTopology(true); mOptimizationTimer = OptimizationFrequency; } Vector3 movePos = Vector3.MoveTowards(agent.data.desiredPosition.point , agent.corridor.Corners.verts[0] , desiredSpeed * Time.deltaTime); agent.corridor.MovePosition(movePos); movePos = agent.corridor.Position.point; agent.data.desiredVelocity = (movePos - agent.data.desiredPosition.point).normalized * desiredSpeed; agent.data.desiredSpeedSq = desiredSpeed * desiredSpeed; agent.data.desiredPosition = agent.corridor.Position; mSpeed = desiredSpeed; return(true); }