794 lines
41 KiB
C#
794 lines
41 KiB
C#
// Copyright (c) Microsoft Corporation.
|
||
// Licensed under the MIT License.
|
||
|
||
using Microsoft.MixedReality.Toolkit.Input;
|
||
using Microsoft.MixedReality.Toolkit.Input.Editor;
|
||
using Microsoft.MixedReality.Toolkit.Utilities;
|
||
using Microsoft.MixedReality.Toolkit.Utilities.Editor;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
|
||
namespace Microsoft.MixedReality.Toolkit.Editor
|
||
{
|
||
public class ControllerPopupWindow : EditorWindow
|
||
{
|
||
// Inspectors/Data/EditorWindowOptions.json
|
||
private const string EditorWindowOptionsGuid = "28091d5ea9b5739419a221a06fa1ec89";
|
||
private const float InputActionLabelWidth = 128f;
|
||
|
||
/// <summary>
|
||
/// Used to enable editing the input axis label positions on controllers.
|
||
/// </summary>
|
||
private static readonly bool EnableWysiwyg = false;
|
||
|
||
private static readonly GUIContent InteractionAddButtonContent = new GUIContent("+ Add a New Interaction Mapping");
|
||
private static readonly GUIContent InteractionMinusButtonContent = new GUIContent("-", "Remove Interaction Mapping");
|
||
private static readonly GUIContent AxisTypeContent = new GUIContent("Axis Type", "The axis type of the button, e.g. Analogue, Digital, etc.");
|
||
private static readonly GUIContent ControllerInputTypeContent = new GUIContent("Input Type", "The primary action of the input as defined by the controller SDK.");
|
||
private static readonly GUIContent ActionContent = new GUIContent("Action", "Action to be raised to the Input Manager when the input data has changed.");
|
||
private static readonly GUIContent KeyCodeContent = new GUIContent("KeyCode", "Unity Input KeyCode id to listen for.");
|
||
private static readonly GUIContent XAxisContent = new GUIContent("X Axis", "Horizontal Axis to listen for.");
|
||
private static readonly GUIContent YAxisContent = new GUIContent("Y Axis", "Vertical Axis to listen for.");
|
||
private static readonly GUIContent InvertContent = new GUIContent("Invert", "Should an Axis be inverted?");
|
||
private static readonly GUIContent[] InvertAxisContent =
|
||
{
|
||
new GUIContent("None"),
|
||
new GUIContent("X"),
|
||
new GUIContent("Y"),
|
||
new GUIContent("Both")
|
||
};
|
||
|
||
private static readonly int[] InvertAxisValues = { 0, 1, 2, 3 };
|
||
|
||
private static readonly Vector2 InputActionLabelPosition = new Vector2(256f, 0f);
|
||
private static readonly Vector2 InputActionDropdownPosition = new Vector2(88f, 0f);
|
||
private static readonly Vector2 InputActionFlipTogglePosition = new Vector2(-24f, 0f);
|
||
private static readonly Vector2 HorizontalSpace = new Vector2(8f, 0f);
|
||
|
||
private static readonly Rect ControllerRectPosition = new Rect(new Vector2(128f, 0f), new Vector2(512f, 512f));
|
||
|
||
private static ControllerPopupWindow window;
|
||
private static ControllerInputActionOptions controllerInputActionOptions;
|
||
|
||
private static GUIContent[] axisLabels;
|
||
private static int[] actionIds;
|
||
private static GUIContent[] actionLabels;
|
||
private static int[] rawActionIds;
|
||
private static GUIContent[] rawActionLabels;
|
||
private static int[] digitalActionIds;
|
||
private static GUIContent[] digitalActionLabels;
|
||
private static int[] singleAxisActionIds;
|
||
private static GUIContent[] singleAxisActionLabels;
|
||
private static int[] dualAxisActionIds;
|
||
private static GUIContent[] dualAxisActionLabels;
|
||
private static int[] threeDofPositionActionIds;
|
||
private static GUIContent[] threeDofPositionActionLabels;
|
||
private static int[] threeDofRotationActionIds;
|
||
private static GUIContent[] threeDofRotationActionLabels;
|
||
private static int[] sixDofActionIds;
|
||
private static GUIContent[] sixDofActionLabels;
|
||
private static bool[] isMouseInRects;
|
||
|
||
private static bool editInputActionPositions;
|
||
|
||
private static float defaultLabelWidth;
|
||
private static float defaultFieldWidth;
|
||
|
||
private static Vector2 horizontalScrollPosition;
|
||
|
||
private SerializedProperty currentInteractionList;
|
||
private List<string> mappedControllerList = new List<string>();
|
||
|
||
private ControllerPopupWindow thisWindow;
|
||
|
||
private MixedRealityControllerMapping currentControllerMapping;
|
||
|
||
private Vector2 mouseDragOffset;
|
||
private GUIStyle flippedLabelStyle;
|
||
private Texture2D currentControllerTexture;
|
||
private ControllerInputActionOption currentControllerOption;
|
||
|
||
private void OnFocus()
|
||
{
|
||
currentControllerTexture = ControllerMappingLibrary.GetControllerTexture(currentControllerMapping.ControllerType, currentControllerMapping.Handedness);
|
||
|
||
#region Interaction Constraint Setup
|
||
|
||
actionIds = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Select(action => (int)action.Id)
|
||
.Prepend(0).ToArray();
|
||
|
||
axisLabels = ControllerMappingLibrary.UnityInputManagerAxes
|
||
.Select(axis => new GUIContent(axis.Name))
|
||
.Prepend(new GUIContent("None")).ToArray();
|
||
|
||
actionIds = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.None)
|
||
.Select(action => (int)action.Id)
|
||
.Prepend(0).ToArray();
|
||
|
||
actionLabels = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.None)
|
||
.Select(inputAction => new GUIContent(inputAction.Description))
|
||
.Prepend(new GUIContent("None")).ToArray();
|
||
|
||
rawActionIds = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.Raw)
|
||
.Select(action => (int)action.Id)
|
||
.Prepend(0).ToArray();
|
||
|
||
rawActionLabels = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.Raw)
|
||
.Select(inputAction => new GUIContent(inputAction.Description))
|
||
.Prepend(new GUIContent("None")).ToArray();
|
||
|
||
digitalActionIds = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.Digital)
|
||
.Select(action => (int)action.Id)
|
||
.Prepend(0).ToArray();
|
||
|
||
digitalActionLabels = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.Digital)
|
||
.Select(inputAction => new GUIContent(inputAction.Description))
|
||
.Prepend(new GUIContent("None")).ToArray();
|
||
|
||
singleAxisActionIds = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.SingleAxis)
|
||
.Select(action => (int)action.Id)
|
||
.Prepend(0).ToArray();
|
||
|
||
singleAxisActionLabels = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.SingleAxis)
|
||
.Select(inputAction => new GUIContent(inputAction.Description))
|
||
.Prepend(new GUIContent("None")).ToArray();
|
||
|
||
dualAxisActionIds = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.DualAxis)
|
||
.Select(action => (int)action.Id).Prepend(0).ToArray();
|
||
|
||
dualAxisActionLabels = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.DualAxis)
|
||
.Select(inputAction => new GUIContent(inputAction.Description))
|
||
.Prepend(new GUIContent("None")).ToArray();
|
||
|
||
threeDofPositionActionIds = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.ThreeDofPosition)
|
||
.Select(action => (int)action.Id)
|
||
.Prepend(0).ToArray();
|
||
|
||
threeDofPositionActionLabels = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.ThreeDofPosition)
|
||
.Select(inputAction => new GUIContent(inputAction.Description))
|
||
.Prepend(new GUIContent("None")).ToArray();
|
||
|
||
threeDofRotationActionIds = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.ThreeDofRotation)
|
||
.Select(action => (int)action.Id)
|
||
.Prepend(0).ToArray();
|
||
|
||
threeDofRotationActionLabels = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.ThreeDofRotation)
|
||
.Select(inputAction => new GUIContent(inputAction.Description))
|
||
.Prepend(new GUIContent("None")).ToArray();
|
||
|
||
sixDofActionIds = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.SixDof)
|
||
.Select(action => (int)action.Id)
|
||
.Prepend(0).ToArray();
|
||
|
||
sixDofActionLabels = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions
|
||
.Where(inputAction => inputAction.AxisConstraint == AxisType.SixDof)
|
||
.Select(inputAction => new GUIContent(inputAction.Description))
|
||
.Prepend(new GUIContent("None")).ToArray();
|
||
|
||
#endregion Interaction Constraint Setup
|
||
}
|
||
|
||
/// <summary>
|
||
/// Displays the controller mapping window for the specified controller mapping.
|
||
/// </summary>
|
||
/// <param name="controllerMapping">The controller mapping being modified.</param>
|
||
/// <param name="interactionsList">The underlying serialized property being modified.</param>
|
||
/// <param name="handedness">The handedness of the controller.</param>
|
||
/// <param name="mappedControllers">The list of controller types affected by this mapping.</param>
|
||
public static void Show(MixedRealityControllerMapping controllerMapping, SerializedProperty interactionsList, Handedness handedness = Handedness.None, List<string> mappedControllers = null)
|
||
{
|
||
if (window != null)
|
||
{
|
||
window.Close();
|
||
}
|
||
|
||
window = null;
|
||
|
||
if (!MixedRealityToolkit.IsInitialized)
|
||
{
|
||
throw new InvalidOperationException("Mixed Reality Toolkit hasn't been initialized yet! Open a scene with a Mixed Reality Toolkit to initialize it before editing the controller mappings.");
|
||
}
|
||
|
||
window = CreateInstance<ControllerPopupWindow>();
|
||
window.thisWindow = window;
|
||
window.titleContent = new GUIContent($"{controllerMapping.Description} - Input Action Assignment");
|
||
window.mappedControllerList = mappedControllers;
|
||
window.currentControllerMapping = controllerMapping;
|
||
window.currentInteractionList = interactionsList;
|
||
isMouseInRects = new bool[interactionsList.arraySize];
|
||
|
||
string editorWindowOptionsPath = ResolveEditorWindowOptionsPath();
|
||
if (!File.Exists(editorWindowOptionsPath))
|
||
{
|
||
var empty = new ControllerInputActionOptions
|
||
{
|
||
Controllers = new List<ControllerInputActionOption>
|
||
{
|
||
new ControllerInputActionOption
|
||
{
|
||
Controller = 0,
|
||
Handedness = Handedness.None,
|
||
InputLabelPositions = new[] {new Vector2(0, 0)},
|
||
IsLabelFlipped = new []{false}
|
||
}
|
||
}
|
||
};
|
||
|
||
File.WriteAllText(editorWindowOptionsPath, JsonUtility.ToJson(empty, true));
|
||
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
|
||
}
|
||
else
|
||
{
|
||
controllerInputActionOptions = JsonUtility.FromJson<ControllerInputActionOptions>(File.ReadAllText(editorWindowOptionsPath));
|
||
|
||
if (controllerInputActionOptions.Controllers.Any(option => option.Controller == controllerMapping.SupportedControllerType && option.Handedness == handedness))
|
||
{
|
||
window.currentControllerOption = controllerInputActionOptions.Controllers.FirstOrDefault(option => option.Controller == controllerMapping.SupportedControllerType && option.Handedness == handedness);
|
||
|
||
if (window.currentControllerOption != null && window.currentControllerOption.IsLabelFlipped == null)
|
||
{
|
||
window.currentControllerOption.IsLabelFlipped = new bool[interactionsList.arraySize];
|
||
}
|
||
}
|
||
}
|
||
|
||
var windowSize = new Vector2(controllerMapping.HasCustomInteractionMappings ? 896f : 768f, 512f);
|
||
window.maxSize = windowSize;
|
||
window.minSize = windowSize;
|
||
window.CenterOnMainWin();
|
||
window.ShowUtility();
|
||
|
||
defaultLabelWidth = EditorGUIUtility.labelWidth;
|
||
defaultFieldWidth = EditorGUIUtility.fieldWidth;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Use this to repaint the pop-up window.
|
||
/// </summary>
|
||
public static void RepaintWindow()
|
||
{
|
||
if (window != null && window.thisWindow != null)
|
||
{
|
||
window.thisWindow.Repaint();
|
||
}
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
if (editInputActionPositions)
|
||
{
|
||
Repaint();
|
||
}
|
||
}
|
||
|
||
private void OnGUI()
|
||
{
|
||
if (flippedLabelStyle == null)
|
||
{
|
||
flippedLabelStyle = new GUIStyle("Label")
|
||
{
|
||
alignment = TextAnchor.UpperRight,
|
||
stretchWidth = true
|
||
};
|
||
}
|
||
|
||
if (!currentControllerMapping.HasCustomInteractionMappings && currentControllerTexture != null)
|
||
{
|
||
GUILayout.BeginHorizontal();
|
||
GUI.DrawTexture(ControllerRectPosition, currentControllerTexture);
|
||
GUILayout.EndHorizontal();
|
||
}
|
||
|
||
try
|
||
{
|
||
RenderInteractionList(currentInteractionList, currentControllerMapping.HasCustomInteractionMappings);
|
||
RenderMappingList(mappedControllerList);
|
||
}
|
||
catch (Exception)
|
||
{
|
||
thisWindow.Close();
|
||
}
|
||
}
|
||
|
||
private void RenderMappingList(List<string> controllerList)
|
||
{
|
||
if (controllerList == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
using (new EditorGUILayout.VerticalScope())
|
||
{
|
||
GUILayout.FlexibleSpace();
|
||
EditorGUILayout.LabelField("Controllers affected by this mapping", EditorStyles.boldLabel);
|
||
for (int i = 0; i < controllerList.Count; i++)
|
||
{
|
||
EditorGUILayout.LabelField(controllerList[i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void RenderInteractionList(SerializedProperty interactionList, bool useCustomInteractionMapping)
|
||
{
|
||
if (interactionList == null) { throw new Exception(); }
|
||
|
||
bool noInteractions = interactionList.arraySize == 0;
|
||
|
||
if (currentControllerOption != null && (currentControllerOption.IsLabelFlipped == null || currentControllerOption.IsLabelFlipped.Length != interactionList.arraySize))
|
||
{
|
||
currentControllerOption.IsLabelFlipped = new bool[interactionList.arraySize];
|
||
}
|
||
|
||
GUILayout.BeginVertical();
|
||
|
||
if (useCustomInteractionMapping)
|
||
{
|
||
horizontalScrollPosition = EditorGUILayout.BeginScrollView(horizontalScrollPosition, false, false, GUILayout.ExpandWidth(true), GUILayout.ExpandWidth(true));
|
||
}
|
||
|
||
if (useCustomInteractionMapping)
|
||
{
|
||
if (GUILayout.Button(InteractionAddButtonContent))
|
||
{
|
||
interactionList.arraySize += 1;
|
||
var interaction = interactionList.GetArrayElementAtIndex(interactionList.arraySize - 1);
|
||
var axisType = interaction.FindPropertyRelative("axisType");
|
||
axisType.enumValueIndex = 0;
|
||
var inputType = interaction.FindPropertyRelative("inputType");
|
||
inputType.enumValueIndex = 0;
|
||
var action = interaction.FindPropertyRelative("inputAction");
|
||
var actionId = action.FindPropertyRelative("id");
|
||
var actionDescription = action.FindPropertyRelative("description");
|
||
actionDescription.stringValue = "None";
|
||
actionId.intValue = 0;
|
||
}
|
||
|
||
if (noInteractions)
|
||
{
|
||
EditorGUILayout.HelpBox("Create an Interaction Mapping.", MessageType.Warning);
|
||
EditorGUILayout.EndScrollView();
|
||
GUILayout.EndVertical();
|
||
return;
|
||
}
|
||
}
|
||
else if (EnableWysiwyg)
|
||
{
|
||
EditorGUI.BeginChangeCheck();
|
||
editInputActionPositions = EditorGUILayout.Toggle("Edit Input Action Positions", editInputActionPositions);
|
||
|
||
if (EditorGUI.EndChangeCheck())
|
||
{
|
||
string editorWindowOptionsPath = ResolveEditorWindowOptionsPath();
|
||
if (!editInputActionPositions)
|
||
{
|
||
File.WriteAllText(editorWindowOptionsPath, JsonUtility.ToJson(controllerInputActionOptions, true));
|
||
}
|
||
else
|
||
{
|
||
if (!controllerInputActionOptions.Controllers.Any(
|
||
option => option.Controller == currentControllerMapping.SupportedControllerType && option.Handedness == currentControllerMapping.Handedness))
|
||
{
|
||
currentControllerOption = new ControllerInputActionOption
|
||
{
|
||
Controller = currentControllerMapping.SupportedControllerType,
|
||
Handedness = currentControllerMapping.Handedness,
|
||
InputLabelPositions = new Vector2[currentInteractionList.arraySize],
|
||
IsLabelFlipped = new bool[currentInteractionList.arraySize]
|
||
};
|
||
|
||
controllerInputActionOptions.Controllers.Add(currentControllerOption);
|
||
isMouseInRects = new bool[currentInteractionList.arraySize];
|
||
|
||
if (controllerInputActionOptions.Controllers.Any(option => option.Controller == 0))
|
||
{
|
||
controllerInputActionOptions.Controllers.Remove(
|
||
controllerInputActionOptions.Controllers.Find(option =>
|
||
option.Controller == 0));
|
||
}
|
||
|
||
File.WriteAllText(editorWindowOptionsPath, JsonUtility.ToJson(controllerInputActionOptions, true));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
GUILayout.BeginHorizontal();
|
||
|
||
if (useCustomInteractionMapping)
|
||
{
|
||
EditorGUILayout.LabelField("Id", GUILayout.Width(32f));
|
||
EditorGUIUtility.labelWidth = 24f;
|
||
EditorGUIUtility.fieldWidth = 24f;
|
||
EditorGUILayout.LabelField(ControllerInputTypeContent, GUILayout.Width(InputActionLabelWidth));
|
||
EditorGUILayout.LabelField(AxisTypeContent, GUILayout.Width(InputActionLabelWidth));
|
||
EditorGUILayout.LabelField(ActionContent, GUILayout.Width(InputActionLabelWidth));
|
||
EditorGUILayout.LabelField(KeyCodeContent, GUILayout.Width(InputActionLabelWidth));
|
||
EditorGUILayout.LabelField(XAxisContent, GUILayout.Width(InputActionLabelWidth));
|
||
EditorGUILayout.LabelField(YAxisContent, GUILayout.Width(InputActionLabelWidth));
|
||
GUILayout.FlexibleSpace();
|
||
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(24f));
|
||
|
||
EditorGUIUtility.labelWidth = defaultLabelWidth;
|
||
EditorGUIUtility.fieldWidth = defaultFieldWidth;
|
||
}
|
||
|
||
GUILayout.EndHorizontal();
|
||
|
||
for (int i = 0; i < interactionList.arraySize; i++)
|
||
{
|
||
using (new EditorGUILayout.HorizontalScope())
|
||
{
|
||
SerializedProperty interaction = interactionList.GetArrayElementAtIndex(i);
|
||
|
||
if (useCustomInteractionMapping)
|
||
{
|
||
EditorGUILayout.LabelField($"{i + 1}", GUILayout.Width(32f));
|
||
var inputType = interaction.FindPropertyRelative("inputType");
|
||
EditorGUILayout.PropertyField(inputType, GUIContent.none, GUILayout.Width(InputActionLabelWidth));
|
||
var axisType = interaction.FindPropertyRelative("axisType");
|
||
EditorGUILayout.PropertyField(axisType, GUIContent.none, GUILayout.Width(InputActionLabelWidth));
|
||
var invertXAxis = interaction.FindPropertyRelative("invertXAxis");
|
||
var invertYAxis = interaction.FindPropertyRelative("invertYAxis");
|
||
var interactionAxisConstraint = interaction.FindPropertyRelative("axisType");
|
||
|
||
var action = interaction.FindPropertyRelative("inputAction");
|
||
var actionId = action.FindPropertyRelative("id");
|
||
var actionDescription = action.FindPropertyRelative("description");
|
||
var actionConstraint = action.FindPropertyRelative("axisConstraint");
|
||
|
||
GUIContent[] labels;
|
||
int[] ids;
|
||
|
||
switch ((AxisType)interactionAxisConstraint.intValue)
|
||
{
|
||
default:
|
||
case AxisType.None:
|
||
labels = actionLabels;
|
||
ids = actionIds;
|
||
break;
|
||
case AxisType.Raw:
|
||
labels = rawActionLabels;
|
||
ids = rawActionIds;
|
||
break;
|
||
case AxisType.Digital:
|
||
labels = digitalActionLabels;
|
||
ids = digitalActionIds;
|
||
break;
|
||
case AxisType.SingleAxis:
|
||
labels = singleAxisActionLabels;
|
||
ids = singleAxisActionIds;
|
||
break;
|
||
case AxisType.DualAxis:
|
||
labels = dualAxisActionLabels;
|
||
ids = dualAxisActionIds;
|
||
break;
|
||
case AxisType.ThreeDofPosition:
|
||
labels = threeDofPositionActionLabels;
|
||
ids = threeDofPositionActionIds;
|
||
break;
|
||
case AxisType.ThreeDofRotation:
|
||
labels = threeDofRotationActionLabels;
|
||
ids = threeDofRotationActionIds;
|
||
break;
|
||
case AxisType.SixDof:
|
||
labels = sixDofActionLabels;
|
||
ids = sixDofActionIds;
|
||
break;
|
||
}
|
||
|
||
EditorGUI.BeginChangeCheck();
|
||
actionId.intValue = EditorGUILayout.IntPopup(GUIContent.none, actionId.intValue, labels, ids, GUILayout.Width(InputActionLabelWidth));
|
||
|
||
if (EditorGUI.EndChangeCheck())
|
||
{
|
||
var inputAction = actionId.intValue == 0 ? MixedRealityInputAction.None : MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions[actionId.intValue - 1];
|
||
actionDescription.stringValue = inputAction.Description;
|
||
actionConstraint.intValue = (int)inputAction.AxisConstraint;
|
||
}
|
||
|
||
if ((AxisType)axisType.intValue == AxisType.Digital)
|
||
{
|
||
var keyCode = interaction.FindPropertyRelative("keyCode");
|
||
EditorGUILayout.PropertyField(keyCode, GUIContent.none, GUILayout.Width(InputActionLabelWidth));
|
||
}
|
||
else
|
||
{
|
||
if ((AxisType)axisType.intValue == AxisType.DualAxis)
|
||
{
|
||
EditorGUIUtility.labelWidth = InputActionLabelWidth * 0.5f;
|
||
EditorGUIUtility.fieldWidth = InputActionLabelWidth * 0.5f;
|
||
|
||
int currentAxisSetting = 0;
|
||
|
||
if (invertXAxis.boolValue)
|
||
{
|
||
currentAxisSetting += 1;
|
||
}
|
||
|
||
if (invertYAxis.boolValue)
|
||
{
|
||
currentAxisSetting += 2;
|
||
}
|
||
|
||
EditorGUI.BeginChangeCheck();
|
||
currentAxisSetting = EditorGUILayout.IntPopup(InvertContent, currentAxisSetting, InvertAxisContent, InvertAxisValues, GUILayout.Width(InputActionLabelWidth));
|
||
|
||
if (EditorGUI.EndChangeCheck())
|
||
{
|
||
switch (currentAxisSetting)
|
||
{
|
||
case 0:
|
||
invertXAxis.boolValue = false;
|
||
invertYAxis.boolValue = false;
|
||
break;
|
||
case 1:
|
||
invertXAxis.boolValue = true;
|
||
invertYAxis.boolValue = false;
|
||
break;
|
||
case 2:
|
||
invertXAxis.boolValue = false;
|
||
invertYAxis.boolValue = true;
|
||
break;
|
||
case 3:
|
||
invertXAxis.boolValue = true;
|
||
invertYAxis.boolValue = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
EditorGUIUtility.labelWidth = defaultLabelWidth;
|
||
EditorGUIUtility.fieldWidth = defaultFieldWidth;
|
||
}
|
||
else if ((AxisType)axisType.intValue == AxisType.SingleAxis)
|
||
{
|
||
invertXAxis.boolValue = EditorGUILayout.ToggleLeft("Invert X", invertXAxis.boolValue, GUILayout.Width(InputActionLabelWidth));
|
||
EditorGUIUtility.labelWidth = defaultLabelWidth;
|
||
}
|
||
else
|
||
{
|
||
EditorGUILayout.LabelField(GUIContent.none, GUILayout.Width(InputActionLabelWidth));
|
||
}
|
||
}
|
||
|
||
if ((AxisType)axisType.intValue == AxisType.SingleAxis ||
|
||
(AxisType)axisType.intValue == AxisType.DualAxis)
|
||
{
|
||
var axisCodeX = interaction.FindPropertyRelative("axisCodeX");
|
||
RenderAxisPopup(axisCodeX, InputActionLabelWidth);
|
||
}
|
||
else
|
||
{
|
||
EditorGUILayout.LabelField(GUIContent.none, GUILayout.Width(InputActionLabelWidth));
|
||
}
|
||
|
||
if ((AxisType)axisType.intValue == AxisType.DualAxis)
|
||
{
|
||
var axisCodeY = interaction.FindPropertyRelative("axisCodeY");
|
||
RenderAxisPopup(axisCodeY, InputActionLabelWidth);
|
||
}
|
||
else
|
||
{
|
||
EditorGUILayout.LabelField(GUIContent.none, GUILayout.Width(InputActionLabelWidth));
|
||
}
|
||
|
||
if (GUILayout.Button(InteractionMinusButtonContent, EditorStyles.miniButtonRight, GUILayout.ExpandWidth(true)))
|
||
{
|
||
interactionList.DeleteArrayElementAtIndex(i);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var interactionDescription = interaction.FindPropertyRelative("description");
|
||
var interactionAxisConstraint = interaction.FindPropertyRelative("axisType");
|
||
var action = interaction.FindPropertyRelative("inputAction");
|
||
var actionId = action.FindPropertyRelative("id");
|
||
var actionDescription = action.FindPropertyRelative("description");
|
||
var actionConstraint = action.FindPropertyRelative("axisConstraint");
|
||
|
||
GUIContent[] labels;
|
||
int[] ids;
|
||
|
||
switch ((AxisType)interactionAxisConstraint.intValue)
|
||
{
|
||
default:
|
||
case AxisType.None:
|
||
labels = actionLabels;
|
||
ids = actionIds;
|
||
break;
|
||
case AxisType.Raw:
|
||
labels = rawActionLabels;
|
||
ids = rawActionIds;
|
||
break;
|
||
case AxisType.Digital:
|
||
labels = digitalActionLabels;
|
||
ids = digitalActionIds;
|
||
break;
|
||
case AxisType.SingleAxis:
|
||
labels = singleAxisActionLabels;
|
||
ids = singleAxisActionIds;
|
||
break;
|
||
case AxisType.DualAxis:
|
||
labels = dualAxisActionLabels;
|
||
ids = dualAxisActionIds;
|
||
break;
|
||
case AxisType.ThreeDofPosition:
|
||
labels = threeDofPositionActionLabels;
|
||
ids = threeDofPositionActionIds;
|
||
break;
|
||
case AxisType.ThreeDofRotation:
|
||
labels = threeDofRotationActionLabels;
|
||
ids = threeDofRotationActionIds;
|
||
break;
|
||
case AxisType.SixDof:
|
||
labels = sixDofActionLabels;
|
||
ids = sixDofActionIds;
|
||
break;
|
||
}
|
||
|
||
EditorGUI.BeginChangeCheck();
|
||
|
||
if (currentControllerOption == null || currentControllerTexture == null)
|
||
{
|
||
bool skip = false;
|
||
var description = interactionDescription.stringValue;
|
||
if (currentControllerMapping.SupportedControllerType == SupportedControllerType.GGVHand
|
||
&& currentControllerMapping.Handedness == Handedness.None)
|
||
{
|
||
if (description != "Select")
|
||
{
|
||
skip = true;
|
||
}
|
||
}
|
||
|
||
if (!skip)
|
||
{
|
||
actionId.intValue = EditorGUILayout.IntPopup(GUIContent.none, actionId.intValue, labels, ids, GUILayout.Width(80f));
|
||
EditorGUILayout.LabelField(description, GUILayout.ExpandWidth(true));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var rectPosition = currentControllerOption.InputLabelPositions[i];
|
||
var rectSize = InputActionLabelPosition + InputActionDropdownPosition + new Vector2(currentControllerOption.IsLabelFlipped[i] ? 0f : 8f, EditorGUIUtility.singleLineHeight);
|
||
GUI.Box(new Rect(rectPosition, rectSize), GUIContent.none, EditorGUIUtility.isProSkin ? "ObjectPickerBackground" : "ObjectPickerResultsEven");
|
||
var offset = currentControllerOption.IsLabelFlipped[i] ? InputActionLabelPosition : Vector2.zero;
|
||
var popupRect = new Rect(rectPosition + offset, new Vector2(InputActionDropdownPosition.x, EditorGUIUtility.singleLineHeight));
|
||
|
||
actionId.intValue = EditorGUI.IntPopup(popupRect, actionId.intValue, labels, ids);
|
||
offset = currentControllerOption.IsLabelFlipped[i] ? Vector2.zero : InputActionDropdownPosition;
|
||
var labelRect = new Rect(rectPosition + offset, new Vector2(InputActionLabelPosition.x, EditorGUIUtility.singleLineHeight));
|
||
EditorGUI.LabelField(labelRect, interactionDescription.stringValue, currentControllerOption.IsLabelFlipped[i] ? flippedLabelStyle : EditorStyles.label);
|
||
|
||
if (editInputActionPositions)
|
||
{
|
||
offset = currentControllerOption.IsLabelFlipped[i] ? InputActionLabelPosition + InputActionDropdownPosition + HorizontalSpace : InputActionFlipTogglePosition;
|
||
var toggleRect = new Rect(rectPosition + offset, new Vector2(-InputActionFlipTogglePosition.x, EditorGUIUtility.singleLineHeight));
|
||
|
||
EditorGUI.BeginChangeCheck();
|
||
currentControllerOption.IsLabelFlipped[i] = EditorGUI.Toggle(toggleRect, currentControllerOption.IsLabelFlipped[i]);
|
||
|
||
if (EditorGUI.EndChangeCheck())
|
||
{
|
||
if (currentControllerOption.IsLabelFlipped[i])
|
||
{
|
||
currentControllerOption.InputLabelPositions[i] -= InputActionLabelPosition;
|
||
}
|
||
else
|
||
{
|
||
currentControllerOption.InputLabelPositions[i] += InputActionLabelPosition;
|
||
}
|
||
}
|
||
|
||
if (!isMouseInRects.Any(value => value) || isMouseInRects[i])
|
||
{
|
||
if (Event.current.type == EventType.MouseDrag && labelRect.Contains(Event.current.mousePosition) && !isMouseInRects[i])
|
||
{
|
||
isMouseInRects[i] = true;
|
||
mouseDragOffset = Event.current.mousePosition - currentControllerOption.InputLabelPositions[i];
|
||
}
|
||
else if (Event.current.type == EventType.Repaint && isMouseInRects[i])
|
||
{
|
||
currentControllerOption.InputLabelPositions[i] = Event.current.mousePosition - mouseDragOffset;
|
||
}
|
||
else if (Event.current.type == EventType.DragUpdated && isMouseInRects[i])
|
||
{
|
||
currentControllerOption.InputLabelPositions[i] = Event.current.mousePosition - mouseDragOffset;
|
||
}
|
||
else if (Event.current.type == EventType.MouseUp && isMouseInRects[i])
|
||
{
|
||
currentControllerOption.InputLabelPositions[i] = Event.current.mousePosition - mouseDragOffset;
|
||
mouseDragOffset = Vector2.zero;
|
||
isMouseInRects[i] = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (EditorGUI.EndChangeCheck())
|
||
{
|
||
MixedRealityInputAction inputAction = actionId.intValue == 0 ?
|
||
MixedRealityInputAction.None :
|
||
MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions[actionId.intValue - 1];
|
||
actionId.intValue = (int)inputAction.Id;
|
||
actionDescription.stringValue = inputAction.Description;
|
||
actionConstraint.intValue = (int)inputAction.AxisConstraint;
|
||
interactionList.serializedObject.ApplyModifiedProperties();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (useCustomInteractionMapping)
|
||
{
|
||
EditorGUILayout.EndScrollView();
|
||
interactionList.serializedObject.ApplyModifiedProperties();
|
||
}
|
||
|
||
GUILayout.EndVertical();
|
||
}
|
||
|
||
private static void RenderAxisPopup(SerializedProperty axisCode, float customLabelWidth)
|
||
{
|
||
var axisId = -1;
|
||
|
||
for (int j = 0; j < ControllerMappingLibrary.UnityInputManagerAxes.Length; j++)
|
||
{
|
||
if (ControllerMappingLibrary.UnityInputManagerAxes[j].Name == axisCode.stringValue)
|
||
{
|
||
axisId = j + 1;
|
||
break;
|
||
}
|
||
}
|
||
|
||
EditorGUI.BeginChangeCheck();
|
||
axisId = EditorGUILayout.IntPopup(GUIContent.none, axisId, axisLabels, null, GUILayout.Width(customLabelWidth));
|
||
|
||
if (EditorGUI.EndChangeCheck())
|
||
{
|
||
if (axisId == 0)
|
||
{
|
||
axisCode.stringValue = string.Empty;
|
||
axisCode.serializedObject.ApplyModifiedProperties();
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < ControllerMappingLibrary.UnityInputManagerAxes.Length; j++)
|
||
{
|
||
if (axisId - 1 == j)
|
||
{
|
||
axisCode.stringValue = ControllerMappingLibrary.UnityInputManagerAxes[j].Name;
|
||
axisCode.serializedObject.ApplyModifiedProperties();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private static string ResolveEditorWindowOptionsPath()
|
||
{
|
||
return Path.GetFullPath(AssetDatabase.GUIDToAssetPath(EditorWindowOptionsGuid));
|
||
}
|
||
}
|
||
}
|