Search code examples
unity-game-enginemrtkwindows-mixed-reality

Controlling Main Camera with xBox Controller (MRTK & Unity)


Hi we (myself and my students) are using MRTK in Unity to build simple VR games.

We are trying to get the xBox Controller to move the player (or in MRTK terms I think to move the scene around the camera which is fixed at 0,0,0).

I've set up the controller and played with the MRTK settings but no luck.

My controller works perfectly in Windows Mixed Reality Portal but goes dead when the game loads.

Any help on the exact steps/settings in the MRTK editor window is appreciated.

Ben


Solution

  • There are two things to solve here:

    1. How to move the player. Answer: Use MixedRealityPlayspace.Transform.Translate
    2. How to respond to gamepad input. Answer: you can use Unity's Input.GetAxis to figure out which buttons / joysticks are pressed, however I found it a bit easier to use the controller mappings in MRTK to map the "navigation action" to the gamepad dpad and joysticks, and then listen for input changed on navigation events.

    You can use the following code to move the MR Playspace using gamepad:

    using Microsoft.MixedReality.Toolkit;
    using Microsoft.MixedReality.Toolkit.Input;
    using Microsoft.MixedReality.Toolkit.Utilities;
    using UnityEngine;
    
    /// <summary>
    /// Moves the player around the world using the gamepad, or any other input action that supports 2D axis.
    /// 
    /// We extend InputSystemGlobalHandlerListener because we always want to listen for the gamepad joystick position
    /// We implement InputHandler<Vector2> interface in order to receive the 2D navigation action events.
    /// </summary>
    public class MRPlayspaceMover : InputSystemGlobalHandlerListener, IMixedRealityInputHandler<Vector2>
    {
        public MixedRealityInputAction navigationAction;
        public float multiplier = 5f;
    
        private Vector3 delta = Vector3.zero;
        public void OnInputChanged(InputEventData<Vector2> eventData)
        {
            float horiz = eventData.InputData.x;
            float vert = eventData.InputData.y;
            if (eventData.MixedRealityInputAction == navigationAction)
            {
                delta = CameraCache.Main.transform.TransformDirection(new Vector3(horiz, 0, vert) * multiplier);
            }
        }
    
        public void Update()
        {
            if (delta.sqrMagnitude > 0.01f)
            {
                MixedRealityPlayspace.Transform.Translate(delta);
            }
        }
    
        protected override void RegisterHandlers()
        {
            CoreServices.InputSystem.RegisterHandler<MRPlayspaceMover>(this);
        }
    
        protected override void UnregisterHandlers()
        {
            CoreServices.InputSystem.UnregisterHandler<MRPlayspaceMover>(this);
        }
    }
    

    I used the following controller mapping to have dpad and thumbstick hook up to the navigation action: enter image description here

    Then I created a new gameobject, attached the MRPlayspaceMover script, and assigned the "navigation action" field:

    enter image description here