#if UNITY_INPUT_SYSTEM_ENABLE_UI && UNITY_EDITOR using System; using System.Linq; using UnityEditor; ////TODO: add button to automatically set up gamepad mouse cursor support namespace UnityEngine.InputSystem.UI.Editor { [CustomEditor(typeof(InputSystemUIInputModule))] internal class InputSystemUIInputModuleEditor : UnityEditor.Editor { private static InputActionReference GetActionReferenceFromAssets(InputActionReference[] actions, params string[] actionNames) { foreach (var actionName in actionNames) { foreach (var action in actions) { if (string.Compare(action.action.name, actionName, StringComparison.InvariantCultureIgnoreCase) == 0) return action; } } return null; } private static InputActionReference[] GetAllActionsFromAsset(InputActionAsset actions) { if (actions != null) { var path = AssetDatabase.GetAssetPath(actions); var assets = AssetDatabase.LoadAllAssetsAtPath(path); return assets.Where(asset => asset is InputActionReference).Cast().OrderBy(x => x.name).ToArray(); } return null; } private static readonly string[] s_ActionNames = { "Point", "LeftClick", "MiddleClick", "RightClick", "ScrollWheel", "Move", "Submit", "Cancel", "TrackedDevicePosition", "TrackedDeviceOrientation" }; private static readonly string[] s_ActionNiceNames = { "Point", "Left Click", "Middle Click", "Right Click", "Scroll Wheel", "Move", "Submit", "Cancel", "Tracked Position", "Tracked Orientation" }; private SerializedProperty[] m_ReferenceProperties; private SerializedProperty m_ActionsAsset; private InputActionReference[] m_AvailableActionsInAsset; private string[] m_AvailableActionsInAssetNames; public void OnEnable() { var numActions = s_ActionNames.Length; m_ReferenceProperties = new SerializedProperty[numActions]; for (var i = 0; i < numActions; i++) m_ReferenceProperties[i] = serializedObject.FindProperty($"m_{s_ActionNames[i]}Action"); m_ActionsAsset = serializedObject.FindProperty("m_ActionsAsset"); m_AvailableActionsInAsset = GetAllActionsFromAsset(m_ActionsAsset.objectReferenceValue as InputActionAsset); // Ugly hack: GenericMenu interprets "/" as a submenu path. But luckily, "/" is not the only slash we have in Unicode. m_AvailableActionsInAssetNames = new[] { "None" }.Concat(m_AvailableActionsInAsset?.Select(x => x.name.Replace("/", "\uFF0F")) ?? new string[0]).ToArray(); } public static void ReassignActions(InputSystemUIInputModule module, InputActionAsset action) { module.actionsAsset = action; var assets = GetAllActionsFromAsset(action); if (assets != null) { module.point = GetActionReferenceFromAssets(assets, module.point?.action?.name, "Point", "MousePosition", "Mouse Position"); module.leftClick = GetActionReferenceFromAssets(assets, module.leftClick?.action?.name, "Click", "LeftClick", "Left Click"); module.rightClick = GetActionReferenceFromAssets(assets, module.rightClick?.action?.name, "RightClick", "Right Click", "ContextClick", "Context Click", "ContextMenu", "Context Menu"); module.middleClick = GetActionReferenceFromAssets(assets, module.middleClick?.action?.name, "MiddleClick", "Middle Click"); module.scrollWheel = GetActionReferenceFromAssets(assets, module.scrollWheel?.action?.name, "ScrollWheel", "Scroll Wheel", "Scroll", "Wheel"); module.move = GetActionReferenceFromAssets(assets, module.move?.action?.name, "Navigate", "Move"); module.submit = GetActionReferenceFromAssets(assets, module.submit?.action?.name, "Submit"); module.cancel = GetActionReferenceFromAssets(assets, module.cancel?.action?.name, "Cancel", "Esc", "Escape"); module.trackedDevicePosition = GetActionReferenceFromAssets(assets, module.trackedDevicePosition?.action?.name, "TrackedDevicePosition", "Position"); module.trackedDeviceOrientation = GetActionReferenceFromAssets(assets, module.trackedDeviceOrientation?.action?.name, "TrackedDeviceOrientation", "Orientation"); } } public override void OnInspectorGUI() { base.OnInspectorGUI(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_ActionsAsset); if (EditorGUI.EndChangeCheck()) { var actions = m_ActionsAsset.objectReferenceValue as InputActionAsset; if (actions != null) { serializedObject.ApplyModifiedProperties(); ReassignActions(target as InputSystemUIInputModule, actions); serializedObject.Update(); } // reinitialize action types OnEnable(); } var numActions = s_ActionNames.Length; for (var i = 0; i < numActions; i++) { if (m_AvailableActionsInAsset == null) continue; var index = Array.IndexOf(m_AvailableActionsInAsset, m_ReferenceProperties[i].objectReferenceValue) + 1; EditorGUI.BeginChangeCheck(); index = EditorGUILayout.Popup(s_ActionNiceNames[i], index, m_AvailableActionsInAssetNames); if (EditorGUI.EndChangeCheck()) m_ReferenceProperties[i].objectReferenceValue = index > 0 ? m_AvailableActionsInAsset[index - 1] : null; } if (GUI.changed) serializedObject.ApplyModifiedProperties(); } } } #endif