IEnumerator WaitTrafficLight() { currentStopTime = 0f; yield return(FixedUpdateManager.WaitUntilFixed(() => distanceToStopTarget <= stopLineDistance)); if (prevMapLane.stopLine.currentState == MapData.SignalLightStateType.Green) { yield break; // light is green so just go } isStopLight = true; yield return(FixedUpdateManager.WaitUntilFixed(() => atStopTarget)); // wait if until reaching stop line if ((isRightTurn && prevMapLane.rightLaneReverse == null)) { var waitTime = RandomGenerator.NextFloat(0f, 3f); var startTime = currentStopTime; yield return(FixedUpdateManager.WaitUntilFixed(() => prevMapLane.stopLine.currentState == MapData.SignalLightStateType.Green || currentStopTime - startTime >= waitTime)); isStopLight = false; yield break; } yield return(FixedUpdateManager.WaitUntilFixed(() => prevMapLane.stopLine.currentState == MapData.SignalLightStateType.Green)); // wait until green light if (isLeftTurn || isRightTurn) { yield return(FixedUpdateManager.WaitForFixedSeconds(RandomGenerator.NextFloat(1f, 2f))); // wait to creep out on turn } isStopLight = false; }
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())); } } }
protected IEnumerator DelayOffTurnSignals() { yield return(FixedUpdateManager.WaitForFixedSeconds(3f)); isLeftTurn = isRightTurn = false; controller.SetNPCTurnSignal(); }
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); } } } }
private void InitNPC() { Debug.Assert(LaneData != null); rb.isKinematic = true; controller.MainCollider.isTrigger = true; controller.ResetLights(); currentSpeed = 0f; rb.angularVelocity = Vector3.zero; rb.velocity = Vector3.zero; CurrentIndex = 0; CurrentLoopIndex = 0; CurrentDeactivate = LaneDeactivate[CurrentIndex]; if (IdleCoroutine != null) { FixedUpdateManager.StopCoroutine(IdleCoroutine); IdleCoroutine = null; } if (MoveCoroutine != null) { FixedUpdateManager.StopCoroutine(MoveCoroutine); MoveCoroutine = null; } if (TriggerCoroutine != null) { FixedUpdateManager.StopCoroutine(TriggerCoroutine); TriggerCoroutine = null; } WaypointState = WaypointDriveState.Drive; }
private void EvaluateLane() { CurrentIndex++; // index can equal laneData.Count so it can finish npc move IE if (CurrentIndex < LaneData.Count) { CurrentTarget = LaneData[CurrentIndex]; } if (CurrentIndex == LaneData.Count) { if (WaypointLoop) { rb.MovePosition(InitPos); rb.MoveRotation(InitRot); InitNPC(); } else { WaypointState = WaypointDriveState.Despawn; FixedUpdateManager.StopAllCoroutines(); TriggerCoroutine = null; IdleCoroutine = null; MoveCoroutine = null; } } else { WaypointState = WaypointDriveState.Drive; } }
private void InitPedestrian() { Debug.Assert(LaneData != null); RB.isKinematic = true; // TODO currentSpeed = 0f; RB.angularVelocity = Vector3.zero; RB.velocity = Vector3.zero; CurrentIndex = 0; CurrentLoopIndex = 0; if (IdleCoroutine != null) { FixedUpdateManager.StopCoroutine(IdleCoroutine); IdleCoroutine = null; } if (MoveCoroutine != null) { FixedUpdateManager.StopCoroutine(MoveCoroutine); MoveCoroutine = null; } if (TriggerCoroutine != null) { FixedUpdateManager.StopCoroutine(TriggerCoroutine); TriggerCoroutine = null; } WaypointState = WaypointWalkState.Walk; }
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); } } } } } }
private void EvaluateLane() { CurrentIndex++; // index can equal laneData.Count so it can finish npc move IE if (CurrentIndex < LaneData.Count) { CurrentTarget = LaneData[CurrentIndex]; controller.MovementSpeed = LaneSpeed[CurrentIndex]; controller.currentSpeed = LaneSpeed[CurrentIndex]; controller.steerVector = (CurrentTarget - controller.frontCenter.position).normalized; } if (CurrentIndex == LaneData.Count) { var api = ApiManager.Instance; if (WaypointLoop) { if (CurrentLoopIndex == 0 && api != null) { api.AgentTraversedWaypoints(gameObject); } CurrentLoopIndex++; rb.MovePosition(InitPos); rb.MoveRotation(InitRot); InitNPC(); } else { if (api != null) { api.AgentTraversedWaypoints(gameObject); } WaypointState = WaypointDriveState.Despawn; if (TriggerCoroutine != null) { FixedUpdateManager.StopCoroutine(TriggerCoroutine); } TriggerCoroutine = null; if (IdleCoroutine != null) { FixedUpdateManager.StopCoroutine(IdleCoroutine); } IdleCoroutine = null; if (MoveCoroutine != null) { FixedUpdateManager.StopCoroutine(MoveCoroutine); } MoveCoroutine = null; } } else { WaypointState = WaypointDriveState.Drive; } }
public override void PhysicsUpdate() { if (WaypointState == WaypointWalkState.Walk) { if (MoveCoroutine != null) { return; } MoveCoroutine = FixedUpdateManager.StartCoroutine(PedestrianMoveIE()); } }
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(); } }
private IEnumerator NPCIdleIE(float duration, bool deactivate) { if (deactivate) { gameObject.SetActive(false); } yield return(FixedUpdateManager.WaitForFixedSeconds(duration)); if (deactivate) { gameObject.SetActive(true); } EvaluateLane(); IdleCoroutine = null; }
protected IEnumerator DelayChangeLane() { if (currentMapLane == null) { yield break; } if (!currentMapLane.isTrafficLane) { yield break; } if (RandomGenerator.Next(100) < 98) { yield break; } if (!laneChange) { yield break; } if (currentMapLane.leftLaneForward != null) { isLeftTurn = true; isRightTurn = false; controller.SetNPCTurnSignal(); } else if (currentMapLane.rightLaneForward != null) { isRightTurn = true; isLeftTurn = false; controller.SetNPCTurnSignal(); } yield return(FixedUpdateManager.WaitForFixedSeconds(RandomGenerator.NextFloat(1f, 3f))); if (currentIndex >= laneData.Count - 2) { isLeftTurn = isRightTurn = false; yield break; } SetLaneChange(); }
IEnumerator WaitStopSign() { yield return(FixedUpdateManager.WaitUntilFixed(() => distanceToStopTarget <= stopLineDistance)); isStopSign = true; currentStopTime = 0f; hasReachedStopSign = false; yield return(FixedUpdateManager.WaitUntilFixed(() => distanceToStopTarget < minTargetDistance)); prevMapLane.stopLine.intersection.EnterStopSignQueue(controller); hasReachedStopSign = true; yield return(FixedUpdateManager.WaitForFixedSeconds(stopSignWaitTime)); yield return(FixedUpdateManager.WaitUntilFixed(() => prevMapLane.stopLine.intersection.CheckStopSignQueue(controller))); hasReachedStopSign = false; isStopSign = false; }
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())); } } } }
private void EvaluateLane() { CurrentIndex++; // index can equal laneData.Count so it can finish npc move IE if (CurrentIndex < LaneData.Count) { CurrentTarget = LaneData[CurrentIndex]; controller.MovementSpeed = LaneSpeed[CurrentIndex]; } if (CurrentIndex == LaneData.Count) { var api = ApiManager.Instance; if (WaypointLoop) { if (CurrentLoopIndex == 0 && api != null) { api.AgentTraversedWaypoints(gameObject); } CurrentLoopIndex++; rb.MovePosition(InitPos); rb.MoveRotation(InitRot); InitNPC(); } else { if (api != null) { api.AgentTraversedWaypoints(gameObject); } WaypointState = WaypointDriveState.Despawn; FixedUpdateManager.StopAllCoroutines(); TriggerCoroutine = null; IdleCoroutine = null; MoveCoroutine = null; } } else { WaypointState = WaypointDriveState.Drive; } }
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(); } } }
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; }
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; }
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; }