Exemple #1
0
        protected override IEnumerator <float> OnFollowPathCoroutine()
        {
            IsMovingFlag = false;
            //是否为第一段移动
            bool isFirstMoved = false;
            //当前已经走过的路段
            float distanceAlongSegment = 0;
            //当前路段长度
            var segmentLength = 0.0f;
            //节点的大小
            float nodeSize = AStarMgr.Ins.data.gridGraph.nodeSize;
            //最大可以移动的距离
            float maxMoveDistance = nodeSize * MaxMovePoint;
            //已经移动的距离
            float movedDistance = 0;
            var   moveStep      = Time.smoothDeltaTime * RealMoveSpeed;

            IsForceBreak   = false;
            IsFinalPosMove = false;
            for (int i = 0; i < ABPath.vectorPath.Count - 1; i++)
            {
                CurIndex = i;
                var p1 = ABPath.vectorPath[i];
                var p2 = ABPath.vectorPath[i + 1];
                segmentLength = Vector3.Distance(p1, p2);
                if (CurMovePoint <= segmentLength)
                {
                    p2 = (Vector3)AStarMgr.GetSafeNode(p2).position;;
                }
                while (IsHaveMoveSegment() && !IsForceBreak)
                {
                    if (CurMovePoint < nodeSize &&
                        MathUtil.Approximately(SelfBaseUnit.Pos, p2))
                    {
                        IsForceBreak = true;
                    }
                    else
                    {
                        LerpMove(p1, p2, 1, true, false);
                    }

                    yield return(Timing.WaitForOneFrame);

                    if (!isFirstMoved)
                    {
                        isFirstMoved = true;
                        Callback_OnFirstMovingAlone?.Invoke();
                    }
                }

                distanceAlongSegment -= segmentLength;
                OnMoveStep(movedDistance, maxMoveDistance, nodeSize, segmentLength);
                CurIndex++;
                if (!IsCanMove || IsForceBreak)
                {
                    break;
                }
            }

            //计算最后的安全落点
            yield return(Timing.WaitUntilDone(FinalPosMove()));

            if (CurMovePoint < 1)
            {
                CurMovePoint = 0;
            }
            IsMovingFlag = true;
            Callback_OnMoveDestination?.Invoke();
            StopPath();

            //最后位置点的矫正
            IEnumerator <float> FinalPosMove()
            {
                IsFinalPosMove = true;
                Vector3 startPos = SelfBaseUnit.Pos;
                var     finalPos = GetFinalPos(startPos);

                if (MathUtil.Approximately(startPos, finalPos))
                {
                    yield break;
                }
                //将单位移动到最终的目标节点
                distanceAlongSegment = 0;
                segmentLength        = Vector3.Distance(startPos, finalPos);
                while (IsHaveMoveSegment())
                {
                    LerpMove(startPos, finalPos, 1, segmentLength > nodeSize, true);
                    yield return(Timing.WaitForOneFrame);
                }
                SelfBaseUnit.Pos = finalPos;

                //如果目标无效,进入递归
                if (!MathUtil.Approximately(finalPos, GetFinalPos(SelfBaseUnit.Pos)))
                {
                    yield return(Timing.WaitUntilDone(FinalPosMove()));
                }
                IsForceBreak   = false;
                IsFinalPosMove = false;
            }

            bool LerpMove(Vector3 p1, Vector3 p2, float speedMul = 1.0f, bool isRot = true, bool isFinalCorrect = false)
            {
                float aiSpeedMul = 1;

                if (BaseGlobal.FOWMgr != null &&
                    BaseGlobal.FOWMgr.IsInFog(p2) &&
                    SelfBaseUnit != null &&
                    SelfBaseUnit.IsAI() &&
                    SelfBaseUnit.FOWMgr != null &&
                    !SelfBaseUnit.FOWMgr.IsVisible &&
                    !SelfBaseUnit.FOWMgr.IsPreVisible)
                {
                    aiSpeedMul = 10;
                }
                if (!isFinalCorrect && IsForceBreak)
                {
                    return(false);
                }
                var tempMoveStep      = moveStep * speedMul * aiSpeedMul;
                var interpolatedPoint = Vector3.Lerp(p1, p2, distanceAlongSegment / segmentLength);
                var targetRot         = Quaternion.LookRotation((p2 - p1).SetY(0), Vector3.up);

                if (isRot)
                {
                    SelfBaseUnit.Rot = Quaternion.Slerp(SelfBaseUnit.Rot, targetRot, tempMoveStep);
                }
                bool isValid = OnPreLerpMoveAlone(interpolatedPoint, tempMoveStep, movedDistance, maxMoveDistance, nodeSize, segmentLength, isFinalCorrect);

                if (!isValid)
                {
                    return(false);
                }
                SelfBaseUnit.Pos      = interpolatedPoint;
                movedDistance        += tempMoveStep;
                distanceAlongSegment += tempMoveStep;
                OnLerpMoveAlone(tempMoveStep, movedDistance, maxMoveDistance, nodeSize, segmentLength, isFinalCorrect);
                Callback_OnMovingAlone?.Invoke();
                return(true);
            }

            //是否有移动的路段
            bool IsHaveMoveSegment()
            {
                return(distanceAlongSegment < segmentLength);
            }
        }
Exemple #2
0
        protected override void OnFollowPathUpdate()
        {
            if (ABPath == null)
            {
                return;
            }
            if (!IsMovingFlag)
            {
                return;
            }

            if (currentWaypoint >= ABPath.vectorPath.Count)
            {
                return;
            }

            reachedEndOfPath   = false;
            distanceToWaypoint = 0;
            while (true)
            {
                if (currentWaypoint >= ABPath.vectorPath.Count)
                {
                    break;
                }

                distanceToWaypoint = Vector3.Distance(SelfBaseUnit.Pos, ABPath.vectorPath[currentWaypoint]);
                if (distanceToWaypoint < NextWaypointDistance)
                {
                    if (currentWaypoint + 1 < ABPath.vectorPath.Count)
                    {
                        currentWaypoint++;
                    }
                    else
                    {
                        reachedEndOfPath = true;
                        break;
                    }
                }
                else
                {
                    break;
                }
            }

            if (MathUtil.Approximately(SelfBaseUnit.Pos, Destination, 0.01f))
            {
                IsMovingFlag     = false;
                SelfBaseUnit.Pos = Destination;
                StopPath();
                Callback_OnMoveDestination?.Invoke();
            }
            else
            {
                if (currentWaypoint >= ABPath.vectorPath.Count)
                {
                    return;
                }

                speedFaction = reachedEndOfPath ? Mathf.Sqrt(distanceToWaypoint / NextWaypointDistance) : 1f;
                Vector3 dir      = (ABPath.vectorPath[currentWaypoint] - SelfBaseUnit.Pos).normalized;
                Vector3 velocity = dir * RealMoveSpeed * speedFaction;
                SelfBaseUnit.Pos += velocity * Time.deltaTime;
                SelfBaseUnit.Rot  = Quaternion.Slerp(SelfBaseUnit.Rot, Quaternion.LookRotation(dir.SetY(0), Vector3.up), Time.smoothDeltaTime * RealMoveSpeed * 3.0f);
                IsMovingFlag      = true;
            }
        }