예제 #1
0
        /// <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);
        }
예제 #2
0
        //只要没有结束就会一直更新
        //这些更新是在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);
            }
        }
예제 #3
0
        /// <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);
        }