cancel
Showing results for 
Search instead for 
Did you mean: 

How do I Transfer Active Interaction From One Object To Another

InfiniteEcho
Explorer

Hi,

I'm using Meta's XR Interaction SDK v66 in Unity and have a situation where I have a Grab Interaction 'pulling' a Build Icon in a Build Menu to initiate the building of the corresponding object in the game world at the point of the Grab Interaction.  So I'd like to programmatically cancel the Grab Interaction on the Build Icon, instantiate a 'real-world' version of that object, and programmatically begin the Grab Interaction on this new object, letting the Player place the built object wherever they would like.  So effectively I want to transfer the Grab from the Icon object to the newly instantiated object.

The documentation for interacting with controllers and hands is great but I haven't been able to find much around initiating interactions exclusively with code.

Any help would be much appreciated.

Thanks!

InfiniteEcho

1 ACCEPTED SOLUTION

Accepted Solutions

InfiniteEcho
Explorer

Alright, figured it out, at least for HandGrab Interactions.

HandGrabInteractables have a property, SelectingInteractors that will have all grabbing HandGrabInteractors in it.  Iterating through these Interactors allows us to modify their selecting states using ForceRelease and ForceSelect.

I ended up with code similar to:

 

public void CreateNewObjectAndTransferGrabToIt() {
    GameObject interactable = Instantiate( NewPrefabToBuild, ... );

    foreach( HandGrabInteractor selectingInteractor in GetComponentInChildren<HandGrabInteractable>().SelectingInteractors ) {
        selectingInteractor.ForceRelease();

        selectingInteractor.ForceSelect( interactable.GetComponentInChildren<HandGrabInteractable>(), true );
    }
}

 

 

In some cases, such as if you're running the code doing the Grab transfer in LateUpdate, you'll need to wait a frame to allow the new Interactable Components to properly instantiate before doing a ForceSelect on them.  In this case, one solution is to create a co-routine.  Also, I found that though the ForceRelease is 'buffered' for a frame so I needed to wait a frame to reset the position of the originally-Grabbed object.

Hope this helps someone out there!

InfiniteEcho

View solution in original post

1 REPLY 1

InfiniteEcho
Explorer

Alright, figured it out, at least for HandGrab Interactions.

HandGrabInteractables have a property, SelectingInteractors that will have all grabbing HandGrabInteractors in it.  Iterating through these Interactors allows us to modify their selecting states using ForceRelease and ForceSelect.

I ended up with code similar to:

 

public void CreateNewObjectAndTransferGrabToIt() {
    GameObject interactable = Instantiate( NewPrefabToBuild, ... );

    foreach( HandGrabInteractor selectingInteractor in GetComponentInChildren<HandGrabInteractable>().SelectingInteractors ) {
        selectingInteractor.ForceRelease();

        selectingInteractor.ForceSelect( interactable.GetComponentInChildren<HandGrabInteractable>(), true );
    }
}

 

 

In some cases, such as if you're running the code doing the Grab transfer in LateUpdate, you'll need to wait a frame to allow the new Interactable Components to properly instantiate before doing a ForceSelect on them.  In this case, one solution is to create a co-routine.  Also, I found that though the ForceRelease is 'buffered' for a frame so I needed to wait a frame to reset the position of the originally-Grabbed object.

Hope this helps someone out there!

InfiniteEcho