private void OnDrawGizmosSelected() { Gizmos.color = Color.red; Vector3 offset = -transform.right * vehicle.Roundabout.laneWidth; Vector3 r = (vehicle.GetRear() - transform.forward * minMergeDist + offset); Vector3 f = (vehicle.GetFront() + transform.forward * minMergeDist + offset); Gizmos.DrawWireSphere(r, 0.25f); Gizmos.DrawWireSphere(f, 0.25f); Gizmos.DrawLine(f, r); offset *= -1.0f; r = (vehicle.GetRear() - transform.forward * minMergeDist + offset); f = (vehicle.GetFront() + transform.forward * minMergeDist + offset); Gizmos.DrawWireSphere(r, 0.25f); Gizmos.DrawWireSphere(f, 0.25f); Gizmos.DrawLine(f, r); ILaneUser infront = vehicle.Roundabout.GetNextAhead(vehicle.GetLane(), vehicle); if (infront != null) { Gizmos.DrawWireSphere(((MonoBehaviour)infront).transform.position, 1.0f); } }
public ILaneUser GetNextAhead(ILaneUser from) { int laneId = from.GetLane() - 1; var vehicles = laneObjects[laneId]; int index = vehicles.FindIndex(v => v == from); int nextIndex = index + 1; if (nextIndex >= vehicles.Count) { nextIndex = 0; } if (vehicles[nextIndex] == from) { return(null); } return(vehicles[nextIndex]); }
public ILaneUser GetNextBehind(int lane, ILaneUser from) { int laneId = lane - 1; var vehicles = laneObjects[laneId]; if (vehicles.Count == 0) { return(null); } for (int i = vehicles.Count - 1; i >= 0; i--) { if (vehicles[i] == from) { continue; } if (vehicles[i].CurrentAngle < from.CurrentAngle) { return(vehicles[i]); } } return(vehicles[vehicles.Count - 1] == from ? null : vehicles[vehicles.Count - 1]); }
public ILaneUser GetNextAhead(int lane, ILaneUser from) { int laneId = lane - 1; var vehicles = laneObjects[laneId]; if (vehicles.Count == 0) { return(null); } for (int i = 0; i < vehicles.Count; i++) { if (vehicles[i] == from) { continue; } if (vehicles[i].CurrentAngle > from.CurrentAngle) { return(vehicles[i]); } } return(vehicles[0] == from ? null : vehicles[0]); }
private void FixedUpdate() { var roundabout = vehicle.Roundabout; // Follow the next object until we can go around them ILaneUser nextObject = vehicle.Roundabout.GetNextAhead(vehicle); if (nextObject != null) { float distance = vehicle.Roundabout.GetAngleDistance(vehicle.GetLane(), vehicle.GetFront(), nextObject.GetRear()); if (distance < followDistance) { vehicle.targetSpeed = distance < arseDistance?nextObject.GetSpeed() - backoffSpeed : nextObject.GetSpeed(); if (followStartTime == 0.0f) { followStartTime = Time.time; } } else if (distance > followDistance + 0.2f) { ResetFollowing(); } } else { ResetFollowing(); } float targetFollowTime = nextObject != null && nextObject is Obstacle ? 0.0f : minFollowTime; // If we've been following for a few seconds, try and go around the object if (vehicle.targetSpeed < vehicle.maxSpeed && Time.time - followStartTime >= targetFollowTime && Time.time - lastTurnTime > turnDelay) { bool canChangeLeft = false; bool canChangeRight = false; if (vehicle.GetLane() < roundabout.lanes) { canChangeLeft = true; int targetLane = vehicle.GetLane() + 1; ILaneUser ahead = roundabout.GetNextAhead(targetLane, vehicle); ILaneUser behind = roundabout.GetNextBehind(targetLane, vehicle); Vector3 offset = -transform.right * roundabout.laneWidth; if (ahead != null && Vector3.Dot(transform.forward, ahead.GetRear() - vehicle.GetFront()) < 0.0f) { canChangeLeft = false; } if (behind != null && Vector3.Dot(-transform.forward, behind.GetFront() - vehicle.GetRear()) < 0.0f) { canChangeLeft = false; } if (canChangeLeft) { if (ahead != null) { float frontDist2 = (ahead.GetRear() - (vehicle.GetFront() + offset)).sqrMagnitude; if (frontDist2 < minMergeDist * minMergeDist) { canChangeLeft = false; } } if (behind != null) { float rearDist2 = ((vehicle.GetRear() + offset) - behind.GetFront()).sqrMagnitude; if (rearDist2 < minMergeDist * minMergeDist) { canChangeLeft = false; } } } } if (vehicle.GetLane() > 1) { canChangeRight = true; int targetLane = vehicle.GetLane() - 1; ILaneUser ahead = roundabout.GetNextAhead(targetLane, vehicle); ILaneUser behind = roundabout.GetNextBehind(targetLane, vehicle); if (ahead != null && Vector3.Dot(transform.forward, ahead.GetRear() - vehicle.GetFront()) < 0.0f) { canChangeRight = false; } if (behind != null && Vector3.Dot(-transform.forward, behind.GetFront() - vehicle.GetRear()) < 0.0f) { canChangeRight = false; } if (canChangeRight) { Vector3 offset = transform.right * roundabout.laneWidth; if (ahead != null) { float frontDist2 = (ahead.GetRear() - (vehicle.GetFront() + offset)).sqrMagnitude; if (frontDist2 < minMergeDist * minMergeDist) { canChangeRight = false; } } if (behind != null) { float rearDist2 = ((vehicle.GetRear() + offset) - behind.GetFront()).sqrMagnitude; if (rearDist2 < minMergeDist * minMergeDist) { canChangeRight = false; } } } } if (canChangeLeft || canChangeRight) { lastTurnTime = Time.time; followStartTime = Time.time; } if (canChangeLeft && !canChangeRight) { vehicle.ChangeLaneLeft(); } else if (canChangeRight && !canChangeLeft) { vehicle.ChangeLaneRight(); } else if (canChangeLeft && canChangeRight) { if (Random.value > 0.5f) { vehicle.ChangeLaneLeft(); } else { vehicle.ChangeLaneRight(); } } } }