Turn.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using JetBrains.Annotations;
  5. using Pools;
  6. using Roads;
  7. using UnityEditor;
  8. using UnityEngine;
  9. using Valve.VR.InteractionSystem;
  10. namespace Routes
  11. {
  12. public enum TriggerState
  13. {
  14. Inside,
  15. Outside,
  16. }
  17. public enum RoadDirection
  18. {
  19. West,
  20. North,
  21. East,
  22. South,
  23. None
  24. }
  25. public enum TurnDirection
  26. {
  27. Right,
  28. Left,
  29. Straight
  30. }
  31. public abstract class Turn : MonoBehaviour
  32. {
  33. public RoadDirection comingFrom;
  34. public RoadDirection goingTo;
  35. [CanBeNull] private Pool arrowPool;
  36. private bool arrowPoolAvailable;
  37. private TurnDirection turnDirection;
  38. private List<GameObject> usedArrows = new List<GameObject>();
  39. private Collider trigger;
  40. private static readonly RoadDirection[] allDirections =
  41. {RoadDirection.West, RoadDirection.North, RoadDirection.East, RoadDirection.South};
  42. public Action OnTriggerExitBicycle { get; set; }
  43. public TriggerState BikeTriggerState { get; private set; } = TriggerState.Outside;
  44. private void Awake()
  45. {
  46. arrowPool = FindObjectsOfType<Pool>().FirstOrDefault(o => o.CompareTag("ArrowPool"));
  47. arrowPoolAvailable = arrowPool != null;
  48. trigger = GetComponent<Collider>();
  49. if (!arrowPoolAvailable) Debug.LogWarning("Arrow Pool not found");
  50. }
  51. private void Start()
  52. {
  53. UpdateArrows();
  54. }
  55. [CanBeNull]
  56. protected abstract Transform RoadDirectionToTransform(RoadDirection position);
  57. private bool AddArrows(RoadDirection position, GameObject arrows)
  58. {
  59. Debug.Log($"---{gameObject.name}--- adding arrows at {position}");
  60. var t = RoadDirectionToTransform(position);
  61. if (t == null) return false;
  62. Debug.Log($" Transform for position => {t.gameObject.name}");
  63. SetRotation(arrows, position);
  64. arrows.transform.position = t.position;
  65. return true;
  66. }
  67. private void SetRotation(GameObject arrows, RoadDirection position)
  68. {
  69. var t = arrows.transform;
  70. //by default, the arrows show to east
  71. switch (position)
  72. {
  73. case RoadDirection.West:
  74. {
  75. if (turnDirection == TurnDirection.Left ||
  76. turnDirection == TurnDirection.Straight && goingTo == RoadDirection.South)
  77. {
  78. t.rotation = Quaternion.Euler(0, 90, 0);
  79. //arrows.transform.Rotate(Vector3.up, 90);
  80. }
  81. else if (turnDirection == TurnDirection.Right ||
  82. turnDirection == TurnDirection.Straight && goingTo == RoadDirection.North)
  83. {
  84. t.rotation = Quaternion.Euler(0, 270, 0);
  85. //arrows.transform.Rotate(Vector3.up, 90);
  86. }
  87. break;
  88. }
  89. case RoadDirection.North:
  90. if (turnDirection == TurnDirection.Left ||
  91. turnDirection == TurnDirection.Straight && goingTo == RoadDirection.West)
  92. {
  93. t.rotation = Quaternion.Euler(0, 180, 0);
  94. //arrows.transform.Rotate(Vector3.up, 180);
  95. }
  96. break;
  97. case RoadDirection.East:
  98. if (turnDirection == TurnDirection.Right ||
  99. turnDirection == TurnDirection.Straight && goingTo == RoadDirection.South)
  100. {
  101. t.rotation = Quaternion.Euler(0, 90, 0);
  102. //arrows.transform.Rotate(Vector3.up, 90);
  103. }
  104. else if (turnDirection == TurnDirection.Left ||
  105. turnDirection == TurnDirection.Straight && goingTo == RoadDirection.North)
  106. {
  107. t.rotation = Quaternion.Euler(0, 270, 0);
  108. //arrows.transform.Rotate(Vector3.up, -90);
  109. }
  110. break;
  111. case RoadDirection.South:
  112. if (turnDirection == TurnDirection.Right ||
  113. turnDirection == TurnDirection.Straight && goingTo == RoadDirection.West)
  114. {
  115. t.rotation = Quaternion.Euler(0, 180, 0);
  116. //arrows.transform.Rotate(Vector3.up, 180);
  117. }
  118. break;
  119. case RoadDirection.None:
  120. throw new ArgumentException("RoadDirection.None not allowed for adding arrows");
  121. default:
  122. throw new ArgumentOutOfRangeException(nameof(position), position, null);
  123. }
  124. }
  125. public void UpdateArrows()
  126. {
  127. if (comingFrom == RoadDirection.None || goingTo == RoadDirection.None)
  128. {
  129. if (!arrowPoolAvailable) return;
  130. usedArrows.ForEach(o =>
  131. {
  132. // ReSharper disable once PossibleNullReferenceException
  133. arrowPool.ReturnToPool(o);
  134. });
  135. usedArrows.Clear();
  136. return;
  137. }
  138. turnDirection = TurnDirectionMapper.GetTurnDirection(comingFrom, goingTo);
  139. var usedArrowIndex = 0;
  140. foreach (var position in allDirections.Where(i => i != comingFrom && i != goingTo))
  141. {
  142. GameObject arrows;
  143. if (usedArrowIndex < usedArrows.Count)
  144. {
  145. arrows = usedArrows[usedArrowIndex];
  146. }
  147. else
  148. {
  149. // ReSharper disable once PossibleNullReferenceException
  150. arrows = arrowPool.GetItem();
  151. usedArrows.Add(arrows);
  152. }
  153. var used = AddArrows(position, arrows);
  154. if (!used)
  155. {
  156. // ReSharper disable once PossibleNullReferenceException
  157. arrowPool.ReturnToPool(arrows);
  158. usedArrows.Remove(arrows);
  159. continue;
  160. }
  161. usedArrowIndex++;
  162. }
  163. trigger.enabled = true;
  164. }
  165. private void OnTriggerExit(Collider other)
  166. {
  167. if (other.CompareTag("bike") && OnTriggerExitBicycle != null)
  168. {
  169. OnTriggerExitBicycle();
  170. trigger.enabled = false;
  171. BikeTriggerState = TriggerState.Outside;
  172. }
  173. }
  174. private void OnTriggerEnter(Collider other)
  175. {
  176. if (other.CompareTag("bike"))
  177. {
  178. BikeTriggerState = TriggerState.Inside;
  179. }
  180. }
  181. }
  182. }