445 lines
20 KiB
C#
445 lines
20 KiB
C#
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
using Microsoft.MixedReality.Toolkit.Utilities;
|
|
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.Serialization;
|
|
|
|
namespace Microsoft.MixedReality.Toolkit.Input
|
|
{
|
|
[CreateAssetMenu(menuName = "Mixed Reality/Toolkit/Profiles/Mixed Reality Simulated Input Profile", fileName = "MixedRealityInputSimulationProfile", order = (int)CreateProfileMenuItemIndices.InputSimulation)]
|
|
[MixedRealityServiceProfile(typeof(IInputSimulationService))]
|
|
[HelpURL("https://docs.microsoft.com/windows/mixed-reality/mrtk-unity/features/input-simulation/input-simulation-service")]
|
|
public class MixedRealityInputSimulationProfile : BaseMixedRealityProfile
|
|
{
|
|
[SerializeField]
|
|
[Tooltip("Indicator buttons to show input simulation state in the viewport")]
|
|
private GameObject indicatorsPrefab = null;
|
|
/// <summary>
|
|
/// Indicator buttons to show input simulation state in the viewport
|
|
/// </summary>
|
|
public GameObject IndicatorsPrefab => indicatorsPrefab;
|
|
|
|
[Header("Common Input")]
|
|
[SerializeField]
|
|
[Tooltip("Sensitivity when using the mouse for rotation")]
|
|
[FormerlySerializedAs("defaultMouseSensitivity")]
|
|
private float mouseRotationSensitivity = 0.1f;
|
|
/// <summary>
|
|
/// Sensitivity when using the mouse for rotation
|
|
/// </summary>
|
|
public float MouseRotationSensitivity => mouseRotationSensitivity;
|
|
[SerializeField]
|
|
[Tooltip("Mouse Movement X-axis")]
|
|
private string mouseX = "Mouse X";
|
|
/// <summary>
|
|
/// Mouse Movement X-axis
|
|
/// </summary>
|
|
public string MouseX => mouseX;
|
|
[SerializeField]
|
|
[Tooltip("Mouse Movement Y-axis")]
|
|
private string mouseY = "Mouse Y";
|
|
/// <summary>
|
|
/// Mouse Movement Y-axis
|
|
/// </summary>
|
|
public string MouseY => mouseY;
|
|
[SerializeField]
|
|
[Tooltip("Mouse Scroll Wheel")]
|
|
private string mouseScroll = "Mouse ScrollWheel";
|
|
/// <summary>
|
|
/// Mouse Scroll Wheel
|
|
/// </summary>
|
|
public string MouseScroll => mouseScroll;
|
|
[SerializeField]
|
|
[Tooltip("Button pressed to interact with objects")]
|
|
[FormerlySerializedAs("Interaction Button")]
|
|
private KeyBinding interactionButton = KeyBinding.FromMouseButton(KeyBinding.MouseButton.Left);
|
|
/// <summary>
|
|
/// Button pressed to interact with objects
|
|
/// </summary>
|
|
public KeyBinding InteractionButton => interactionButton;
|
|
[SerializeField]
|
|
[Tooltip("Maximum time interval for double press")]
|
|
private float doublePressTime = 0.4f;
|
|
/// <summary>
|
|
/// Maximum time interval for double press
|
|
/// </summary>
|
|
public float DoublePressTime => doublePressTime;
|
|
[SerializeField]
|
|
[Tooltip("Enable hands free input")]
|
|
private bool isHandsFreeInputEnabled = true;
|
|
/// <summary>
|
|
/// Enable hands free input
|
|
/// </summary>
|
|
public bool IsHandsFreeInputEnabled => isHandsFreeInputEnabled;
|
|
|
|
[Header("Camera Control")]
|
|
[SerializeField]
|
|
[Tooltip("Enable manual camera control")]
|
|
private bool isCameraControlEnabled = true;
|
|
/// <summary>
|
|
/// Enable manual camera control
|
|
/// </summary>
|
|
public bool IsCameraControlEnabled => isCameraControlEnabled;
|
|
[SerializeField]
|
|
[Tooltip("Additional rotation factor after input smoothing has been applied")]
|
|
[FormerlySerializedAs("extraMouseSensitivityScale")]
|
|
private float mouseLookSpeed = 3.0f;
|
|
/// <summary>
|
|
/// Additional rotation factor after input smoothing has been applied
|
|
/// </summary>
|
|
public float MouseLookSpeed => mouseLookSpeed;
|
|
[SerializeField]
|
|
[Tooltip("Controls how mouse look control is activated")]
|
|
private KeyBinding mouseLookButton = KeyBinding.FromMouseButton(KeyBinding.MouseButton.Right);
|
|
/// <summary>
|
|
/// Controls how mouse look control is activated
|
|
/// </summary>
|
|
public KeyBinding MouseLookButton => mouseLookButton;
|
|
[SerializeField]
|
|
[Tooltip("Toggle mouse look on with the mouse look button, press escape to release")]
|
|
private bool mouseLookToggle = false;
|
|
/// <summary>
|
|
/// Toggle mouse look on with the mouse look button, press escape to release
|
|
/// </summary>
|
|
public bool MouseLookToggle => mouseLookToggle;
|
|
[SerializeField]
|
|
[Tooltip("Invert the vertical rotation")]
|
|
private bool isControllerLookInverted = true;
|
|
/// <summary>
|
|
/// Invert the vertical rotation
|
|
/// </summary>
|
|
public bool IsControllerLookInverted => isControllerLookInverted;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Amount to offset the starting position of the camera from the origin")]
|
|
private Vector3 cameraOriginOffset = Vector3.zero;
|
|
/// <summary>
|
|
/// Amount to offset the starting position of the camera from the origin
|
|
/// </summary>
|
|
public Vector3 CameraOriginOffset => cameraOriginOffset;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Camera movement mode")]
|
|
private InputSimulationControlMode currentControlMode = InputSimulationControlMode.Fly;
|
|
/// <summary>
|
|
/// Camera movement mode
|
|
/// </summary>
|
|
public InputSimulationControlMode CurrentControlMode => currentControlMode;
|
|
[SerializeField]
|
|
[Tooltip("Key to speed up camera movement")]
|
|
private KeyBinding fastControlKey = KeyBinding.FromKey(KeyCode.RightControl);
|
|
/// <summary>
|
|
/// Key to speed up camera movement
|
|
/// </summary>
|
|
public KeyBinding FastControlKey => fastControlKey;
|
|
[SerializeField]
|
|
[Tooltip("Slow camera translation speed")]
|
|
private float controlSlowSpeed = 0.1f;
|
|
/// <summary>
|
|
/// Slow camera translation speed
|
|
/// </summary>
|
|
public float ControlSlowSpeed => controlSlowSpeed;
|
|
[SerializeField]
|
|
[Tooltip("Fast camera translation speed")]
|
|
private float controlFastSpeed = 1.0f;
|
|
/// <summary>
|
|
/// Fast camera translation speed
|
|
/// </summary>
|
|
public float ControlFastSpeed => controlFastSpeed;
|
|
|
|
// Input axes to coordinate with the Input Manager (Project Settings -> Input)
|
|
|
|
// Horizontal movement string for keyboard and left stick of game controller
|
|
[SerializeField]
|
|
[Tooltip("Horizontal movement Axis ")]
|
|
private string moveHorizontal = "Horizontal";
|
|
/// <summary>
|
|
/// Horizontal movement Axis
|
|
/// </summary>
|
|
public string MoveHorizontal => moveHorizontal;
|
|
// Vertical movement string for keyboard and left stick of game controller
|
|
[SerializeField]
|
|
[Tooltip("Vertical movement Axis ")]
|
|
private string moveVertical = "Vertical";
|
|
/// <summary>
|
|
/// Vertical movement Axis
|
|
/// </summary>
|
|
public string MoveVertical => moveVertical;
|
|
[SerializeField]
|
|
[Tooltip("Up/Down movement Axis ")]
|
|
private string moveUpDown = "UpDown";
|
|
/// <summary>
|
|
/// Up/Down movement Axis
|
|
/// </summary>
|
|
public string MoveUpDown => moveUpDown;
|
|
// Look horizontal string for right stick of game controller
|
|
// The right stick has no default settings in the Input Manager and will need to be setup for a game controller to look
|
|
[SerializeField]
|
|
[Tooltip("Look Horizontal Axis - Right Stick On Controller")]
|
|
private string lookHorizontal = ControllerMappingLibrary.AXIS_4;
|
|
/// <summary>
|
|
/// Look Horizontal Axis - Right Stick On Controller
|
|
/// </summary>
|
|
public string LookHorizontal => lookHorizontal;
|
|
// Look vertical string for right stick of game controller
|
|
[SerializeField]
|
|
[Tooltip("Look Vertical Axis - Right Stick On Controller ")]
|
|
private string lookVertical = ControllerMappingLibrary.AXIS_5;
|
|
/// <summary>
|
|
/// Look Vertical Axis - Right Stick On Controller
|
|
/// </summary>
|
|
public string LookVertical => lookVertical;
|
|
|
|
/// <summary>
|
|
/// Enable eye gaze simulation
|
|
/// </summary>
|
|
[Obsolete("Check the EyeGazeSimulationMode instead")]
|
|
public bool SimulateEyePosition => defaultEyeGazeSimulationMode != EyeGazeSimulationMode.Disabled;
|
|
|
|
[Header("Eye Gaze Simulation")]
|
|
[SerializeField]
|
|
[Tooltip("Enable eye gaze simulation")]
|
|
[FormerlySerializedAs("simulateEyePosition")]
|
|
private EyeGazeSimulationMode defaultEyeGazeSimulationMode = EyeGazeSimulationMode.Disabled;
|
|
|
|
/// <summary>
|
|
/// Enable eye gaze simulation
|
|
/// </summary>
|
|
public EyeGazeSimulationMode DefaultEyeGazeSimulationMode => defaultEyeGazeSimulationMode;
|
|
|
|
[Header("Controller Simulation")]
|
|
[SerializeField]
|
|
[Tooltip("Enable controller simulation")]
|
|
[FormerlySerializedAs("handSimulationMode")]
|
|
[FormerlySerializedAs("defaultHandSimulationMode")]
|
|
private ControllerSimulationMode defaultControllerSimulationMode = ControllerSimulationMode.ArticulatedHand;
|
|
/// <summary>
|
|
/// Enable controller simulation
|
|
/// </summary>
|
|
public ControllerSimulationMode DefaultControllerSimulationMode => defaultControllerSimulationMode;
|
|
|
|
[Header("Controller Control Settings")]
|
|
[SerializeField]
|
|
[Tooltip("Key to toggle persistent mode for the left controller")]
|
|
[FormerlySerializedAs("toggleLeftHandKey")]
|
|
private KeyBinding toggleLeftControllerKey = KeyBinding.FromKey(KeyCode.T);
|
|
/// <summary>
|
|
/// Key to toggle persistent mode for the left controller
|
|
/// </summary>
|
|
public KeyBinding ToggleLeftControllerKey => toggleLeftControllerKey;
|
|
[SerializeField]
|
|
[Tooltip("Key to toggle persistent mode for the right controller")]
|
|
[FormerlySerializedAs("toggleRightHandKey")]
|
|
private KeyBinding toggleRightControllerKey = KeyBinding.FromKey(KeyCode.Y);
|
|
/// <summary>
|
|
/// Key to toggle persistent mode for the right controller
|
|
/// </summary>
|
|
public KeyBinding ToggleRightControllerKey => toggleRightControllerKey;
|
|
[SerializeField]
|
|
[Tooltip("Time after which uncontrolled controllers are hidden")]
|
|
[FormerlySerializedAs("handHideTimeout")]
|
|
private float controllerHideTimeout = 0.2f;
|
|
/// <summary>
|
|
/// Time after which uncontrolled controllers are hidden
|
|
/// </summary>
|
|
public float ControllerHideTimeout => controllerHideTimeout;
|
|
[SerializeField]
|
|
[Tooltip("Key to manipulate the left controller")]
|
|
[FormerlySerializedAs("leftHandManipulationKey")]
|
|
private KeyBinding leftControllerManipulationKey = KeyBinding.FromKey(KeyCode.LeftShift);
|
|
/// <summary>
|
|
/// Key to manipulate the left controller
|
|
/// </summary>
|
|
public KeyBinding LeftControllerManipulationKey => leftControllerManipulationKey;
|
|
[SerializeField]
|
|
[Tooltip("Key to manipulate the right controller")]
|
|
[FormerlySerializedAs("rightHandManipulationKey")]
|
|
private KeyBinding rightControllerManipulationKey = KeyBinding.FromKey(KeyCode.Space);
|
|
/// <summary>
|
|
/// Key to manipulate the right controller
|
|
/// </summary>
|
|
public KeyBinding RightControllerManipulationKey => rightControllerManipulationKey;
|
|
[SerializeField]
|
|
[Tooltip("Additional rotation factor after input smoothing has been applied")]
|
|
[FormerlySerializedAs("mouseHandRotationSpeed")]
|
|
private float mouseControllerRotationSpeed = 6.0f;
|
|
/// <summary>
|
|
/// Additional rotation factor after input smoothing has been applied
|
|
/// </summary>
|
|
public float MouseControllerRotationSpeed => mouseControllerRotationSpeed;
|
|
[SerializeField]
|
|
[Tooltip("Controls how controller rotation is activated")]
|
|
[FormerlySerializedAs("handRotateButton")]
|
|
private KeyBinding controllerRotateButton = KeyBinding.FromKey(KeyCode.LeftControl);
|
|
/// <summary>
|
|
/// Controls how controller rotation is activated
|
|
/// </summary>
|
|
public KeyBinding ControllerRotateButton => controllerRotateButton;
|
|
|
|
[Header("Hand Gesture Settings")]
|
|
[SerializeField]
|
|
[Tooltip("Hand joint pose on first show or reset")]
|
|
private ArticulatedHandPose.GestureId defaultHandGesture = ArticulatedHandPose.GestureId.Open;
|
|
/// <summary>
|
|
/// Hand joint pose on first show or reset
|
|
/// </summary>
|
|
public ArticulatedHandPose.GestureId DefaultHandGesture => defaultHandGesture;
|
|
[SerializeField]
|
|
[Tooltip("Hand joint pose when pressing the left mouse button")]
|
|
private ArticulatedHandPose.GestureId leftMouseHandGesture = ArticulatedHandPose.GestureId.Pinch;
|
|
/// <summary>
|
|
/// Hand joint pose when pressing the left mouse button
|
|
/// </summary>
|
|
public ArticulatedHandPose.GestureId LeftMouseHandGesture => leftMouseHandGesture;
|
|
[SerializeField]
|
|
[Tooltip("Hand joint pose when pressing the middle mouse button")]
|
|
private ArticulatedHandPose.GestureId middleMouseHandGesture = ArticulatedHandPose.GestureId.None;
|
|
/// <summary>
|
|
/// Hand joint pose when pressing the middle mouse button
|
|
/// </summary>
|
|
public ArticulatedHandPose.GestureId MiddleMouseHandGesture => middleMouseHandGesture;
|
|
[SerializeField]
|
|
[Tooltip("Hand joint pose when pressing the right mouse button")]
|
|
private ArticulatedHandPose.GestureId rightMouseHandGesture = ArticulatedHandPose.GestureId.None;
|
|
/// <summary>
|
|
/// Hand joint pose when pressing the right mouse button
|
|
/// </summary>
|
|
public ArticulatedHandPose.GestureId RightMouseHandGesture => rightMouseHandGesture;
|
|
[SerializeField]
|
|
[Tooltip("Gesture interpolation per second")]
|
|
private float handGestureAnimationSpeed = 8.0f;
|
|
/// <summary>
|
|
/// Gesture interpolation per second
|
|
/// </summary>
|
|
public float HandGestureAnimationSpeed => handGestureAnimationSpeed;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Time until hold gesture starts")]
|
|
private float holdStartDuration = 0.5f;
|
|
/// <summary>
|
|
/// Time until hold gesture starts
|
|
/// </summary>
|
|
public float HoldStartDuration => holdStartDuration;
|
|
[SerializeField]
|
|
[Tooltip("The total amount of input source movement that needs to happen to start navigation")]
|
|
[UnityEngine.Serialization.FormerlySerializedAs("manipulationStartThreshold")]
|
|
private float navigationStartThreshold = 0.03f;
|
|
/// <summary>
|
|
/// The total amount of input source movement that needs to happen to start navigation
|
|
/// </summary>
|
|
public float NavigationStartThreshold => navigationStartThreshold;
|
|
|
|
[Header("Controller Placement Settings")]
|
|
[SerializeField]
|
|
[Tooltip("Default distance of the controller from the camera")]
|
|
[FormerlySerializedAs("defaultHandDistance")]
|
|
private float defaultControllerDistance = 0.5f;
|
|
/// <summary>
|
|
/// Default distance of the controller from the camera
|
|
/// </summary>
|
|
public float DefaultControllerDistance => defaultControllerDistance;
|
|
[SerializeField]
|
|
[Tooltip("Depth change when scrolling the mouse wheel")]
|
|
[FormerlySerializedAs("handDepthMultiplier")]
|
|
private float controllerDepthMultiplier = 0.03f;
|
|
/// <summary>
|
|
/// Depth change when scrolling the mouse wheel
|
|
/// </summary>
|
|
public float ControllerDepthMultiplier => controllerDepthMultiplier;
|
|
[SerializeField]
|
|
[Tooltip("Apply random offset to the controller position")]
|
|
[FormerlySerializedAs("handJitterAmount")]
|
|
private float controllerJitterAmount = 0.0f;
|
|
/// <summary>
|
|
/// Apply random offset to the controller position
|
|
/// </summary>
|
|
public float ControllerJitterAmount => controllerJitterAmount;
|
|
|
|
[Header("Motion Controller Settings")]
|
|
[SerializeField]
|
|
[Tooltip("Key to simulate a trigger press (select) on the motion controller")]
|
|
private KeyBinding motionControllerTriggerKey = KeyBinding.FromMouseButton(KeyBinding.MouseButton.Left);
|
|
|
|
/// <summary>
|
|
/// Key to simulate a trigger press (select) on the motion controller
|
|
/// </summary>
|
|
public KeyBinding MotionControllerTriggerKey => motionControllerTriggerKey;
|
|
[SerializeField]
|
|
[Tooltip("Key to simulate a grab on the motion controller")]
|
|
private KeyBinding motionControllerGrabKey = KeyBinding.FromKey(KeyCode.G);
|
|
|
|
/// <summary>
|
|
/// Key to simulate a grab on the motion controller
|
|
/// </summary>
|
|
public KeyBinding MotionControllerGrabKey => motionControllerGrabKey;
|
|
[SerializeField]
|
|
[Tooltip("Key to simulate a menu press on the motion controller")]
|
|
private KeyBinding motionControllerMenuKey = KeyBinding.FromKey(KeyCode.M);
|
|
|
|
/// <summary>
|
|
/// Key to simulate a menu press on the motion controller
|
|
/// </summary>
|
|
public KeyBinding MotionControllerMenuKey => motionControllerMenuKey;
|
|
|
|
#region Obsolete Properties
|
|
/// <summary>
|
|
/// Enable controller simulation
|
|
/// </summary>
|
|
[Obsolete("Use DefaultControllerSimulationMode instead.")]
|
|
public ControllerSimulationMode DefaultHandSimulationMode => DefaultControllerSimulationMode;
|
|
/// <summary>
|
|
/// Key to toggle persistent mode for the left controller
|
|
/// </summary>
|
|
[Obsolete("Use ToggleLeftControllerKey instead.")]
|
|
public KeyBinding ToggleLeftHandKey => ToggleLeftControllerKey;
|
|
/// <summary>
|
|
/// Key to toggle persistent mode for the right controller
|
|
/// </summary>
|
|
[Obsolete("Use ToggleRightControllerKey instead.")]
|
|
public KeyBinding ToggleRightHandKey => ToggleRightControllerKey;
|
|
/// <summary>
|
|
/// Time after which uncontrolled hands are hidden
|
|
/// </summary>
|
|
[Obsolete("Use ControllerHideTimeout instead.")]
|
|
public float HandHideTimeout => ControllerHideTimeout;
|
|
/// <summary>
|
|
/// Key to manipulate the left hand
|
|
/// </summary>
|
|
[Obsolete("Use LeftControllerManipulationKey instead.")]
|
|
public KeyBinding LeftHandManipulationKey => LeftControllerManipulationKey;
|
|
/// <summary>
|
|
/// Key to manipulate the right hand
|
|
/// </summary>
|
|
[Obsolete("Use RightControllerManipulationKey instead.")]
|
|
public KeyBinding RightHandManipulationKey => RightControllerManipulationKey;
|
|
/// <summary>
|
|
/// Additional rotation factor after input smoothing has been applied
|
|
/// </summary>
|
|
[Obsolete("Use MouseControllerRotationSpeed instead.")]
|
|
public float MouseHandRotationSpeed => MouseControllerRotationSpeed;
|
|
/// <summary>
|
|
/// Controls how hand rotation is activated
|
|
/// </summary>
|
|
[Obsolete("Use ControllerRotateButton instead.")]
|
|
public KeyBinding HandRotateButton => ControllerRotateButton;
|
|
/// <summary>
|
|
/// Default distance of the hand from the camera
|
|
/// </summary>
|
|
[Obsolete("Use DefaultControllerDistance instead.")]
|
|
public float DefaultHandDistance => DefaultControllerDistance;
|
|
/// <summary>
|
|
/// Depth change when scrolling the mouse wheel
|
|
/// </summary>
|
|
[Obsolete("Use ControllerDepthMultiplier instead.")]
|
|
public float HandDepthMultiplier => ControllerDepthMultiplier;
|
|
/// <summary>
|
|
/// Apply random offset to the hand position
|
|
/// </summary>
|
|
[Obsolete("Use ControllerJitterAmount instead.")]
|
|
public float HandJitterAmount => ControllerJitterAmount;
|
|
#endregion
|
|
}
|
|
}
|