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); } } } }
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()); } }
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())); } } } }
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; }
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; }
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; }