ToggleComponentZone.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. using System.Collections.Generic;
  2. namespace UnityEngine.XR.Interaction.Toolkit.Samples.StarterAssets
  3. {
  4. /// <summary>
  5. /// This component is designed to easily toggle a specific component and GameObject on or off when an object
  6. /// enters the specified <see cref="triggerVolume"/>.
  7. /// </summary>
  8. [RequireComponent(typeof(Collider))]
  9. public class ToggleComponentZone : MonoBehaviour
  10. {
  11. [SerializeField]
  12. [Tooltip("Collider that will trigger the component to turn on or off when entering the Trigger Volume. Must have a Rigidbody component and be on the same physics layer as the Trigger Volume.")]
  13. Collider m_ActivationObject;
  14. /// <summary>
  15. /// Collider that will trigger the component to turn on or off when entering the Trigger Volume.
  16. /// Must have a Rigidbody component and be on the same physics layer as the Trigger Volume.
  17. /// </summary>
  18. public Collider activationObject
  19. {
  20. get => m_ActivationObject;
  21. set => m_ActivationObject = value;
  22. }
  23. [SerializeField]
  24. [Tooltip("Sets whether to enable or disable the Component To Toggle and GameObject To Toggle upon entry into the Trigger Volume.")]
  25. bool m_EnableOnEntry = true;
  26. /// <summary>
  27. /// Sets whether to enable or disable the Component To Toggle and GameObject To Toggle upon entry into the Trigger Volume.
  28. /// </summary>
  29. public bool enableOnEntry
  30. {
  31. get => m_EnableOnEntry;
  32. set => m_EnableOnEntry = value;
  33. }
  34. [SerializeField]
  35. [Tooltip("Components to set the enabled state for. Will set the value to the Enable On Entry value upon entry and revert to original value on exit.")]
  36. List<Behaviour> m_ComponentsToToggle = new List<Behaviour>();
  37. /// <summary>
  38. /// Component to set the enabled state for. Will set the value to the
  39. /// Enable On Entry value upon entry and revert to original value on exit.
  40. /// </summary>
  41. public List<Behaviour> componentsToToggle
  42. {
  43. get => m_ComponentsToToggle;
  44. set => m_ComponentsToToggle = value;
  45. }
  46. [SerializeField]
  47. [Tooltip("Array of GameObjects to set the enabled state for. Will set the value to the Enable On Entry value upon entry and revert to original value on exit.")]
  48. List<GameObject> m_GameObjectsToToggle = new List<GameObject>();
  49. /// <summary>
  50. /// GameObject to set the enabled state for. Will set the value to the
  51. /// Enable On Entry value upon entry and revert to original value on exit.
  52. /// </summary>
  53. public List<GameObject> gameObjectsToToggle
  54. {
  55. get => m_GameObjectsToToggle;
  56. set => m_GameObjectsToToggle = value;
  57. }
  58. Collider m_TriggerVolume;
  59. Dictionary<Behaviour, bool> m_InitialComponentStateOnEntry;
  60. Dictionary<GameObject, bool> m_InitialGameObjectStateOnEntry;
  61. /// <summary>
  62. /// See <see cref="MonoBehaviour"/>.
  63. /// </summary>
  64. void Start()
  65. {
  66. if (m_TriggerVolume == null && !TryGetComponent(out m_TriggerVolume))
  67. {
  68. enabled = false;
  69. return;
  70. }
  71. if (!m_TriggerVolume.isTrigger)
  72. {
  73. m_TriggerVolume.isTrigger = true;
  74. Debug.LogWarning($"Trigger Volume \"{m_TriggerVolume}\" was not set as trigger, which the Toggle Component Zone expects. It has been forced to be a trigger.", this);
  75. }
  76. }
  77. /// <summary>
  78. /// See <see cref="MonoBehaviour"/>.
  79. /// </summary>
  80. void OnTriggerEnter(Collider other)
  81. {
  82. if (other == null || other != m_ActivationObject)
  83. return;
  84. // Save the target GameObject(s) active state to restore when leaving the zone
  85. if (m_GameObjectsToToggle != null && m_GameObjectsToToggle.Count > 0)
  86. {
  87. m_InitialGameObjectStateOnEntry ??= new Dictionary<GameObject, bool>(m_GameObjectsToToggle.Count);
  88. m_InitialGameObjectStateOnEntry.Clear();
  89. for (var i = 0; i < m_GameObjectsToToggle.Count; ++i)
  90. {
  91. var target = m_GameObjectsToToggle[i];
  92. m_InitialGameObjectStateOnEntry.Add(target, target.activeSelf);
  93. target.SetActive(m_EnableOnEntry);
  94. }
  95. }
  96. // Save the target component(s) enabled state to restore when leaving the zone
  97. if (m_ComponentsToToggle != null && m_ComponentsToToggle.Count > 0)
  98. {
  99. m_InitialComponentStateOnEntry ??= new Dictionary<Behaviour, bool>(m_ComponentsToToggle.Count);
  100. m_InitialComponentStateOnEntry.Clear();
  101. for (var i = 0; i < m_ComponentsToToggle.Count; ++i)
  102. {
  103. var target = m_ComponentsToToggle[i];
  104. m_InitialComponentStateOnEntry.Add(target, target.enabled);
  105. target.enabled = m_EnableOnEntry;
  106. }
  107. }
  108. }
  109. /// <summary>
  110. /// See <see cref="MonoBehaviour"/>.
  111. /// </summary>
  112. void OnTriggerExit(Collider other)
  113. {
  114. if (other == null || other != m_ActivationObject)
  115. return;
  116. // Restore original target component(s) enabled state
  117. if (m_ComponentsToToggle != null && m_ComponentsToToggle.Count > 0 && m_InitialComponentStateOnEntry != null)
  118. {
  119. if (m_InitialComponentStateOnEntry.Count == m_ComponentsToToggle.Count)
  120. {
  121. for (var i = 0; i < m_ComponentsToToggle.Count; ++i)
  122. {
  123. var component = m_ComponentsToToggle[i];
  124. if (m_InitialComponentStateOnEntry.TryGetValue(component, out var initialState))
  125. component.enabled = initialState;
  126. }
  127. }
  128. else
  129. {
  130. Debug.LogWarning("List of Components to Toggle changed in count between entering and exiting the Trigger Volume," +
  131. " which is not supported by this component. Cannot restore original enabled state.", this);
  132. }
  133. }
  134. // Restore original target GameObject(s) active state
  135. if (m_GameObjectsToToggle != null && m_GameObjectsToToggle.Count > 0 && m_InitialGameObjectStateOnEntry != null)
  136. {
  137. if (m_InitialGameObjectStateOnEntry.Count == m_GameObjectsToToggle.Count)
  138. {
  139. for (var i = 0; i < m_GameObjectsToToggle.Count; ++i)
  140. {
  141. var go = m_GameObjectsToToggle[i];
  142. if (m_InitialGameObjectStateOnEntry.TryGetValue(go, out var initialState))
  143. go.SetActive(initialState);
  144. }
  145. }
  146. else
  147. {
  148. Debug.LogWarning("List of GameObjects to Toggle changed in count between entering and exiting the Trigger Volume," +
  149. " which is not supported by this component. Cannot restore original active state.", this);
  150. }
  151. }
  152. }
  153. }
  154. }