Example #1
0
        /// <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);
        }