How to access what gameobject is inside an XR Socket Interactor?

Hi all,

I’m basically trying to make a coffee shop game in VR (on HTC Vive). Right now, the coffee machine has a lever that, when you pull it, should have the machine pour out coffee in two streams, one for hot coffee and one for cold coffee. I want the machine to detect, when the lever is pulled, which slots have cups set inside them and only activate the streams above those slots.

Right now, to place a cup inside the machine (picture a soda fountain), you just put it close enough to the spot and a socket interactor snaps it into place.

My issue is that I don’t know how to figure out which object is currently in the socket. I’ve looked through the XR Socket Interactor script, but it’s a little hard for me to read, as I’m not very experienced. I need to know if a cup is in the socket or not. I have all the cups tagged as “Cup”. Any help is greatly appreciated!

Thanks!

Check out the documentation for XRBaseInteractor. XRSocketInteractor inherits from it and the functionality you need is located there along with a lot of other useful things. You could access this information by checking if the your cup gameobject is in the XRSocketInteractor.selectTarget property. Another implementation would be to subscribe to the OnSelectEnter and OnSelectExit XRInteractorEvents, you would be able to see which Interactables entered or exited the sockets.

1 Like

Did you find what you were looking for? I want to do the same thing.

XRSocketInteractor.selectTarget from DejaMooo’s answer is now depreciated (Very late 2021). Use
GetOldestInteractableSelected() method as shown. Hope this helps anyone else, took me too long to work it out.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
public class SocketChecking : MonoBehaviour
{
   
    XRSocketInteractor socket;
   
    void Start()
    {
        socket = GetComponent<XRSocketInteractor>();
    }

    public void socketCheck()
    {
       
        IXRSelectInteractable objName = socket.GetOldestInteractableSelected();
       
        Debug.Log(objName.transform.name + " in socket of " + transform.name);
    }
6 Likes

You just saved me have been searching for this for weeks !

1 Like

How do you delete the object in the zone using this method?

For anyone attempting to use this kind of thing to check if a socket is simply occupied and you don’t care about what object is actually selected, you can just check the bool XRSocketInteractor.hasSelection instead.

Bear in mind if you’re using XRGrabInteractable with sockets for a drag and drop game, like I am, there’s a delay of at least a frame before the bool is updated. Using a simple coroutine with a WaitForEndOfFrame sorted this out in my case. Personally, I opted to override the Drop method of the XRGrabInteractable object, so that I could almost instantly check if the referenced XRSocketInteractor was occupied or not.

using UnityEngine;
using System.Collections;
using UnityEngine.XR.Interaction.Toolkit;

public class XRGrabInteractable_Custom : XRGrabInteractable {

    [SerializeField, Tooltip("The XRSocketInteractor to be checked.")]
    private XRSocketInteractor xrSocketInteractor;

    protected override void Drop() {
        base.Drop();
        StartCoroutine(CheckSocket());
    }

    IEnumerator CheckSocket() {
        yield return new WaitForEndOfFrame();
        Debug.Log(xrSocketInteractor.hasSelection);
    }

}
2 Likes

This method gets the Interactor but it doesn’t seem to get the actual GameObject. Has anyone found a way to get an actual GameObject reference?

1 Like

@SecretNerd
What is your script attached to? The Socket itself?

Hey Im not sure if you ever got your answer but this is how you would reference it as a game object.

IXRSelectInteractable screw = socket.GetOldestInteractableSelected();
GameObject screwCol = screw.transform.gameObject;

You have to access it through its transform extension :slight_smile:

Hope that helps!

4 Likes