BUGFIX: Fix for the InteractableLockingFilter blocking everything (including physics??) driven via the GrabInteractable when "locked"

This commit is contained in:
Brown, Caleb M 2023-12-15 12:13:25 -05:00
parent 45bb69ff56
commit 0882c6e866
2 changed files with 52 additions and 47 deletions

View File

@ -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: []

View File

@ -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<XRBaseInteractable>();
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
}
}