Search code examples
c#unity-game-enginemrtk

Accessing VR Controller GameObject references in MRTK 2?


I'm currently working on an application where I need to stick some objects on the user's motion controllers but I can't seem to find a way to obtain the references.

Coming from VRTK which had GameObjects exposed outside of run time, this is proving to be a bit of a challenge for me. Is there a better way of doing this on MRTK?


Solution

  • To get the "proxy" game object for a controller, you can use the code down below (see the first part of it, which uses the visualizer's proxy game object).

    It's also possible to get pointer's game object (note that a given controller may have many pointers)

    If some of this terminology is confusing, I would also recommend having a read of this: https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/Architecture/InputSystem/Terminology.html

    Which explains some of the terms being used and how they relate to each other.

    using Microsoft.MixedReality.Toolkit;
    using Microsoft.MixedReality.Toolkit.Input;
    using UnityEngine;
    
    public class ControllerPointers : MonoBehaviour
    {
       private IMixedRealityInputSystem inputSystem = null;
    
       /// <summary>
       /// The active instance of the input system.
       /// </summary>
       protected IMixedRealityInputSystem InputSystem
       {
           get
           {
               if (inputSystem == null)
               {
                   MixedRealityServiceRegistry.TryGetService<IMixedRealityInputSystem>(out inputSystem);
               }
               return inputSystem;
           }
       }
    
       // Update is called once per frame
       void Update()
       {
           // Log something every 60 frames.
           if (Time.frameCount % 60 == 0)
           {
               foreach (IMixedRealityController controller in InputSystem.DetectedControllers)
               {
                   if (controller.Visualizer?.GameObjectProxy != null)
                   {
                       Debug.Log("Visualizer Game Object: " + controller.Visualizer.GameObjectProxy);
                   }
                   else
                   {
                       Debug.Log("Controller has no visualizer!");
                   }
    
    
                   foreach (IMixedRealityPointer pointer in controller.InputSource.Pointers)
                   {
                       if (pointer is MonoBehaviour)
                       {
                           var monoBehavior = pointer as MonoBehaviour;
                           Debug.Log("Found pointer game object: " + (monoBehavior.gameObject));
                       }
                   }
               }
           }
       }
    }
    

    Lastly, you could also always grab the position/rotation/velocity properties off of the pointer interfaces themselves (i.e. in the code above, use the pointer position: https://microsoft.github.io/MixedRealityToolkit-Unity/api/Microsoft.MixedReality.Toolkit.Input.IMixedRealityPointer.html#Microsoft_MixedReality_Toolkit_Input_IMixedRealityPointer_Position)