I am trying to migrate my Unity project from MRTK2 to MRTK3 and running into some problems.
Background
I wrote a script to show or hide an object depending on how far the hands are from it. To make this easy for multiple objects, I do it through the code in a script rather than using drag and drop in the Inspector. I also want to be able to move the object by grabbing it when it gets visible. Based on the Documentation i first tried to add an MRTKBaseInteractable and an ObjectManipulator. I later found out that this is not possible as in the ObjectManipulator are already the Events from the MRTKBaseInteractable and the second instance gets ignored (?). So now i just add an ObjectManipulator and want to add listeners for Grab entered (started) and exited (released).
In MRTK2 i just could do
var onGrabReceiver = interactable.AddReceiver<InteractableOnGrabReceiver>();
onGrabReceiver.OnGrab.AddListener(() => OnGrab());
onGrabReceiver.OnRelease.AddListener(() => OnGrabRelease());
But with the new system this is not possible. No everything is more generic (just Select and hover,..) and based on XRBaseInteractable.
Question
How can I create a grab listener from the ObjectManipulator component using a script? I want to detect when a grab starts and ends and define a method to do something when the events are detected. But i do not understand how to get from ObjectManipulator to MRTKBaseInteractable to the "Is Grab Selected"->"On Entered" Event.
I am trying to migrate my Unity project from MRTK2 to MRTK3 and running into some problems.
Background
I wrote a script to show or hide an object depending on how far the hands are from it. To make this easy for multiple objects, I do it through the code in a script rather than using drag and drop in the Inspector. I also want to be able to move the object by grabbing it when it gets visible. Based on the Documentation i first tried to add an MRTKBaseInteractable and an ObjectManipulator. I later found out that this is not possible as in the ObjectManipulator are already the Events from the MRTKBaseInteractable and the second instance gets ignored (?). So now i just add an ObjectManipulator and want to add listeners for Grab entered (started) and exited (released).
In MRTK2 i just could do
var onGrabReceiver = interactable.AddReceiver<InteractableOnGrabReceiver>();
onGrabReceiver.OnGrab.AddListener(() => OnGrab());
onGrabReceiver.OnRelease.AddListener(() => OnGrabRelease());
But with the new system this is not possible. No everything is more generic (just Select and hover,..) and based on XRBaseInteractable.
Question
How can I create a grab listener from the ObjectManipulator component using a script? I want to detect when a grab starts and ends and define a method to do something when the events are detected. But i do not understand how to get from ObjectManipulator to MRTKBaseInteractable to the "Is Grab Selected"->"On Entered" Event.
Share Improve this question asked Feb 6 at 14:55 AlexAlex 15313 bronze badges 1 |1 Answer
Reset to default 0The ObjectManipulator component inherits from an MRTKBaseInteractable. When you add an ObjectManipulator to a GameObject, it is already an interactable object. It make use of the underlying MRTKBaseInteractable functionality to respond events like grab, hover. Therefore, you don’t need an extra MRTKBaseInteractable component on same object. You can directly get an MRTKBaseInteractable from a game object with ObjectManipulator component in your script.
public class GrabListener : MonoBehaviour
{
private MRTKBaseInteractable interactable;
void Start()
{
interactable = GetComponent<MRTKBaseInteractable>();
if (interactable != null)
{
interactable.selectEntered.AddListener(OnGrab);
interactable.selectExited.AddListener(OnGrabRelease);
}
}
private void OnGrab(SelectEnterEventArgs args)
{
Debug.Log("MRTKBaseInteractable: Object grabbed!");
// ...
}
private void OnGrabRelease(SelectExitEventArgs args)
{
Debug.Log("MRTKBaseInteractable: Object released!");
// ...
}
private void OnDestroy()
{
if (interactable != null)
{
interactable.selectEntered.RemoveListener(OnGrab);
interactable.selectExited.RemoveListener(OnGrabRelease);
}
}
}
ObjectManipulator
IS anMRTKBaseInteractable
! SeeInheritance UnityEngine.XR.Interaction.Toolkit.XRBaseInteractable -> MRTKBaseInteractable -> StatefulInteractable -> ObjectManipulator
– derHugo Commented Feb 6 at 19:35