DoorController.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using Sirenix.OdinInspector;
  5. using KairoEngine.Core;
  6. using KairoEngine.SFX;
  7. namespace KairoEngine.CharacterSystem
  8. {
  9. public enum DoorState
  10. {
  11. Open,
  12. Closed,
  13. Locked,
  14. LockedOpen,
  15. Blocked
  16. }
  17. public class DoorController : MonoBehaviour
  18. {
  19. public string title = "Door 001";
  20. public DoorState doorState = DoorState.Closed;
  21. public GameObject doorObject;
  22. public DoorTrigger doorTrigger;
  23. public Transform doorOpenTransform;
  24. public Transform doorClosedTransform;
  25. public float animationTime;
  26. public SFXClip soundEffect;
  27. private ActionController actionController;
  28. private bool inMotion = false;
  29. private float time = 0f;
  30. public static Dictionary<string, System.Action<DoorState>> list = new Dictionary<string, System.Action<DoorState>>();
  31. public static void StartListening(string title, System.Action<DoorState> listener)
  32. {
  33. System.Action<DoorState> action = null;
  34. if (list.TryGetValue(title, out action))
  35. {
  36. action += listener;
  37. list[title] = action;
  38. }
  39. else
  40. {
  41. action += listener;
  42. list.Add(title, action);
  43. }
  44. }
  45. public static void StopListening(string title, System.Action<DoorState> listener)
  46. {
  47. System.Action<DoorState> action = null;
  48. if (list.TryGetValue(title, out action))
  49. {
  50. action -= listener;
  51. list[title] = action;
  52. }
  53. }
  54. public static void Trigger(string title, DoorState state)
  55. {
  56. System.Action<DoorState> action = null;
  57. if (list.TryGetValue(title, out action))
  58. {
  59. if(action != null) action(state);
  60. }
  61. }
  62. void OnEnable()
  63. {
  64. DoorController.StartListening(title, ChangeState);
  65. }
  66. void OnDisable()
  67. {
  68. DoorController.StopListening(title, ChangeState);
  69. }
  70. void Start()
  71. {
  72. actionController = GetComponent<ActionController>();
  73. if(actionController == null) Debug.LogError("Missing ActionController", this.gameObject);
  74. }
  75. void Update()
  76. {
  77. time += Time.deltaTime;
  78. if(doorTrigger.charactersInRange.Count > 0 && inMotion == false)
  79. {
  80. if(doorState == DoorState.Closed) ChangeState(DoorState.Open);
  81. }
  82. else if(doorTrigger.charactersInRange.Count == 0 && inMotion == false)
  83. {
  84. if(doorState == DoorState.Open) ChangeState(DoorState.Closed);
  85. }
  86. }
  87. public void ChangeState(DoorState newState)
  88. {
  89. switch (newState)
  90. {
  91. case DoorState.Open:
  92. if(doorState == DoorState.Closed)
  93. {
  94. Open();
  95. doorState = DoorState.Open;
  96. }
  97. else if(doorState == DoorState.LockedOpen) doorState = DoorState.Open;
  98. break;
  99. case DoorState.Closed:
  100. if(doorState == DoorState.Open || doorState == DoorState.LockedOpen)
  101. {
  102. Close();
  103. doorState = DoorState.Closed;
  104. }
  105. else if(doorState == DoorState.Locked) doorState = DoorState.Closed;
  106. break;
  107. case DoorState.Locked:
  108. if(doorState == DoorState.Closed) doorState = DoorState.Locked;
  109. else if(doorState == DoorState.Open)
  110. {
  111. Close();
  112. doorState = DoorState.Locked;
  113. }
  114. else if(doorState == DoorState.LockedOpen)
  115. {
  116. Close();
  117. doorState = DoorState.Locked;
  118. }
  119. break;
  120. case DoorState.LockedOpen:
  121. if(doorState == DoorState.Open) doorState = DoorState.LockedOpen;
  122. else if(doorState == DoorState.Closed || doorState == DoorState.Locked)
  123. {
  124. Open();
  125. doorState = DoorState.LockedOpen;
  126. }
  127. break;
  128. case DoorState.Blocked:
  129. doorState = DoorState.Blocked;
  130. break;
  131. default:
  132. break;
  133. }
  134. }
  135. public void Open()
  136. {
  137. if(doorState == DoorState.Open) return;
  138. StartCoroutine(Animate(doorClosedTransform.position, doorOpenTransform.position));
  139. if(soundEffect != null) SoundController.EmmitSound(soundEffect, doorClosedTransform.position);
  140. }
  141. public void Close()
  142. {
  143. if(doorState == DoorState.Closed) return;
  144. StartCoroutine(Animate(doorOpenTransform.position, doorClosedTransform.position));
  145. if(soundEffect != null) SoundController.EmmitSound(soundEffect, doorOpenTransform.position);
  146. }
  147. IEnumerator Animate(Vector3 start, Vector3 end)
  148. {
  149. inMotion = true;
  150. time = 0f;
  151. while(animationTime > time)
  152. {
  153. float x = Mathf.Lerp(start.x, end.x, time/animationTime);
  154. float y = Mathf.Lerp(start.y, end.y, time/animationTime);
  155. float z = Mathf.Lerp(start.z, end.z, time/animationTime);
  156. doorObject.transform.position = new Vector3(x, y, z);
  157. yield return null;
  158. }
  159. yield return null;
  160. inMotion = false;
  161. }
  162. }
  163. }