123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- #if UNITY_EDITOR
- using System;
- using System.Linq;
- using UnityEditor;
- using UnityEngine.InputSystem.Users;
-
- namespace UnityEngine.InputSystem.Editor
- {
- /// <summary>
- /// Custom inspector for <see cref="PlayerInputManager"/>.
- /// </summary>
- [CustomEditor(typeof(PlayerInputManager))]
- internal class PlayerInputManagerEditor : UnityEditor.Editor
- {
- public void OnEnable()
- {
- InputUser.onChange += OnUserChange;
- }
-
- public void OnDestroy()
- {
- InputUser.onChange -= OnUserChange;
- }
-
- private void OnUserChange(InputUser user, InputUserChange change, InputDevice device)
- {
- Repaint();
- }
-
- public override void OnInspectorGUI()
- {
- ////TODO: cache properties
-
- EditorGUI.BeginChangeCheck();
-
- DoNotificationSectionUI();
- EditorGUILayout.Space();
- DoJoinSectionUI();
- EditorGUILayout.Space();
- DoSplitScreenSectionUI();
-
- if (EditorGUI.EndChangeCheck())
- serializedObject.ApplyModifiedProperties();
-
- if (EditorApplication.isPlaying)
- DoDebugUI();
- }
-
- private void DoNotificationSectionUI()
- {
- var notificationBehaviorProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_NotificationBehavior));
- EditorGUILayout.PropertyField(notificationBehaviorProperty);
- switch ((PlayerNotifications)notificationBehaviorProperty.intValue)
- {
- case PlayerNotifications.SendMessages:
- if (m_SendMessagesHelpText == null)
- m_SendMessagesHelpText = EditorGUIUtility.TrTextContent(
- $"Will SendMessage() to GameObject: " + string.Join(",", PlayerInputManager.messages));
- EditorGUILayout.HelpBox(m_SendMessagesHelpText);
- break;
-
- case PlayerNotifications.BroadcastMessages:
- if (m_BroadcastMessagesHelpText == null)
- m_BroadcastMessagesHelpText = EditorGUIUtility.TrTextContent(
- $"Will BroadcastMessage() to GameObject: " + string.Join(",", PlayerInputManager.messages));
- EditorGUILayout.HelpBox(m_BroadcastMessagesHelpText);
- break;
-
- case PlayerNotifications.InvokeUnityEvents:
- m_EventsExpanded = EditorGUILayout.Foldout(m_EventsExpanded, m_EventsLabel, toggleOnLabelClick: true);
- if (m_EventsExpanded)
- {
- var playerJoinedEventProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_PlayerJoinedEvent));
- var playerLeftEventProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_PlayerLeftEvent));
-
- EditorGUILayout.PropertyField(playerJoinedEventProperty);
- EditorGUILayout.PropertyField(playerLeftEventProperty);
- }
- break;
- }
- }
-
- private void DoJoinSectionUI()
- {
- EditorGUILayout.LabelField(m_JoiningGroupLabel, EditorStyles.boldLabel);
-
- // Join behavior
- var joinBehaviorProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_JoinBehavior));
- EditorGUILayout.PropertyField(joinBehaviorProperty);
- if ((PlayerJoinBehavior)joinBehaviorProperty.intValue != PlayerJoinBehavior.JoinPlayersManually)
- {
- ++EditorGUI.indentLevel;
-
- // Join action.
- if ((PlayerJoinBehavior)joinBehaviorProperty.intValue ==
- PlayerJoinBehavior.JoinPlayersWhenJoinActionIsTriggered)
- {
- var joinActionProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_JoinAction));
- EditorGUILayout.PropertyField(joinActionProperty);
- }
-
- // Player prefab.
- var playerPrefabProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_PlayerPrefab));
- EditorGUILayout.PropertyField(playerPrefabProperty);
-
- ValidatePlayerPrefab(joinBehaviorProperty, playerPrefabProperty);
-
- --EditorGUI.indentLevel;
- }
-
- // Enabled-by-default.
- var allowJoiningProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_AllowJoining));
- if (m_AllowingJoiningLabel == null)
- m_AllowingJoiningLabel = new GUIContent("Joining Enabled By Default", allowJoiningProperty.GetTooltip());
- EditorGUILayout.PropertyField(allowJoiningProperty, m_AllowingJoiningLabel);
-
- // Max player count.
- var maxPlayerCountProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_MaxPlayerCount));
- if (m_EnableMaxPlayerCountLabel == null)
- m_EnableMaxPlayerCountLabel = EditorGUIUtility.TrTextContent("Limit Number of Players", maxPlayerCountProperty.GetTooltip());
- if (maxPlayerCountProperty.intValue > 0)
- m_MaxPlayerCountEnabled = true;
- m_MaxPlayerCountEnabled = EditorGUILayout.Toggle(m_EnableMaxPlayerCountLabel, m_MaxPlayerCountEnabled);
- if (m_MaxPlayerCountEnabled)
- {
- ++EditorGUI.indentLevel;
- if (maxPlayerCountProperty.intValue < 0)
- maxPlayerCountProperty.intValue = 1;
- EditorGUILayout.PropertyField(maxPlayerCountProperty);
- --EditorGUI.indentLevel;
- }
- else
- maxPlayerCountProperty.intValue = -1;
- }
-
- private static void ValidatePlayerPrefab(SerializedProperty joinBehaviorProperty,
- SerializedProperty playerPrefabProperty)
- {
- if ((PlayerJoinBehavior)joinBehaviorProperty.intValue != PlayerJoinBehavior.JoinPlayersWhenButtonIsPressed)
- return;
-
- if (playerPrefabProperty.objectReferenceValue == null)
- return;
-
- var playerInput = ((GameObject)playerPrefabProperty.objectReferenceValue)
- .GetComponentInChildren<PlayerInput>();
-
- if (playerInput == null)
- {
- EditorGUILayout.HelpBox("No PlayerInput component found in player prefab.", MessageType.Info);
- return;
- }
-
- if (playerInput.actions == null)
- {
- EditorGUILayout.HelpBox("PlayerInput component has no input action asset assigned.", MessageType.Info);
- return;
- }
-
- if (playerInput.actions.controlSchemes.Any(c => c.deviceRequirements.Count > 0) == false)
- EditorGUILayout.HelpBox("Join Players When Button Is Pressed behavior will not work when the Input Action Asset " +
- "assigned to the PlayerInput component has no required devices in any control scheme.",
- MessageType.Info);
- }
-
- private void DoSplitScreenSectionUI()
- {
- EditorGUILayout.LabelField(m_SplitScreenGroupLabel, EditorStyles.boldLabel);
-
- // Split-screen toggle.
- var splitScreenProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_SplitScreen));
- if (m_SplitScreenLabel == null)
- m_SplitScreenLabel = new GUIContent("Enable Split-Screen", splitScreenProperty.GetTooltip());
- EditorGUILayout.PropertyField(splitScreenProperty, m_SplitScreenLabel);
- if (!splitScreenProperty.boolValue)
- return;
-
- ++EditorGUI.indentLevel;
-
- // Maintain-aspect-ratio toggle.
- var maintainAspectRatioProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_MaintainAspectRatioInSplitScreen));
- if (m_MaintainAspectRatioLabel == null)
- m_MaintainAspectRatioLabel =
- new GUIContent("Maintain Aspect Ratio", maintainAspectRatioProperty.GetTooltip());
- EditorGUILayout.PropertyField(maintainAspectRatioProperty, m_MaintainAspectRatioLabel);
-
- // Fixed-number toggle.
- var fixedNumberProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_FixedNumberOfSplitScreens));
- if (m_EnableFixedNumberOfSplitScreensLabel == null)
- m_EnableFixedNumberOfSplitScreensLabel = EditorGUIUtility.TrTextContent("Set Fixed Number", fixedNumberProperty.GetTooltip());
- if (fixedNumberProperty.intValue > 0)
- m_FixedNumberOfSplitScreensEnabled = true;
- m_FixedNumberOfSplitScreensEnabled = EditorGUILayout.Toggle(m_EnableFixedNumberOfSplitScreensLabel,
- m_FixedNumberOfSplitScreensEnabled);
- if (m_FixedNumberOfSplitScreensEnabled)
- {
- ++EditorGUI.indentLevel;
- if (fixedNumberProperty.intValue < 0)
- fixedNumberProperty.intValue = 4;
- if (m_FixedNumberOfSplitScreensLabel == null)
- m_FixedNumberOfSplitScreensLabel = EditorGUIUtility.TrTextContent("Number of Screens",
- fixedNumberProperty.tooltip);
- EditorGUILayout.PropertyField(fixedNumberProperty, m_FixedNumberOfSplitScreensLabel);
- --EditorGUI.indentLevel;
- }
- else
- {
- fixedNumberProperty.intValue = -1;
- }
-
- // Split-screen area.
- var splitScreenAreaProperty = serializedObject.FindProperty(nameof(PlayerInputManager.m_SplitScreenRect));
- if (m_SplitScreenAreaLabel == null)
- m_SplitScreenAreaLabel = new GUIContent("Screen Rectangle", splitScreenAreaProperty.GetTooltip());
- EditorGUILayout.PropertyField(splitScreenAreaProperty, m_SplitScreenAreaLabel);
-
- --EditorGUI.indentLevel;
- }
-
- private void DoDebugUI()
- {
- EditorGUILayout.Space();
- EditorGUILayout.LabelField(m_DebugLabel, EditorStyles.boldLabel);
- EditorGUI.BeginDisabledGroup(true);
-
- var players = PlayerInput.all;
- if (players.Count == 0)
- {
- EditorGUILayout.LabelField("No Players");
- }
- else
- {
- foreach (var player in players)
- {
- var str = player.gameObject.name;
- if (player.splitScreenIndex != -1)
- str += $" (Screen #{player.splitScreenIndex})";
- EditorGUILayout.LabelField("Player #" + player.playerIndex, str);
- }
- }
- EditorGUI.EndDisabledGroup();
- }
-
- [SerializeField] private bool m_EventsExpanded;
- [SerializeField] private bool m_MaxPlayerCountEnabled;
- [SerializeField] private bool m_FixedNumberOfSplitScreensEnabled;
-
- [NonSerialized] private readonly GUIContent m_JoiningGroupLabel = EditorGUIUtility.TrTextContent("Joining");
- [NonSerialized] private readonly GUIContent m_SplitScreenGroupLabel = EditorGUIUtility.TrTextContent("Split-Screen");
- [NonSerialized] private readonly GUIContent m_EventsLabel = EditorGUIUtility.TrTextContent("Events");
- [NonSerialized] private readonly GUIContent m_DebugLabel = EditorGUIUtility.TrTextContent("Debug");
- [NonSerialized] private GUIContent m_SendMessagesHelpText;
- [NonSerialized] private GUIContent m_BroadcastMessagesHelpText;
- [NonSerialized] private GUIContent m_AllowingJoiningLabel;
- [NonSerialized] private GUIContent m_SplitScreenLabel;
- [NonSerialized] private GUIContent m_MaintainAspectRatioLabel;
- [NonSerialized] private GUIContent m_SplitScreenAreaLabel;
- [NonSerialized] private GUIContent m_FixedNumberOfSplitScreensLabel;
- [NonSerialized] private GUIContent m_EnableMaxPlayerCountLabel;
- [NonSerialized] private GUIContent m_EnableFixedNumberOfSplitScreensLabel;
- }
- }
- #endif // UNITY_EDITOR
|