Keine Beschreibung
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

InputSystemUIInputModuleEditor.cs 10.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #if UNITY_INPUT_SYSTEM_ENABLE_UI && UNITY_EDITOR
  2. using System;
  3. using System.Linq;
  4. using UnityEditor;
  5. using UnityEditor.EventSystems;
  6. using UnityEngine.InputSystem.Editor;
  7. ////TODO: add button to automatically set up gamepad mouse cursor support
  8. namespace UnityEngine.InputSystem.UI.Editor
  9. {
  10. [CustomEditor(typeof(InputSystemUIInputModule))]
  11. [InitializeOnLoad]
  12. internal class InputSystemUIInputModuleEditor : UnityEditor.Editor
  13. {
  14. static InputSystemUIInputModuleEditor()
  15. {
  16. #if UNITY_6000_0_OR_NEWER && ENABLE_INPUT_SYSTEM
  17. InputModuleComponentFactory.SetInputModuleComponentOverride(
  18. go => ObjectFactory.AddComponent<InputSystemUIInputModule>(go));
  19. #endif
  20. }
  21. private static InputActionReference GetActionReferenceFromAssets(InputActionReference[] actions, params string[] actionNames)
  22. {
  23. foreach (var actionName in actionNames)
  24. {
  25. foreach (var action in actions)
  26. {
  27. if (action.action != null && string.Compare(action.action.name, actionName, StringComparison.InvariantCultureIgnoreCase) == 0)
  28. return action;
  29. }
  30. }
  31. return null;
  32. }
  33. private static InputActionReference[] GetAllAssetReferencesFromAssetDatabase(InputActionAsset actions)
  34. {
  35. if (actions == null)
  36. return null;
  37. var path = AssetDatabase.GetAssetPath(actions);
  38. var assets = AssetDatabase.LoadAllAssetsAtPath(path);
  39. return assets.Where(asset => asset is InputActionReference)
  40. .Cast<InputActionReference>()
  41. .OrderBy(x => x.name)
  42. .ToArray();
  43. }
  44. private static readonly string[] s_ActionNames =
  45. {
  46. "Point",
  47. "LeftClick",
  48. "MiddleClick",
  49. "RightClick",
  50. "ScrollWheel",
  51. "Move",
  52. "Submit",
  53. "Cancel",
  54. "TrackedDevicePosition",
  55. "TrackedDeviceOrientation"
  56. };
  57. private static readonly string[] s_ActionNiceNames =
  58. {
  59. "Point",
  60. "Left Click",
  61. "Middle Click",
  62. "Right Click",
  63. "Scroll Wheel",
  64. "Move",
  65. "Submit",
  66. "Cancel",
  67. "Tracked Position",
  68. "Tracked Orientation"
  69. };
  70. private SerializedProperty[] m_ReferenceProperties;
  71. private SerializedProperty m_ActionsAsset;
  72. private InputActionReference[] m_AvailableActionReferencesInAssetDatabase;
  73. private string[] m_AvailableActionsInAssetNames;
  74. private bool m_AdvancedFoldoutState;
  75. private string MakeActionReferenceNameUsableInGenericMenu(string name)
  76. {
  77. // Ugly hack: GenericMenu interprets "/" as a submenu path. But luckily, "/" is not the only slash we have in Unicode.
  78. return name.Replace("/", "\uFF0F");
  79. }
  80. public void OnEnable()
  81. {
  82. var numActions = s_ActionNames.Length;
  83. m_ReferenceProperties = new SerializedProperty[numActions];
  84. for (var i = 0; i < numActions; i++)
  85. m_ReferenceProperties[i] = serializedObject.FindProperty($"m_{s_ActionNames[i]}Action");
  86. m_ActionsAsset = serializedObject.FindProperty("m_ActionsAsset");
  87. m_AvailableActionReferencesInAssetDatabase = GetAllAssetReferencesFromAssetDatabase(m_ActionsAsset.objectReferenceValue as InputActionAsset);
  88. m_AvailableActionsInAssetNames = new[] { "None" }
  89. .Concat(m_AvailableActionReferencesInAssetDatabase?.Select(x => MakeActionReferenceNameUsableInGenericMenu(x.name)) ?? new string[0]).ToArray();
  90. }
  91. public static void ReassignActions(InputSystemUIInputModule module, InputActionAsset action)
  92. {
  93. module.actionsAsset = action;
  94. var assets = GetAllAssetReferencesFromAssetDatabase(action);
  95. if (assets != null)
  96. {
  97. module.point = GetActionReferenceFromAssets(assets, module.point?.action?.name, "Point", "MousePosition", "Mouse Position");
  98. module.leftClick = GetActionReferenceFromAssets(assets, module.leftClick?.action?.name, "Click", "LeftClick", "Left Click");
  99. module.rightClick = GetActionReferenceFromAssets(assets, module.rightClick?.action?.name, "RightClick", "Right Click", "ContextClick", "Context Click", "ContextMenu", "Context Menu");
  100. module.middleClick = GetActionReferenceFromAssets(assets, module.middleClick?.action?.name, "MiddleClick", "Middle Click");
  101. module.scrollWheel = GetActionReferenceFromAssets(assets, module.scrollWheel?.action?.name, "ScrollWheel", "Scroll Wheel", "Scroll", "Wheel");
  102. module.move = GetActionReferenceFromAssets(assets, module.move?.action?.name, "Navigate", "Move");
  103. module.submit = GetActionReferenceFromAssets(assets, module.submit?.action?.name, "Submit");
  104. module.cancel = GetActionReferenceFromAssets(assets, module.cancel?.action?.name, "Cancel", "Esc", "Escape");
  105. module.trackedDevicePosition = GetActionReferenceFromAssets(assets, module.trackedDevicePosition?.action?.name, "TrackedDevicePosition", "Position");
  106. module.trackedDeviceOrientation = GetActionReferenceFromAssets(assets, module.trackedDeviceOrientation?.action?.name, "TrackedDeviceOrientation", "Orientation");
  107. }
  108. }
  109. public override void OnInspectorGUI()
  110. {
  111. base.OnInspectorGUI();
  112. EditorGUI.BeginChangeCheck();
  113. EditorGUILayout.PropertyField(m_ActionsAsset);
  114. if (EditorGUI.EndChangeCheck())
  115. {
  116. var actions = m_ActionsAsset.objectReferenceValue as InputActionAsset;
  117. if (actions != null)
  118. {
  119. serializedObject.ApplyModifiedProperties();
  120. ReassignActions(target as InputSystemUIInputModule, actions);
  121. serializedObject.Update();
  122. }
  123. // reinitialize action types
  124. OnEnable();
  125. }
  126. var numActions = s_ActionNames.Length;
  127. if ((m_AvailableActionReferencesInAssetDatabase != null && m_AvailableActionReferencesInAssetDatabase.Length > 0) || m_ActionsAsset.objectReferenceValue == null)
  128. {
  129. for (var i = 0; i < numActions; i++)
  130. {
  131. // find the input action reference from the asset that matches the input action reference from the
  132. // InputSystemUIInputModule that is currently selected. Note we can't use reference equality of the
  133. // two InputActionReference objects here because in ReassignActions above, we create new instances
  134. // every time it runs.
  135. var index = IndexOfInputActionInAsset(
  136. ((InputActionReference)m_ReferenceProperties[i]?.objectReferenceValue)?.action);
  137. EditorGUI.BeginChangeCheck();
  138. index = EditorGUILayout.Popup(s_ActionNiceNames[i], index, m_AvailableActionsInAssetNames);
  139. if (EditorGUI.EndChangeCheck())
  140. m_ReferenceProperties[i].objectReferenceValue =
  141. index > 0 ? m_AvailableActionReferencesInAssetDatabase[index - 1] : null;
  142. }
  143. }
  144. else
  145. {
  146. // Somehow we have an asset but no asset references from the database, pull out references manually and show them in read only UI
  147. EditorGUILayout.HelpBox("Showing fields as read-only because current action asset seems to be created by a script and assigned programmatically.", MessageType.Info);
  148. EditorGUI.BeginDisabledGroup(true);
  149. for (var i = 0; i < numActions; i++)
  150. {
  151. var retrievedName = "None";
  152. if (m_ReferenceProperties[i].objectReferenceValue != null &&
  153. (m_ReferenceProperties[i].objectReferenceValue is InputActionReference reference))
  154. retrievedName = MakeActionReferenceNameUsableInGenericMenu(reference.ToDisplayName());
  155. EditorGUILayout.Popup(s_ActionNiceNames[i], 0, new[] {retrievedName});
  156. }
  157. EditorGUI.EndDisabledGroup();
  158. }
  159. m_AdvancedFoldoutState = EditorGUILayout.Foldout(m_AdvancedFoldoutState, new GUIContent("Advanced"), true);
  160. if (m_AdvancedFoldoutState)
  161. EditorGUILayout.PropertyField(serializedObject.FindProperty("m_CursorLockBehavior"),
  162. EditorGUIUtility.TrTextContent("Cursor Lock Behavior",
  163. $"Controls the origin point of UI raycasts when the cursor is locked. {InputSystemUIInputModule.CursorLockBehavior.OutsideScreen} " +
  164. $"is the default behavior and will force the raycast to miss all objects. {InputSystemUIInputModule.CursorLockBehavior.ScreenCenter} " +
  165. $"will cast the ray from the center of the screen."));
  166. if (GUI.changed)
  167. serializedObject.ApplyModifiedProperties();
  168. }
  169. private int IndexOfInputActionInAsset(InputAction inputAction)
  170. {
  171. // return 0 instead of -1 here because the zero-th index refers to the 'None' binding.
  172. if (inputAction == null)
  173. return 0;
  174. if (m_AvailableActionReferencesInAssetDatabase == null)
  175. return 0;
  176. var index = 0;
  177. for (var j = 0; j < m_AvailableActionReferencesInAssetDatabase.Length; j++)
  178. {
  179. if (m_AvailableActionReferencesInAssetDatabase[j].action != null &&
  180. m_AvailableActionReferencesInAssetDatabase[j].action == inputAction)
  181. {
  182. index = j + 1;
  183. break;
  184. }
  185. }
  186. return index;
  187. }
  188. }
  189. }
  190. #endif