예제 #1
0
        //额外辅助的一些方法
        public bool IsAtDestiontion()
        {
            if (mNavAgent == null)
            {
                Debug.Log("NavAgent == null , can not check IsAtDestiontion");
                return(true);
            }

            return(mNavAgent.IsAtDestination());
        }
예제 #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
        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);
        }