PlayerInputManagerEditor.cs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #if UNITY_EDITOR
  2. using System;
  3. using UnityEditor;
  4. using UnityEngine.InputSystem.Users;
  5. namespace UnityEngine.InputSystem.Editor
  6. {
  7. /// <summary>
  8. /// Custom inspector for <see cref="PlayerInputManager"/>.
  9. /// </summary>
  10. [CustomEditor(typeof(PlayerInputManager))]
  11. internal class PlayerInputManagerEditor : UnityEditor.Editor
  12. {
  13. public void OnEnable()
  14. {
  15. InputUser.onChange += OnUserChange;
  16. }
  17. public void OnDestroy()
  18. {
  19. InputUser.onChange -= OnUserChange;
  20. }
  21. private void OnUserChange(InputUser user, InputUserChange change, InputDevice device)
  22. {
  23. Repaint();
  24. }
  25. public override void OnInspectorGUI()
  26. {
  27. ////TODO: cache properties
  28. EditorGUI.BeginChangeCheck();
  29. DoNotificationSectionUI();
  30. EditorGUILayout.Space();
  31. DoJoinSectionUI();
  32. EditorGUILayout.Space();
  33. DoSplitScreenSectionUI();
  34. if (EditorGUI.EndChangeCheck())
  35. serializedObject.ApplyModifiedProperties();
  36. if (EditorApplication.isPlaying)
  37. DoDebugUI();
  38. }
  39. private void DoNotificationSectionUI()
  40. {
  41. var notificationBehaviorProperty = serializedObject.FindProperty("m_NotificationBehavior");
  42. EditorGUILayout.PropertyField(notificationBehaviorProperty);
  43. switch ((PlayerNotifications)notificationBehaviorProperty.intValue)
  44. {
  45. case PlayerNotifications.SendMessages:
  46. if (m_SendMessagesHelpText == null)
  47. m_SendMessagesHelpText = EditorGUIUtility.TrTextContent(
  48. $"Will SendMessage() to GameObject: " + string.Join(",", PlayerInputManager.messages));
  49. EditorGUILayout.HelpBox(m_SendMessagesHelpText);
  50. break;
  51. case PlayerNotifications.BroadcastMessages:
  52. if (m_BroadcastMessagesHelpText == null)
  53. m_BroadcastMessagesHelpText = EditorGUIUtility.TrTextContent(
  54. $"Will BroadcastMessage() to GameObject: " + string.Join(",", PlayerInputManager.messages));
  55. EditorGUILayout.HelpBox(m_BroadcastMessagesHelpText);
  56. break;
  57. case PlayerNotifications.InvokeUnityEvents:
  58. m_EventsExpanded = EditorGUILayout.Foldout(m_EventsExpanded, m_EventsLabel, toggleOnLabelClick: true);
  59. if (m_EventsExpanded)
  60. {
  61. var playerJoinedEventProperty = serializedObject.FindProperty("m_PlayerJoinedEvent");
  62. var playerLeftEventProperty = serializedObject.FindProperty("m_PlayerLeftEvent");
  63. EditorGUILayout.PropertyField(playerJoinedEventProperty);
  64. EditorGUILayout.PropertyField(playerLeftEventProperty);
  65. }
  66. break;
  67. }
  68. }
  69. private void DoJoinSectionUI()
  70. {
  71. EditorGUILayout.LabelField(m_JoiningGroupLabel, EditorStyles.boldLabel);
  72. // Join behavior
  73. var joinBehaviorProperty = serializedObject.FindProperty("m_JoinBehavior");
  74. EditorGUILayout.PropertyField(joinBehaviorProperty);
  75. if ((PlayerJoinBehavior)joinBehaviorProperty.intValue != PlayerJoinBehavior.JoinPlayersManually)
  76. {
  77. ++EditorGUI.indentLevel;
  78. // Join action.
  79. if ((PlayerJoinBehavior)joinBehaviorProperty.intValue ==
  80. PlayerJoinBehavior.JoinPlayersWhenJoinActionIsTriggered)
  81. {
  82. var joinActionProperty = serializedObject.FindProperty("m_JoinAction");
  83. EditorGUILayout.PropertyField(joinActionProperty);
  84. }
  85. // Player prefab.
  86. var playerPrefabProperty = serializedObject.FindProperty("m_PlayerPrefab");
  87. EditorGUILayout.PropertyField(playerPrefabProperty);
  88. --EditorGUI.indentLevel;
  89. }
  90. // Enabled-by-default.
  91. var allowJoiningProperty = serializedObject.FindProperty("m_AllowJoining");
  92. if (m_AllowingJoiningLabel == null)
  93. m_AllowingJoiningLabel = new GUIContent("Joining Enabled By Default", allowJoiningProperty.tooltip);
  94. EditorGUILayout.PropertyField(allowJoiningProperty, m_AllowingJoiningLabel);
  95. // Max player count.
  96. var maxPlayerCountProperty = serializedObject.FindProperty("m_MaxPlayerCount");
  97. if (maxPlayerCountProperty.intValue > 0)
  98. m_MaxPlayerCountEnabled = true;
  99. m_MaxPlayerCountEnabled = EditorGUILayout.Toggle(m_EnableMaxPlayerCountLabel, m_MaxPlayerCountEnabled);
  100. if (m_MaxPlayerCountEnabled)
  101. {
  102. ++EditorGUI.indentLevel;
  103. if (maxPlayerCountProperty.intValue < 0)
  104. maxPlayerCountProperty.intValue = 1;
  105. EditorGUILayout.PropertyField(maxPlayerCountProperty);
  106. --EditorGUI.indentLevel;
  107. }
  108. else
  109. maxPlayerCountProperty.intValue = -1;
  110. }
  111. private void DoSplitScreenSectionUI()
  112. {
  113. EditorGUILayout.LabelField(m_SplitScreenGroupLabel, EditorStyles.boldLabel);
  114. // Split-screen toggle.
  115. var splitScreenProperty = serializedObject.FindProperty("m_SplitScreen");
  116. if (m_SplitScreenLabel == null)
  117. m_SplitScreenLabel = new GUIContent("Enable Split-Screen", splitScreenProperty.tooltip);
  118. EditorGUILayout.PropertyField(splitScreenProperty, m_SplitScreenLabel);
  119. if (!splitScreenProperty.boolValue)
  120. return;
  121. ++EditorGUI.indentLevel;
  122. // Maintain-aspect-ratio toggle.
  123. var maintainAspectRatioProperty = serializedObject.FindProperty("m_MaintainAspectRatioInSplitScreen");
  124. if (m_MaintainAspectRatioLabel == null)
  125. m_MaintainAspectRatioLabel =
  126. new GUIContent("Maintain Aspect Ratio", maintainAspectRatioProperty.tooltip);
  127. EditorGUILayout.PropertyField(maintainAspectRatioProperty, m_MaintainAspectRatioLabel);
  128. // Fixed-number toggle.
  129. var fixedNumberProperty = serializedObject.FindProperty("m_FixedNumberOfSplitScreens");
  130. if (fixedNumberProperty.intValue > 0)
  131. m_FixedNumberOfSplitScreensEnabled = true;
  132. m_FixedNumberOfSplitScreensEnabled = EditorGUILayout.Toggle(m_EnableFixedNumberOfSplitScreensLabel,
  133. m_FixedNumberOfSplitScreensEnabled);
  134. if (m_FixedNumberOfSplitScreensEnabled)
  135. {
  136. ++EditorGUI.indentLevel;
  137. if (fixedNumberProperty.intValue < 0)
  138. fixedNumberProperty.intValue = 4;
  139. if (m_FixedNumberOfSplitScreensLabel == null)
  140. m_FixedNumberOfSplitScreensLabel = EditorGUIUtility.TrTextContent("Number of Screens",
  141. fixedNumberProperty.tooltip);
  142. EditorGUILayout.PropertyField(fixedNumberProperty, m_FixedNumberOfSplitScreensLabel);
  143. --EditorGUI.indentLevel;
  144. }
  145. else
  146. {
  147. fixedNumberProperty.intValue = -1;
  148. }
  149. // Split-screen area.
  150. var splitScreenAreaProperty = serializedObject.FindProperty("m_SplitScreenRect");
  151. if (m_SplitScreenAreaLabel == null)
  152. m_SplitScreenAreaLabel = new GUIContent("Screen Rectangle", splitScreenAreaProperty.tooltip);
  153. EditorGUILayout.PropertyField(splitScreenAreaProperty, m_SplitScreenAreaLabel);
  154. --EditorGUI.indentLevel;
  155. }
  156. private void DoDebugUI()
  157. {
  158. EditorGUILayout.Space();
  159. EditorGUILayout.LabelField(m_DebugLabel, EditorStyles.boldLabel);
  160. EditorGUI.BeginDisabledGroup(true);
  161. var players = PlayerInput.all;
  162. if (players.Count == 0)
  163. {
  164. EditorGUILayout.LabelField("No Players");
  165. }
  166. else
  167. {
  168. foreach (var player in players)
  169. {
  170. var str = player.gameObject.name;
  171. if (player.splitScreenIndex != -1)
  172. str += $" (Screen #{player.splitScreenIndex})";
  173. EditorGUILayout.LabelField("Player #" + player.playerIndex, str);
  174. }
  175. }
  176. EditorGUI.EndDisabledGroup();
  177. }
  178. [SerializeField] private bool m_EventsExpanded;
  179. [SerializeField] private bool m_MaxPlayerCountEnabled;
  180. [SerializeField] private bool m_FixedNumberOfSplitScreensEnabled;
  181. [NonSerialized] private readonly GUIContent m_JoiningGroupLabel = EditorGUIUtility.TrTextContent("Joining");
  182. [NonSerialized] private readonly GUIContent m_SplitScreenGroupLabel = EditorGUIUtility.TrTextContent("Split-Screen");
  183. [NonSerialized] private readonly GUIContent m_EventsLabel = EditorGUIUtility.TrTextContent("Events");
  184. [NonSerialized] private readonly GUIContent m_DebugLabel = EditorGUIUtility.TrTextContent("Debug");
  185. [NonSerialized] private GUIContent m_SendMessagesHelpText;
  186. [NonSerialized] private GUIContent m_BroadcastMessagesHelpText;
  187. [NonSerialized] private GUIContent m_AllowingJoiningLabel;
  188. [NonSerialized] private GUIContent m_SplitScreenLabel;
  189. [NonSerialized] private GUIContent m_MaintainAspectRatioLabel;
  190. [NonSerialized] private GUIContent m_SplitScreenAreaLabel;
  191. [NonSerialized] private GUIContent m_FixedNumberOfSplitScreensLabel;
  192. [NonSerialized] private readonly GUIContent m_EnableMaxPlayerCountLabel =
  193. EditorGUIUtility.TrTextContent("Limit Number of Players", "TODO");
  194. [NonSerialized] private readonly GUIContent m_EnableFixedNumberOfSplitScreensLabel =
  195. EditorGUIUtility.TrTextContent("Set Fixed Number", "TODO");
  196. }
  197. }
  198. #endif // UNITY_EDITOR