Intersection.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. //Debug.Log("Trigger Stop!");
  43. TriggerStop(_other.gameObject);
  44. }else if(_other.tag == "AutonomousVehicle" && intersectionType == IntersectionType.TRAFFIC_LIGHT){
  45. //Debug.Log("Trigger Light!");
  46. TriggerLight(_other.gameObject);
  47. }
  48. }
  49. void OnTriggerExit(Collider _other) {
  50. if(_other.tag == "AutonomousVehicle" && intersectionType == IntersectionType.STOP)
  51. ExitStop(_other.gameObject);
  52. else if(_other.tag == "AutonomousVehicle" && intersectionType == IntersectionType.TRAFFIC_LIGHT)
  53. ExitLight(_other.gameObject);
  54. }
  55. void TriggerStop(GameObject _vehicle){
  56. VehicleAI vehicleAI = _vehicle.GetComponent<VehicleAI>();
  57. //Depending on the waypoint threshold, the car can be either on the target segment or on the past segment
  58. int vehicleSegment = vehicleAI.GetSegmentVehicleIsIn();
  59. if(!IsPrioritySegment(vehicleSegment)){
  60. if(vehiclesQueue.Count > 0 || vehiclesInIntersection.Count > 0){
  61. vehicleAI.vehicleStatus = Status.STOP;
  62. vehiclesQueue.Add(_vehicle);
  63. }
  64. else{
  65. vehiclesInIntersection.Add(_vehicle);
  66. vehicleAI.vehicleStatus = Status.SLOW_DOWN;
  67. }
  68. }
  69. else{
  70. vehicleAI.vehicleStatus = Status.SLOW_DOWN;
  71. vehiclesInIntersection.Add(_vehicle);
  72. }
  73. }
  74. void ExitStop(GameObject _vehicle){
  75. _vehicle.GetComponent<VehicleAI>().vehicleStatus = Status.GO;
  76. vehiclesInIntersection.Remove(_vehicle);
  77. vehiclesQueue.Remove(_vehicle);
  78. if(vehiclesQueue.Count > 0 && vehiclesInIntersection.Count == 0){
  79. vehiclesQueue[0].GetComponent<VehicleAI>().vehicleStatus = Status.GO;
  80. }
  81. }
  82. void TriggerLight(GameObject _vehicle){
  83. VehicleAI vehicleAI = _vehicle.GetComponent<VehicleAI>();
  84. int vehicleSegment = vehicleAI.GetSegmentVehicleIsIn();
  85. if(IsRedLightSegment(vehicleSegment)){
  86. //Debug.Log("Stop Vehicle");
  87. vehicleAI.vehicleStatus = Status.STOP;
  88. vehiclesQueue.Add(_vehicle);
  89. }
  90. else{
  91. //Debug.Log("Go Vehicle");
  92. vehicleAI.vehicleStatus = Status.GO;
  93. }
  94. }
  95. void ExitLight(GameObject _vehicle){
  96. _vehicle.GetComponent<VehicleAI>().vehicleStatus = Status.GO;
  97. }
  98. bool IsRedLightSegment(int _vehicleSegment){
  99. if(currentRedLightsGroup == 1){
  100. foreach(Segment segment in lightsNbr1){
  101. if(segment.id == _vehicleSegment)
  102. return true;
  103. }
  104. }
  105. else{
  106. foreach(Segment segment in lightsNbr2){
  107. if(segment.id == _vehicleSegment)
  108. return true;
  109. }
  110. }
  111. return false;
  112. }
  113. void MoveVehiclesQueue(){
  114. //Move all vehicles in queue
  115. List<GameObject> nVehiclesQueue = new List<GameObject>(vehiclesQueue);
  116. foreach(GameObject vehicle in vehiclesQueue){
  117. int vehicleSegment = vehicle.GetComponent<VehicleAI>().GetSegmentVehicleIsIn();
  118. if(!IsRedLightSegment(vehicleSegment)){
  119. vehicle.GetComponent<VehicleAI>().vehicleStatus = Status.GO;
  120. nVehiclesQueue.Remove(vehicle);
  121. }
  122. }
  123. vehiclesQueue = nVehiclesQueue;
  124. }
  125. bool IsPrioritySegment(int _vehicleSegment){
  126. foreach(Segment s in prioritySegments){
  127. if(_vehicleSegment == s.id)
  128. return true;
  129. }
  130. return false;
  131. }
  132. bool IsAlreadyInIntersection(GameObject _target){
  133. foreach(GameObject vehicle in vehiclesInIntersection){
  134. if(vehicle.GetInstanceID() == _target.GetInstanceID()) return true;
  135. }
  136. foreach(GameObject vehicle in vehiclesQueue){
  137. if(vehicle.GetInstanceID() == _target.GetInstanceID()) return true;
  138. }
  139. return false;
  140. }
  141. private List<GameObject> memVehiclesQueue = new List<GameObject>();
  142. private List<GameObject> memVehiclesInIntersection = new List<GameObject>();
  143. public void SaveIntersectionStatus(){
  144. memVehiclesQueue = vehiclesQueue;
  145. memVehiclesInIntersection = vehiclesInIntersection;
  146. }
  147. public void ResumeIntersectionStatus(){
  148. foreach(GameObject v in vehiclesInIntersection){
  149. foreach(GameObject v2 in memVehiclesInIntersection){
  150. if(v.GetInstanceID() == v2.GetInstanceID()){
  151. v.GetComponent<VehicleAI>().vehicleStatus = v2.GetComponent<VehicleAI>().vehicleStatus;
  152. break;
  153. }
  154. }
  155. }
  156. foreach(GameObject v in vehiclesQueue){
  157. foreach(GameObject v2 in memVehiclesQueue){
  158. if(v.GetInstanceID() == v2.GetInstanceID()){
  159. v.GetComponent<VehicleAI>().vehicleStatus = v2.GetComponent<VehicleAI>().vehicleStatus;
  160. break;
  161. }
  162. }
  163. }
  164. }
  165. }
  166. }