protected virtual void SetLaneChange()
    {
        if (currentMapLane == null) // Prevent null if despawned during wait
        {
            return;
        }

        ApiManager.Instance?.AddLaneChange(gameObject);

        if (currentMapLane.leftLaneForward != null)
        {
            if (!isFrontLeftDetect)
            {
                currentMapLane       = currentMapLane.leftLaneForward;
                laneSpeedLimit       = currentMapLane.speedLimit;
                aggressionAdjustRate = laneSpeedLimit / 11.176f; // 11.176 m/s corresponds to 25 mph
                SetChangeLaneData(currentMapLane.mapWorldPositions);
                controller.Coroutines.Add(FixedUpdateManager.StartCoroutine(DelayOffTurnSignals()));
            }
        }
        else if (currentMapLane.rightLaneForward != null)
        {
            if (!isFrontRightDetect)
            {
                currentMapLane       = currentMapLane.rightLaneForward;
                laneSpeedLimit       = currentMapLane.speedLimit;
                aggressionAdjustRate = laneSpeedLimit / 11.176f; // 11.176 m/s corresponds to 25 mph
                SetChangeLaneData(currentMapLane.mapWorldPositions);
                controller.Coroutines.Add(FixedUpdateManager.StartCoroutine(DelayOffTurnSignals()));
            }
        }
    }
 public void ForceLaneChange(bool isLeft)
 {
     if (isLeft)
     {
         if (currentMapLane.leftLaneForward != null)
         {
             if (!isFrontLeftDetect)
             {
                 currentMapLane       = currentMapLane.leftLaneForward;
                 laneSpeedLimit       = currentMapLane.speedLimit;
                 aggressionAdjustRate = laneSpeedLimit / 11.176f; // 11.176 m/s corresponds to 25 mph
                 SetChangeLaneData(currentMapLane.mapWorldPositions);
                 controller.Coroutines.Add(FixedUpdateManager.StartCoroutine(DelayOffTurnSignals()));
                 ApiManager.Instance?.AddLaneChange(gameObject);
             }
         }
     }
     else
     {
         if (currentMapLane.rightLaneForward != null)
         {
             if (!isFrontRightDetect)
             {
                 currentMapLane       = currentMapLane.rightLaneForward;
                 laneSpeedLimit       = currentMapLane.speedLimit;
                 aggressionAdjustRate = laneSpeedLimit / 11.176f; // 11.176 m/s corresponds to 25 mph
                 SetChangeLaneData(currentMapLane.mapWorldPositions);
                 controller.Coroutines.Add(FixedUpdateManager.StartCoroutine(DelayOffTurnSignals()));
                 ApiManager.Instance?.AddLaneChange(gameObject);
             }
         }
     }
 }
Example #3
0
    protected void GetDodge()
    {
        if (currentMapLane == null)
        {
            return;
        }
        if (isDodge)
        {
            return;
        }
        if (IsYieldToIntersectionLane())
        {
            return;
        }

        if (isLeftDetectWithinStopDistance || isRightDetectWithinStopDistance)
        {
            var npcC = isLeftDetectWithinStopDistance ? leftClosestHitInfo.collider.GetComponentInParent <NPCLaneFollowBehaviour>() : rightClosestHitInfo.collider.GetComponentInParent <NPCLaneFollowBehaviour>();
            var aC   = isLeftDetectWithinStopDistance ? leftClosestHitInfo.collider.transform.root.GetComponent <AgentController>() : rightClosestHitInfo.collider.transform.root.GetComponent <AgentController>();

            if (currentMapLane.isTrafficLane)
            {
                if (npcC != null)
                {
                    isFrontDetectWithinStopDistance = true;
                    frontClosestHitInfo             = isLeftDetectWithinStopDistance ? leftClosestHitInfo : rightClosestHitInfo;
                }
                else if (aC != null)
                {
                    isFrontDetectWithinStopDistance = true;
                    frontClosestHitInfo             = isLeftDetectWithinStopDistance ? leftClosestHitInfo : rightClosestHitInfo;
                    if (!isWaitingToDodge)
                    {
                        controller.Coroutines.Add(FixedUpdateManager.StartCoroutine(WaitToDodge(aC, isLeftDetectWithinStopDistance)));
                    }
                }
                else
                {
                    if (leftClosestHitInfo.collider?.gameObject?.GetComponentInParent <NPCController>() == null && leftClosestHitInfo.collider?.transform.root.GetComponent <AgentController>() == null)
                    {
                        SetDodge(!isLeftDetectWithinStopDistance);
                    }
                }
            }
            else // intersection lane
            {
                if (npcC != null)
                {
                    if ((isLeftTurn && npcC.isLeftTurn || isRightTurn && npcC.isRightTurn) && Vector3.Dot(transform.TransformDirection(Vector3.forward), npcC.transform.TransformDirection(Vector3.forward)) < -0.7f)
                    {
                        if (currentIndex > 1)
                        {
                            SetDodge(isLeftTurn, true);
                        }
                    }
                }
            }
        }
    }
 public override void PhysicsUpdate()
 {
     if (WaypointState == WaypointWalkState.Walk)
     {
         if (MoveCoroutine != null)
         {
             return;
         }
         MoveCoroutine = FixedUpdateManager.StartCoroutine(PedestrianMoveIE());
     }
 }
Example #5
0
 public override void PhysicsUpdate()
 {
     //controller.SetBrakeLights(currentSpeed < 2.0f); // TODO
     if (WaypointState == WaypointDriveState.Drive)
     {
         if (MoveCoroutine != null)
         {
             return;
         }
         MoveCoroutine = FixedUpdateManager.StartCoroutine(NPCMoveIE());
     }
 }
    private void EvaluateSidewalk()
    {
        if (IsRandomIdle())
        {
            controller.Coroutines[(int)PedestrianController.CoroutineID.ChangePedState] =
                FixedUpdateManager.StartCoroutine(controller.ChangePedState());
        }

        if (controller.ThisPedState == PedestrianController.PedestrianState.Walking)
        {
            EvaluateNextTarget();
        }
    }
 void StartStoppingCoroutine()
 {
     if (currentMapLane?.stopLine != null) // check if stopline is connected to current path
     {
         controller.currentIntersection = currentMapLane.stopLine?.intersection;
         stopTarget  = currentMapLane.mapWorldPositions[currentMapLane.mapWorldPositions.Count - 1];
         prevMapLane = currentMapLane;
         if (prevMapLane.stopLine.intersection != null) // null if map not setup right TODO add check to report missing stopline
         {
             if (prevMapLane.stopLine.isStopSign)       // stop sign
             {
                 controller.Coroutines.Add(FixedUpdateManager.StartCoroutine(WaitStopSign()));
             }
             else
             {
                 controller.Coroutines.Add(FixedUpdateManager.StartCoroutine(WaitTrafficLight()));
             }
         }
     }
 }
Example #8
0
    protected void EvaluateTarget()
    {
        distanceToCurrentTarget = Vector3.Distance(new Vector3(controller.frontCenter.position.x, 0f, controller.frontCenter.position.z), new Vector3(currentTarget.x, 0f, currentTarget.z));
        distanceToStopTarget    = Vector3.Distance(new Vector3(controller.frontCenter.position.x, 0f, controller.frontCenter.position.z), new Vector3(stopTarget.x, 0f, stopTarget.z));

        if (distanceToStopTarget < 1f)
        {
            if (!atStopTarget)
            {
                ApiManager.Instance?.AddStopLine(gameObject);
                atStopTarget = true;
            }
        }
        else
        {
            atStopTarget = false;
        }

        // check if we are past the target or reached current target
        if (Vector3.Dot(controller.frontCenter.forward, (currentTarget - controller.frontCenter.position).normalized) < 0 || distanceToCurrentTarget < 1f)
        {
            if (currentIndex == laneData.Count - 2) // reached 2nd to last target index see if stop line is present
            {
                StartStoppingCoroutine();
            }

            if (currentIndex < laneData.Count - 1) // reached target dist and is not at last index of lane data
            {
                currentIndex++;
                currentTarget = laneData[currentIndex];
                controller.Coroutines.Add(FixedUpdateManager.StartCoroutine(DelayChangeLane()));
            }
            else
            {
                GetNextLane();
            }
        }
    }
Example #9
0
    private IEnumerator NPCMoveIE()
    {
        if (CurrentIndex == 0)
        {
            // increment index since spawn is index = 0 with no passed params
            EvaluateLane();
        }

        if (CurrentIndex != 0)
        {
            var duration    = LaneTime[CurrentIndex] - LaneTime[CurrentIndex - 1];
            var elapsedTime = 0f;
            while (elapsedTime < duration)
            {
                var factor = elapsedTime / duration;
                var pose   = Vector3.Lerp(LaneData[CurrentIndex - 1], LaneData[CurrentIndex], factor);
                var rot    = Quaternion.Slerp(Quaternion.Euler(LaneAngle[CurrentIndex - 1]), Quaternion.Euler(LaneAngle[CurrentIndex]), factor);
                if (!float.IsNaN(pose.x))
                {
                    rb.MovePosition(pose);
                    rb.MoveRotation(rot);
                }
                elapsedTime += Mathf.Min(Time.fixedDeltaTime, duration - elapsedTime);
                yield return(new WaitForFixedUpdate());
            }
            rb.MovePosition(LaneData[CurrentIndex]);
            rb.MoveRotation(Quaternion.Euler(LaneAngle[CurrentIndex]));
        }

        if (CurrentIndex <= LaneData.Count - 1)
        {
            ApiManager.Instance?.AddWaypointReached(gameObject, CurrentIndex);

            // trigger
            if (LaneTriggerDistance[CurrentIndex] > 0)
            {
                WaypointState = WaypointDriveState.Trigger;
                yield return(TriggerCoroutine = FixedUpdateManager.StartCoroutine(NPCTriggerIE()));
            }

            // deactivate
            CurrentDeactivate = LaneDeactivate[CurrentIndex];

            // idle
            if (LaneIdle[CurrentIndex] > 0)
            {
                WaypointState = WaypointDriveState.Idle;
                yield return(IdleCoroutine = FixedUpdateManager.StartCoroutine(NPCIdleIE(LaneIdle[CurrentIndex], CurrentDeactivate)));
            }
            else if (LaneIdle[CurrentIndex] == -1 && CurrentDeactivate)
            {
                WaypointState = WaypointDriveState.Despawn;
                gameObject.SetActive(false);
                yield break;
            }
            else
            {
                // lane
                EvaluateLane();
            }
        }
        MoveCoroutine = null;
    }
Example #10
0
    protected virtual void EvaluateTarget()
    {
        distanceToCurrentTarget = Vector3.Distance(new Vector3(controller.frontCenter.position.x, 0f, controller.frontCenter.position.z), new Vector3(currentTarget.x, 0f, currentTarget.z));
        distanceToStopTarget    = Vector3.Distance(new Vector3(controller.frontCenter.position.x, 0f, controller.frontCenter.position.z), new Vector3(stopTarget.x, 0f, stopTarget.z));

        if (distanceToStopTarget < 1f)
        {
            if (!atStopTarget)
            {
                ApiManager.Instance?.AddStopLine(gameObject);
                atStopTarget = true;
            }
        }
        else
        {
            atStopTarget = false;
        }

        // check if we are past the target or reached current target
        if (Vector3.Dot(controller.frontCenter.forward, (currentTarget - controller.frontCenter.position).normalized) < 0 || distanceToCurrentTarget < 1f)
        {
            if (currentIndex == laneData.Count - 2) // reached 2nd to last target index see if stop line is present
            {
                StartStoppingCoroutine();
            }

            if (currentIndex < laneData.Count - 1) // reached target dist and is not at last index of lane data
            {
                currentIndex++;
                currentTarget = laneData[currentIndex];
                controller.Coroutines.Add(FixedUpdateManager.StartCoroutine(DelayChangeLane()));
            }
            else
            {
                // GetNextLane
                // last index of current lane data
                if (currentMapLane?.nextConnectedLanes.Count >= 1) // choose next path and set waypoints
                {
                    currentMapLane       = currentMapLane.nextConnectedLanes[RandomGenerator.Next(currentMapLane.nextConnectedLanes.Count)];
                    laneSpeedLimit       = currentMapLane.speedLimit;
                    aggressionAdjustRate = laneSpeedLimit / 11.176f; // 11.176 m/s corresponds to 25 mph
                    normalSpeed          = APIMaxSpeed > 0 ?
                                           Mathf.Min(APIMaxSpeed, laneSpeedLimit) :
                                           RandomGenerator.NextFloat(laneSpeedLimit, laneSpeedLimit + 1 + aggression); // API set max speed or lane speed limit
                    SetLaneData(currentMapLane.mapWorldPositions);
                    SetTurnSignal();
                }
                else
                {
                    Despawn(); // issue getting new waypoints so despawn
                }
            }
        }

        // isTurn
        if (currentMapLane == null)
        {
            return;
        }

        var path = transform.InverseTransformPoint(currentTarget).x;

        isCurve = path <-1f || path> 1f ? true : false;
    }
Example #11
0
    private IEnumerator NPCMoveIE()
    {
        if (CurrentIndex == 0)
        {
            // increment index since spawn is index = 0 with no passed params
            EvaluateLane();
        }

        if (CurrentIndex != 0)
        {
            var duration    = LaneTime[CurrentIndex] - LaneTime[CurrentIndex - 1];
            var elapsedTime = 0f;
            while (elapsedTime < duration)
            {
                var factor = elapsedTime / duration;
                var pose   = Vector3.Lerp(LaneData[CurrentIndex - 1], LaneData[CurrentIndex], factor);
                var rot    = Quaternion.Slerp(Quaternion.Euler(LaneAngle[CurrentIndex - 1]), Quaternion.Euler(LaneAngle[CurrentIndex]), factor);
                if (!float.IsNaN(pose.x))
                {
                    rb.MovePosition(pose);
                    rb.MoveRotation(rot);
                }
                elapsedTime += Mathf.Min(Time.fixedDeltaTime, duration - elapsedTime);
                yield return(new WaitForFixedUpdate());
            }
            rb.MovePosition(LaneData[CurrentIndex]);
            rb.MoveRotation(Quaternion.Euler(LaneAngle[CurrentIndex]));
        }

        if (CurrentIndex <= LaneData.Count - 1)
        {
            //LaneData includes npc position at 0 index, waypoints starts from index 1
            //Because of that index has to be lowered by 1 before passing to the API
            if (ApiManager.Instance != null)
            {
                ApiManager.Instance.AddWaypointReached(gameObject, CurrentIndex - 1);
            }

            // apply simple distance trigger
            if (LaneTriggerDistance[CurrentIndex] > 0)
            {
                WaypointState = WaypointDriveState.Trigger;
                yield return(TriggerCoroutine = FixedUpdateManager.StartCoroutine(NPCTriggerIE()));
            }

            // apply complex triggers
            if (CurrentIndex < LaneTriggers.Count && LaneTriggers[CurrentIndex] != null)
            {
                WaypointState = WaypointDriveState.Trigger;
                yield return(TriggerCoroutine = FixedUpdateManager.StartCoroutine(LaneTriggers[CurrentIndex].Apply(controller)));

                TriggerCoroutine = null;
            }

            // deactivate
            CurrentDeactivate = LaneDeactivate[CurrentIndex];

            // idle
            if (LaneIdle[CurrentIndex] > 0)
            {
                WaypointState = WaypointDriveState.Idle;
                yield return(IdleCoroutine = FixedUpdateManager.StartCoroutine(NPCIdleIE(LaneIdle[CurrentIndex], CurrentDeactivate)));
            }
            else if (LaneIdle[CurrentIndex] == -1 && CurrentDeactivate)
            {
                WaypointState = WaypointDriveState.Despawn;
                gameObject.SetActive(false);
                MoveCoroutine = null;
                yield break;
            }
            else
            {
                // lane
                EvaluateLane();
            }
        }
        MoveCoroutine = null;
    }