diff --git a/Assets/Prefabs/LabSpace.prefab b/Assets/Prefabs/LabSpace.prefab index 31cf66d..9405438 100644 --- a/Assets/Prefabs/LabSpace.prefab +++ b/Assets/Prefabs/LabSpace.prefab @@ -244,6 +244,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 8075794149781177989, guid: 1c45490f0e14d4e9c8930009b4ed7108, type: 3} + propertyPath: lockedLayerMask.m_Bits + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] diff --git a/Assets/Scripts/Interactions/Filters/XRInteractableLockingFilter.cs b/Assets/Scripts/Interactions/Filters/XRInteractableLockingFilter.cs index 9b7aaa6..2d0873a 100644 --- a/Assets/Scripts/Interactions/Filters/XRInteractableLockingFilter.cs +++ b/Assets/Scripts/Interactions/Filters/XRInteractableLockingFilter.cs @@ -1,5 +1,7 @@ /// Traken from https://forum.unity.com/threads/how-to-prevent-interactable-from-being-selected-while-in-socket.1317246/#post-9101254 +using System; +using Sirenix.OdinInspector; using UnityEngine.Assertions; using UnityEngine.Serialization; @@ -11,18 +13,27 @@ namespace UnityEngine.XR.Interaction.Toolkit.Filtering #region Fields [Tooltip("The interactor that this filter is associated with. If none, will attempt to find on self.")] - [SerializeField] - private XRBaseInteractable interactable; - - [FormerlySerializedAs("m_locked")] [SerializeField] - private bool isLocked = false; + [SerializeField] private XRBaseInteractable interactable; + [FormerlySerializedAs("m_locked")] + [SerializeField] private bool isLocked = false; + + [SerializeField] private InteractionLayerMask unlockedLayerMask = 1 << 0; // Default value is "Default" layer + #endregion #region Properties - - public bool IsLocked { get => isLocked; set => isLocked = value; } - + + public bool IsLocked + { + get => isLocked; + set + { + isLocked = value; + UpdateInteractionLayerMask(); + } + } + public bool canProcess => true; #endregion @@ -34,59 +45,49 @@ namespace UnityEngine.XR.Interaction.Toolkit.Filtering interactable = interactable ? interactable : GetComponent(); Assert.IsNotNull(interactable); } - + private void OnEnable() { - AddFilters(); + UpdateInteractionLayerMask(); } - - private void OnDisable() - { - RemoveFilters(); - } - - private void AddFilters() - { - if (interactable == null) return; - - // Add filter to interactable - interactable.startingHoverFilters.Add(this); - interactable.startingSelectFilters.Add(this); - - // Make extra sure that the filter is added to the interactable - interactable.hoverFilters.Add(this); - interactable.selectFilters.Add(this); - } - - private void RemoveFilters() - { - if (interactable == null) return; - - // Remove filter from interactable - interactable.startingHoverFilters.Remove(this); - interactable.startingSelectFilters.Remove(this); - interactable.hoverFilters.Remove(this); - interactable.selectFilters.Remove(this); - } - + public bool Process(IXRHoverInteractor interactor, IXRHoverInteractable interactable) { return Process(); } - + public bool Process(IXRSelectInteractor interactor, IXRSelectInteractable interactable) { return Process(); } - + private bool Process() { - if (interactable == null) - return false; - - return !isLocked; + UpdateInteractionLayerMask(); + + return canProcess; } - + + private void UpdateInteractionLayerMask() + { + if (interactable == null) + { + Debug.LogError($"Interactable is null on {gameObject.name}"); + return; + } + + if (IsLocked) + { + // Remove layer from interactable + interactable.interactionLayers &= ~unlockedLayerMask; + } + else + { + // Add layer to interactable + interactable.interactionLayers |= unlockedLayerMask; + } + } + #endregion } } \ No newline at end of file