cancel
Showing results for 
Search instead for 
Did you mean: 

Oculus interactions SDK experimental grab force release (Unity)

akulyhin
Honored Guest

I am trying to develop a VR app with Unity for Oculus Quest 2. 

Is there a way to perform force release of currently grabbed objects?

I've tried with interactor's Unselect() method but after that grab becomes imposible sometimes, i.e. I can't grab objects with current hand anymore. 

1 ACCEPTED SOLUTION

Accepted Solutions

WolffRuoff
Explorer

You need to have the gameobject with the interactor on it in your script (usually called HandGrabInteractor or something along those lines. Once you do, use this line:

sampleGameObject.GetComponent<IInteractor>().Unselect()

View solution in original post

4 REPLIES 4

WolffRuoff
Explorer

You need to have the gameobject with the interactor on it in your script (usually called HandGrabInteractor or something along those lines. Once you do, use this line:

sampleGameObject.GetComponent<IInteractor>().Unselect()

SanCity
Protege

Just some rubber-ducking. Realised I hadn't updated since v34 (now v40). But maybe relevant to someone else:

Not sure if Oculus has changed this function, but now you can't just run Unselect() due to some null flag checks (a private flag named ShouldUnselect (this is removed in v40) must be true, and the state must be InteractorState.Select.

But inside there is a private function named UnselectInteractable. You could just change it to public, but that will be removed when you uprate the plugin. A way simpler (but maybe not that performant) is to disable the entire game object (in the latests example it's a couple of HandGrabInteractorLeft/Right, on for each controller AND hand, if you're using hand tracking)

But must be a better way to do this. Feels like this should be handled from the item being interacted with, rather then the controller/hand.

Started to search for a solution by looking in the PointableElement class, but always got stuck in private or protected variables.

What I did understand, is that when you grab a Grabbable, your will create points (actually you create them as soon as you're inside some trigger zone), ex a point with id -233332081 for my left hand's pinch fingers. If you would also move my other hand, it would create another point for that hand.

So theoretically I could try to find this unique id, and send it direcly to the Grabbable class using the ProcessPointerEvent, ex:

 

 

PointerArgs args = new PointerArgs( THE_UNIQUE_ID, PointerEvent.Unselect, Pose.identity);
grabbable.ProcessPointerEvent(new PointerArgs(args.Identifier, args.PointerEvent, args.Pose));

 


The problem here is that I can't find a way to get this point´s unique id. It's stored in a protected List called _pointsIds (visible in the Inspector when using debug mode).

So has anyone solved this using Oculus Interaction SDK v34 (have also tried upgrading to v40)?

Digging into the Grabbable now in v40 there is a WhenPointerEventRaised in the lowest IPointable.class that is inherited in all subclasses. So I ended up not force releasing at all, but instead just detecting if the grabbable object is grabed or not, and then use a mesh offset to handle everything else. Works in my usecase.

    public Grabbable grabbable;
    
    private void OnEnable()
    {
        grabbable.WhenPointerEventRaised += OnPointerEvent;
    }
    private void OnDisable()
    {
        grabbable.WhenPointerEventRaised -= OnPointerEvent;
    }

    private void OnPointerEvent(PointerArgs args)
    {
        switch (args.PointerEvent)
        {
            case PointerEvent.Select:
                Debug.Log("Select");
                break;
            case PointerEvent.Unselect:
                Debug.Log("Unselect");
                break;
            default:
                return;
        }
    }


Thanks for the rubber-ducking internet.

AdamChojaczyk
Honored Guest

SanCity Your sollution

PointerArgs args = new PointerArgs( THE_UNIQUE_ID, PointerEvent.Unselect, Pose.identity);
grabbable.ProcessPointerEvent(new PointerArgs(args.Identifier, args.PointerEvent, args.Pose));

 works fine.

 

I've put in directly in Grabbable class within new method called ForceUnselect() so I can access protected lists.

To avoid risk of disposing changes with new package updates You can create new class that inherits from Grabbable and has only this new method.

Shizola
Honored Guest

Can Meta add a built-in solution to this please.