Intersection.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Traffic Simulation
  2. // https://github.com/mchrbn/unity-traffic-simulation
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. namespace TrafficSimulation{
  6. public enum IntersectionType{
  7. STOP,
  8. TRAFFIC_LIGHT
  9. }
  10. public class Intersection : MonoBehaviour
  11. {
  12. public IntersectionType intersectionType;
  13. public int id;
  14. //For stop only
  15. public List<Segment> prioritySegments;
  16. //For traffic lights only
  17. public float lightsDuration = 8;
  18. public float orangeLightDuration = 2;
  19. public List<Segment> lightsNbr1;
  20. public List<Segment> lightsNbr2;
  21. private List<GameObject> vehiclesQueue;
  22. private List<GameObject> vehiclesInIntersection;
  23. private TrafficSystem trafficSystem;
  24. [HideInInspector] public int currentRedLightsGroup = 1;
  25. void Start(){
  26. vehiclesQueue = new List<GameObject>();
  27. vehiclesInIntersection = new List<GameObject>();
  28. if(intersectionType == IntersectionType.TRAFFIC_LIGHT)
  29. InvokeRepeating("SwitchLights", lightsDuration, lightsDuration);
  30. }
  31. void SwitchLights(){
  32. if(currentRedLightsGroup == 1) currentRedLightsGroup = 2;
  33. else if(currentRedLightsGroup == 2) currentRedLightsGroup = 1;
  34. //Wait few seconds after light transition before making the other car move (= orange light)
  35. Invoke("MoveVehiclesQueue", orangeLightDuration);
  36. }
  37. void OnTriggerEnter(Collider _other) {
  38. //Check if vehicle is already in the list if yes abort
  39. //Also abort if we just started the scene (if vehicles inside colliders at start)
  40. if(IsAlreadyInIntersection(_other.gameObject) || Time.timeSinceLevelLoad < .5f) return;
  41. if(_other.tag == "AutonomousVehicle" && intersectionType == IntersectionType.STOP)
  42. TriggerStop(_other.gameObject);
  43. else if(_other.tag == "AutonomousVehicle" && intersectionType == IntersectionType.TRAFFIC_LIGHT)
  44. TriggerLight(_other.gameObject);
  45. }
  46. void OnTriggerExit(Collider _other) {
  47. if(_other.tag == "AutonomousVehicle" && intersectionType == IntersectionType.STOP)
  48. ExitStop(_other.gameObject);
  49. else if(_other.tag == "AutonomousVehicle" && intersectionType == IntersectionType.TRAFFIC_LIGHT)
  50. ExitLight(_other.gameObject);
  51. }
  52. void TriggerStop(GameObject _vehicle){
  53. VehicleAI vehicleAI = _vehicle.GetComponent<VehicleAI>();
  54. //Depending on the waypoint threshold, the car can be either on the target segment or on the past segment
  55. int vehicleSegment = vehicleAI.GetSegmentVehicleIsIn();
  56. if(!IsPrioritySegment(vehicleSegment)){
  57. if(vehiclesQueue.Count > 0 || vehiclesInIntersection.Count > 0){
  58. vehicleAI.vehicleStatus = Status.STOP;
  59. vehiclesQueue.Add(_vehicle);
  60. }
  61. else{
  62. vehiclesInIntersection.Add(_vehicle);
  63. vehicleAI.vehicleStatus = Status.SLOW_DOWN;
  64. }
  65. }
  66. else{
  67. vehicleAI.vehicleStatus = Status.SLOW_DOWN;
  68. vehiclesInIntersection.Add(_vehicle);
  69. }
  70. }
  71. void ExitStop(GameObject _vehicle){
  72. _vehicle.GetComponent<VehicleAI>().vehicleStatus = Status.GO;
  73. vehiclesInIntersection.Remove(_vehicle);
  74. vehiclesQueue.Remove(_vehicle);
  75. if(vehiclesQueue.Count > 0 && vehiclesInIntersection.Count == 0){
  76. vehiclesQueue[0].GetComponent<VehicleAI>().vehicleStatus = Status.GO;
  77. }
  78. }
  79. void TriggerLight(GameObject _vehicle){
  80. VehicleAI vehicleAI = _vehicle.GetComponent<VehicleAI>();
  81. int vehicleSegment = vehicleAI.GetSegmentVehicleIsIn();
  82. if(IsRedLightSegment(vehicleSegment)){
  83. vehicleAI.vehicleStatus = Status.STOP;
  84. vehiclesQueue.Add(_vehicle);
  85. }
  86. else{
  87. vehicleAI.vehicleStatus = Status.GO;
  88. }
  89. }
  90. void ExitLight(GameObject _vehicle){
  91. _vehicle.GetComponent<VehicleAI>().vehicleStatus = Status.GO;
  92. }
  93. bool IsRedLightSegment(int _vehicleSegment){
  94. if(currentRedLightsGroup == 1){
  95. foreach(Segment segment in lightsNbr1){
  96. if(segment.id == _vehicleSegment)
  97. return true;
  98. }
  99. }
  100. else{
  101. foreach(Segment segment in lightsNbr2){
  102. if(segment.id == _vehicleSegment)
  103. return true;
  104. }
  105. }
  106. return false;
  107. }
  108. void MoveVehiclesQueue(){
  109. //Move all vehicles in queue
  110. List<GameObject> nVehiclesQueue = new List<GameObject>(vehiclesQueue);
  111. foreach(GameObject vehicle in vehiclesQueue){
  112. int vehicleSegment = vehicle.GetComponent<VehicleAI>().GetSegmentVehicleIsIn();
  113. if(!IsRedLightSegment(vehicleSegment)){
  114. vehicle.GetComponent<VehicleAI>().vehicleStatus = Status.GO;
  115. nVehiclesQueue.Remove(vehicle);
  116. }
  117. }
  118. vehiclesQueue = nVehiclesQueue;
  119. }
  120. bool IsPrioritySegment(int _vehicleSegment){
  121. foreach(Segment s in prioritySegments){
  122. if(_vehicleSegment == s.id)
  123. return true;
  124. }
  125. return false;
  126. }
  127. bool IsAlreadyInIntersection(GameObject _target){
  128. foreach(GameObject vehicle in vehiclesInIntersection){
  129. if(vehicle.GetInstanceID() == _target.GetInstanceID()) return true;
  130. }
  131. foreach(GameObject vehicle in vehiclesQueue){
  132. if(vehicle.GetInstanceID() == _target.GetInstanceID()) return true;
  133. }
  134. return false;
  135. }
  136. private List<GameObject> memVehiclesQueue = new List<GameObject>();
  137. private List<GameObject> memVehiclesInIntersection = new List<GameObject>();
  138. public void SaveIntersectionStatus(){
  139. memVehiclesQueue = vehiclesQueue;
  140. memVehiclesInIntersection = vehiclesInIntersection;
  141. }
  142. public void ResumeIntersectionStatus(){
  143. foreach(GameObject v in vehiclesInIntersection){
  144. foreach(GameObject v2 in memVehiclesInIntersection){
  145. if(v.GetInstanceID() == v2.GetInstanceID()){
  146. v.GetComponent<VehicleAI>().vehicleStatus = v2.GetComponent<VehicleAI>().vehicleStatus;
  147. break;
  148. }
  149. }
  150. }
  151. foreach(GameObject v in vehiclesQueue){
  152. foreach(GameObject v2 in memVehiclesQueue){
  153. if(v.GetInstanceID() == v2.GetInstanceID()){
  154. v.GetComponent<VehicleAI>().vehicleStatus = v2.GetComponent<VehicleAI>().vehicleStatus;
  155. break;
  156. }
  157. }
  158. }
  159. }
  160. }
  161. }