LinkedObjectSystem.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. using UdonSharp;
  2. using UnityEngine;
  3. using UnityEngine.Rendering;
  4. using VRC.SDKBase;
  5. using VRC.Udon;
  6. [DisallowMultipleComponent]
  7. [AddComponentMenu("Artyom Scripting System/Linked Object System")]
  8. public class LinkedObjectSystem : UdonSharpBehaviour
  9. {
  10. [Header("Script Settings\n")]
  11. [Tooltip("Print all variables to console for debug purposes")]
  12. public bool debugMode;
  13. [Tooltip("Delay for Temporarty interact, ignore if not needed")]
  14. public float delayedInteractTime = 0f;
  15. public LayerMask excludeLayers;
  16. [Header("Interactions Settings\n")]
  17. [Tooltip("Trigger behavior type")]
  18. public TriggerType triggerType = TriggerType.None;
  19. [Tooltip("Interact via select type")]
  20. public InteractionType interactionType = InteractionType.None;
  21. [Header("Animator Links (bool only)\n")]
  22. public Animator[] outputAnimators;
  23. public string[] outputParameterNames;
  24. [Space]
  25. public GameObject audioObjectTrue;
  26. public GameObject audioObjectFalse;
  27. // PRIVATE VARS
  28. private bool playerTriggerEnabled = false;
  29. private bool pickupTriggerEnabled = false;
  30. [UdonSynced]
  31. private int isOccupied;
  32. private float timer;
  33. void Start()
  34. {
  35. isOccupied = 0;
  36. if (triggerType == TriggerType.BothPlayerAndObject)
  37. {
  38. playerTriggerEnabled = true;
  39. pickupTriggerEnabled = true;
  40. }
  41. else if (triggerType == TriggerType.Player)
  42. {
  43. playerTriggerEnabled = true;
  44. pickupTriggerEnabled = false;
  45. }
  46. else if (triggerType == TriggerType.Object)
  47. {
  48. playerTriggerEnabled = false;
  49. pickupTriggerEnabled = true;
  50. }
  51. if (interactionType == InteractionType.None)
  52. {
  53. DisableInteractive = true;
  54. }
  55. }
  56. private void Update()
  57. {
  58. if (interactionType == InteractionType.Temporary && isOccupied == 1)
  59. {
  60. if (debugMode) Debug.Log("Linked Object System: Interaction Type Checked As Temprary");
  61. if (timer < delayedInteractTime)
  62. {
  63. isOccupied = 1;
  64. if (debugMode) Debug.LogWarning("LOS: Logged isOccupied as " + isOccupied.ToString());
  65. timer += Time.deltaTime;
  66. if (debugMode) Debug.Log("Linked Object System: DeltaTime Update, New Value -> " + timer.ToString());
  67. }
  68. else if (timer >= delayedInteractTime)
  69. {
  70. isOccupied = 0;
  71. if (debugMode) Debug.LogWarning("LOS: Logged isOccupied as " + isOccupied.ToString());
  72. UpdateAnims(false);
  73. timer = 0f;
  74. }
  75. }
  76. }
  77. private void UpdateAnims(bool state)
  78. {
  79. for (int i = 0; i < outputAnimators.Length; i++)
  80. {
  81. outputAnimators[i].SetBool(outputParameterNames[i], state);
  82. }
  83. // Enable or disable GameObjects based on the state
  84. if (audioObjectFalse != null && audioObjectTrue != null)
  85. {
  86. if (!state)
  87. {
  88. if (debugMode) Debug.Log("Linked Object System: GameObject set audio to false");
  89. audioObjectFalse.SetActive(true);
  90. audioObjectTrue.SetActive(false);
  91. }
  92. else
  93. {
  94. if (debugMode) Debug.Log("Linked Object System: GameObject set audio to true");
  95. audioObjectTrue.SetActive(true);
  96. audioObjectFalse.SetActive(false);
  97. }
  98. }
  99. }
  100. private void OnTriggerEnter(Collider other)
  101. {
  102. if (pickupTriggerEnabled && other.GetComponent<VRC_Pickup>())
  103. {
  104. isOccupied++;
  105. if (debugMode) Debug.Log("Linked Object System: Pickup set trigger to " + isOccupied.ToString());
  106. if (isOccupied > 0 && isOccupied <=2)
  107. {
  108. UpdateAnims(true);
  109. }
  110. }
  111. }
  112. public override void OnPlayerTriggerEnter(VRCPlayerApi player)
  113. {
  114. if (playerTriggerEnabled)
  115. {
  116. isOccupied++;
  117. if (debugMode) Debug.Log("Linked Object System: Player set trigger to " + isOccupied.ToString());
  118. if (isOccupied > 0 && isOccupied <=2)
  119. {
  120. UpdateAnims(true);
  121. }
  122. }
  123. }
  124. private void OnTriggerExit(Collider other)
  125. {
  126. if (pickupTriggerEnabled)
  127. {
  128. VRC_Pickup pickup = other.GetComponent<VRC_Pickup>();
  129. if (pickup != null)
  130. {
  131. isOccupied--;
  132. if (debugMode) Debug.Log("Linked Object System: Pickup set trigger to " + isOccupied.ToString());
  133. if (isOccupied == 0)
  134. {
  135. UpdateAnims(false);
  136. }
  137. }
  138. }
  139. }
  140. public override void OnPlayerTriggerExit(VRCPlayerApi player)
  141. {
  142. if (playerTriggerEnabled)
  143. {
  144. isOccupied--;
  145. if (debugMode) Debug.Log("Linked Object System: Player set trigger to " + isOccupied.ToString());
  146. if (isOccupied == 0)
  147. {
  148. UpdateAnims(false);
  149. }
  150. }
  151. }
  152. public override void Interact()
  153. {
  154. if (interactionType.Equals(InteractionType.Permanent))
  155. {
  156. isOccupied++;
  157. if (isOccupied == 1)
  158. {
  159. UpdateAnims(true);
  160. }
  161. }
  162. if (interactionType.Equals(InteractionType.Temporary))
  163. {
  164. if (isOccupied == 0)
  165. {
  166. isOccupied = 1;
  167. if (debugMode) Debug.LogWarning("LOS: Logged isOccupied as " + isOccupied.ToString());
  168. UpdateAnims(true);
  169. UdonBehaviour behaviour = (UdonBehaviour)GetComponent(typeof(UdonBehaviour));
  170. behaviour.DisableInteractive = true;
  171. SendCustomEventDelayedSeconds(nameof(DisableTemp), delayedInteractTime+0.2f);
  172. }
  173. }
  174. if (interactionType.Equals(InteractionType.Toggle))
  175. {
  176. if (isOccupied == 1) {
  177. isOccupied = 0;
  178. UpdateAnims(false);
  179. }
  180. else {
  181. isOccupied = 1;
  182. UpdateAnims(true);
  183. }
  184. }
  185. }
  186. public void DisableTemp()
  187. {
  188. UdonBehaviour behaviour = (UdonBehaviour)GetComponent(typeof(UdonBehaviour));
  189. behaviour.DisableInteractive = false;
  190. isOccupied = 0;
  191. if (debugMode) Debug.LogWarning("LOS: Logged isOccupied as " + isOccupied.ToString());
  192. }
  193. }
  194. public enum InteractionType
  195. {
  196. None,
  197. Permanent,
  198. Temporary,
  199. Toggle
  200. }
  201. public enum TriggerType
  202. {
  203. None,
  204. Player,
  205. Object,
  206. BothPlayerAndObject
  207. }