/// <summary> /// Update the planner. /// </summary> /// <returns>True if successful.</returns> public bool Update() { if (mAtGoalState == StateNormal) { agent.SyncCrowdToDesired(); } 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 new position to the 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 new goal to the navigation mesh. Ignoring: {1}" , agent.transform.name, pt.ToString())); newGoal = false; } else { agent.data.plannerGoal = pt; } } if (mAtGoalState != StateNormal && newGoal || newPos) { TransitionToNormalGoalState(); } agent.data.flags &= ~(NavFlag.HasNewPosition | NavFlag.HasNewGoal); if (newPos) { // Note: This call inherently handles everything, not just the // position change. return(HandlePositionFeedback()); } if (!HandleNormalPlanning(newGoal)) { // A critical failure has occurred. return(false); } if ((agent.data.flags & NavFlag.CrowdConfigUpdated) != 0) { CrowdAgentParams config = agent.crowdConfig; if (mAtGoalState != StateNormal) { config.maxSpeed = 0; } agent.crowdAgent.SetConfig(config); agent.data.flags &= ~NavFlag.CrowdConfigUpdated; } if (mAtGoalState == StateInRange) { // Need to manually move the agent to the goal. Vector3 pos = agent.data.desiredPosition.point; Vector3 goal = agent.data.plannerGoal.point; if (Vector2Util.SloppyEquals( new Vector2(pos.x, pos.z), new Vector2(goal.x, goal.z), 0.005f)) { // Snap to the goal and, essentially, go into an idle // state. mAtGoalState = StateIdle; agent.data.desiredPosition = agent.data.plannerGoal; agent.data.desiredSpeedSq = 0; agent.data.desiredVelocity = Vector3.zero; // Debug.Log("Reached goal. Going idle."); } else { // Need to manually move the agent to the goal. // Assumptions: The distance is short, and the crowd has // already slowed the agent's speed to a minimal value. float desiredSpeed = Mathf.Sqrt(agent.data.desiredSpeedSq); agent.data.desiredPosition.point = Vector3.MoveTowards(pos, goal, desiredSpeed * Time.deltaTime); // While the point will be on the mesh surface, we // can't assume we are already in the goal's polygon. agent.data.desiredPosition.polyRef = 0; agent.data.desiredVelocity = (agent.data.desiredPosition.point - pos).normalized * desiredSpeed; } } return(true); }
/// <summary> /// Update the planner. /// </summary> /// <returns>True if the update completed successfully.</returns> public bool Update() { agent.SyncCrowdToDesired(); // Constrain the goal to the navigation mesh. NavmeshPoint ngoal = agent.GetPointSearch(agent.data.goal); if (ngoal.polyRef == 0) { Debug.LogWarning(string.Format( "{0}: Failed constrain goal to navmesh: Ignoring: {1}" , agent.transform.name, ngoal.ToString())); // Leave the flag alone. It will be handled later. ngoal = agent.data.plannerGoal; // Revert to last good. } agent.data.plannerGoal = ngoal; // Handle a full planner reset if the agent position has changed. if ((agent.data.flags & NavFlag.HasNewPosition) != 0) { NavmeshPoint pt = agent.GetPointSearch(agent.data.position); if (pt.polyRef == 0) { // Ignore the new position. Debug.LogWarning(string.Format( "{0}: Failed constrain pos to navmesh: Ignoring: {1}" , agent.transform.name, agent.data.position.ToString())); agent.data.flags &= ~NavFlag.HasNewPosition; } else { // Assume large change in position. So force a full reset of planning. // Note: Ignoring failure of add since it can only occur from invalid crowd // manager use cases. agent.AddToCrowd(pt.point); agent.crowdAgent.RequestMoveTarget(ngoal); agent.data.flags &= ~(NavFlag.HasNewPosition | NavFlag.HasNewGoal); agent.data.desiredPosition = pt; //Debug.Log(string.Format( // "{0}: Reset planning. New position." // , agent.transform.name)); return(true); } } // Feed the goal to the crowd manager. if ((agent.data.flags & NavFlag.HasNewGoal) != 0) { agent.crowdAgent.RequestMoveTarget(ngoal); agent.data.flags &= ~NavFlag.HasNewGoal; //Debug.Log(string.Format("{0}: Reset crowd goal." // , agent.transform.name)); } else { agent.crowdAgent.AdjustMoveTarget(ngoal); } // Handle posting configation changes to the crowd. if ((agent.data.flags & NavFlag.CrowdConfigUpdated) != 0) { agent.crowdAgent.SetConfig(agent.crowdConfig); agent.data.flags &= ~NavFlag.CrowdConfigUpdated; } return(true); }