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!
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.
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);
}
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);
}
}