A game about forced loneliness, made by TACStudios
1#if UNITY_EDITOR
2using System;
3using System.Collections.Generic;
4using System.IO;
5using System.Linq;
6using System.Text;
7using UnityEditor;
8using UnityEngine.InputSystem.Users;
9using UnityEngine.InputSystem.Utilities;
10
11#if UNITY_INPUT_SYSTEM_ENABLE_UI
12using UnityEngine.InputSystem.UI;
13using UnityEngine.InputSystem.UI.Editor;
14#endif
15
16////TODO: detect if new input system isn't enabled and provide UI to enable it
17#pragma warning disable 0414
18namespace UnityEngine.InputSystem.Editor
19{
20 /// <summary>
21 /// A custom inspector for the <see cref="PlayerInput"/> component.
22 /// </summary>
23 [CustomEditor(typeof(PlayerInput))]
24 internal class PlayerInputEditor : UnityEditor.Editor
25 {
26 public const string kDefaultInputActionsAssetPath =
27 "Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/DefaultInputActions.inputactions";
28
29 public void OnEnable()
30 {
31 InputActionImporter.onImport += Refresh;
32 InputUser.onChange += OnUserChange;
33
34 // Look up properties.
35 m_ActionsProperty = serializedObject.FindProperty(nameof(PlayerInput.m_Actions));
36 m_DefaultControlSchemeProperty = serializedObject.FindProperty(nameof(PlayerInput.m_DefaultControlScheme));
37 m_NeverAutoSwitchControlSchemesProperty = serializedObject.FindProperty(nameof(PlayerInput.m_NeverAutoSwitchControlSchemes));
38 m_DefaultActionMapProperty = serializedObject.FindProperty(nameof(PlayerInput.m_DefaultActionMap));
39 m_NotificationBehaviorProperty = serializedObject.FindProperty(nameof(PlayerInput.m_NotificationBehavior));
40 m_CameraProperty = serializedObject.FindProperty(nameof(PlayerInput.m_Camera));
41 m_ActionEventsProperty = serializedObject.FindProperty(nameof(PlayerInput.m_ActionEvents));
42 m_DeviceLostEventProperty = serializedObject.FindProperty(nameof(PlayerInput.m_DeviceLostEvent));
43 m_DeviceRegainedEventProperty = serializedObject.FindProperty(nameof(PlayerInput.m_DeviceRegainedEvent));
44 m_ControlsChangedEventProperty = serializedObject.FindProperty(nameof(PlayerInput.m_ControlsChangedEvent));
45
46 #if UNITY_INPUT_SYSTEM_ENABLE_UI
47 m_UIInputModuleProperty = serializedObject.FindProperty(nameof(PlayerInput.m_UIInputModule));
48 #endif
49 }
50
51 public void OnDisable()
52 {
53 new InputComponentEditorAnalytic(InputSystemComponent.PlayerInput).Send();
54 new PlayerInputEditorAnalytic(this).Send();
55 }
56
57 public void OnDestroy()
58 {
59 InputActionImporter.onImport -= Refresh;
60 InputUser.onChange -= OnUserChange;
61 }
62
63 private void Refresh()
64 {
65 ////FIXME: doesn't seem like we're picking up the results of the latest import
66 m_ActionAssetInitialized = false;
67 Repaint();
68 }
69
70 private void OnUserChange(InputUser user, InputUserChange change, InputDevice device)
71 {
72 Repaint();
73 }
74
75 public override void OnInspectorGUI()
76 {
77 EditorGUI.BeginChangeCheck();
78
79 // Action config section.
80 EditorGUI.BeginChangeCheck();
81 EditorGUILayout.PropertyField(m_ActionsProperty);
82 var actionsWereChanged = false;
83 if (EditorGUI.EndChangeCheck() || !m_ActionAssetInitialized || CheckIfActionAssetChanged())
84 {
85 OnActionAssetChange();
86 actionsWereChanged = true;
87 }
88
89 ++EditorGUI.indentLevel;
90 if (m_ControlSchemeOptions != null && m_ControlSchemeOptions.Length > 1) // Don't show if <Any> is the only option.
91 {
92 // Default control scheme picker.
93 Color currentBg = GUI.backgroundColor;
94 // if the invalid DefaultControlSchemeName is selected set the popup draw the BG color in red
95 if (m_InvalidDefaultControlSchemeName != null && m_SelectedDefaultControlScheme == 1)
96 GUI.backgroundColor = Color.red;
97
98 var rect = EditorGUILayout.GetControlRect();
99 var label = EditorGUI.BeginProperty(rect, m_DefaultControlSchemeText, m_DefaultControlSchemeProperty);
100 var selected = EditorGUI.Popup(rect, label, m_SelectedDefaultControlScheme, m_ControlSchemeOptions);
101 EditorGUI.EndProperty();
102 if (selected != m_SelectedDefaultControlScheme)
103 {
104 if (selected == 0)
105 {
106 m_DefaultControlSchemeProperty.stringValue = null;
107 }
108 // if there is an invalid default scheme name it will be at rank 1.
109 // we use m_InvalidDefaultControlSchemeName to prevent usage of the string with "name<Not Found>"
110 else if (m_InvalidDefaultControlSchemeName != null && selected == 1)
111 {
112 m_DefaultControlSchemeProperty.stringValue = m_InvalidDefaultControlSchemeName;
113 }
114 else
115 {
116 m_DefaultControlSchemeProperty.stringValue = m_ControlSchemeOptions[selected].text;
117 }
118 m_SelectedDefaultControlScheme = selected;
119 }
120 // Restore the initial color
121 GUI.backgroundColor = currentBg;
122
123
124 rect = EditorGUILayout.GetControlRect();
125 label = EditorGUI.BeginProperty(rect, m_AutoSwitchText, m_NeverAutoSwitchControlSchemesProperty);
126 var neverAutoSwitchValueOld = m_NeverAutoSwitchControlSchemesProperty.boolValue;
127 var neverAutoSwitchValueNew = !EditorGUI.Toggle(rect, label, !neverAutoSwitchValueOld);
128 EditorGUI.EndProperty();
129 if (neverAutoSwitchValueOld != neverAutoSwitchValueNew)
130 {
131 m_NeverAutoSwitchControlSchemesProperty.boolValue = neverAutoSwitchValueNew;
132 serializedObject.ApplyModifiedProperties();
133 }
134 }
135 if (m_ActionMapOptions != null && m_ActionMapOptions.Length > 0)
136 {
137 // Default action map picker.
138 var rect = EditorGUILayout.GetControlRect();
139 var label = EditorGUI.BeginProperty(rect, m_DefaultActionMapText, m_DefaultActionMapProperty);
140 var selected = EditorGUI.Popup(rect, label, m_SelectedDefaultActionMap,
141 m_ActionMapOptions);
142 EditorGUI.EndProperty();
143 if (selected != m_SelectedDefaultActionMap)
144 {
145 if (selected == 0)
146 {
147 m_DefaultActionMapProperty.stringValue = null;
148 }
149 else
150 {
151 // Use ID rather than name.
152 var asset = (InputActionAsset)m_ActionsProperty.objectReferenceValue;
153 var actionMap = asset.FindActionMap(m_ActionMapOptions[selected].text);
154 if (actionMap != null)
155 m_DefaultActionMapProperty.stringValue = actionMap.id.ToString();
156 }
157 m_SelectedDefaultActionMap = selected;
158 }
159 }
160 --EditorGUI.indentLevel;
161 DoHelpCreateAssetUI();
162
163 #if UNITY_INPUT_SYSTEM_ENABLE_UI
164 // UI config section.
165 if (m_UIPropertyText == null)
166 m_UIPropertyText = EditorGUIUtility.TrTextContent("UI Input Module", m_UIInputModuleProperty.GetTooltip());
167 EditorGUI.BeginChangeCheck();
168 EditorGUILayout.PropertyField(m_UIInputModuleProperty, m_UIPropertyText);
169 if (EditorGUI.EndChangeCheck())
170 serializedObject.ApplyModifiedProperties();
171
172 if (m_UIInputModuleProperty.objectReferenceValue != null)
173 {
174 var uiModule = m_UIInputModuleProperty.objectReferenceValue as InputSystemUIInputModule;
175 if (m_ActionsProperty.objectReferenceValue != null && uiModule.actionsAsset != m_ActionsProperty.objectReferenceValue)
176 {
177 EditorGUILayout.HelpBox("The referenced InputSystemUIInputModule is configured using different input actions than this PlayerInput. They should match if you want to synchronize PlayerInput actions to the UI input.", MessageType.Warning);
178 if (GUILayout.Button(m_FixInputModuleText))
179 InputSystemUIInputModuleEditor.ReassignActions(uiModule, m_ActionsProperty.objectReferenceValue as InputActionAsset);
180 }
181 }
182 #endif
183
184 // Camera section.
185 if (m_CameraPropertyText == null)
186 m_CameraPropertyText = EditorGUIUtility.TrTextContent("Camera", m_CameraProperty.GetTooltip());
187 EditorGUI.BeginChangeCheck();
188 EditorGUILayout.PropertyField(m_CameraProperty, m_CameraPropertyText);
189 if (EditorGUI.EndChangeCheck())
190 serializedObject.ApplyModifiedProperties();
191
192 // Notifications/event section.
193 EditorGUI.BeginChangeCheck();
194 EditorGUILayout.PropertyField(m_NotificationBehaviorProperty, m_NotificationBehaviorText);
195 if (EditorGUI.EndChangeCheck() || actionsWereChanged || !m_NotificationBehaviorInitialized)
196 OnNotificationBehaviorChange();
197 switch ((PlayerNotifications)m_NotificationBehaviorProperty.intValue)
198 {
199 case PlayerNotifications.SendMessages:
200 case PlayerNotifications.BroadcastMessages:
201 Debug.Assert(m_SendMessagesHelpText != null);
202 EditorGUILayout.HelpBox(m_SendMessagesHelpText);
203 break;
204
205 case PlayerNotifications.InvokeUnityEvents:
206 m_EventsGroupUnfolded = EditorGUILayout.Foldout(m_EventsGroupUnfolded, m_EventsGroupText, toggleOnLabelClick: true);
207 if (m_EventsGroupUnfolded)
208 {
209 // Action events. Group by action map.
210 if (m_ActionNames != null)
211 {
212 using (new EditorGUI.IndentLevelScope())
213 {
214 for (var n = 0; n < m_NumActionMaps; ++n)
215 {
216 // Skip action maps that have no names (case 1317735).
217 if (m_ActionMapNames[n] == null)
218 continue;
219
220 m_ActionMapEventsUnfolded[n] = EditorGUILayout.Foldout(m_ActionMapEventsUnfolded[n],
221 m_ActionMapNames[n], toggleOnLabelClick: true);
222 using (new EditorGUI.IndentLevelScope())
223 {
224 if (m_ActionMapEventsUnfolded[n])
225 {
226 for (var i = 0; i < m_ActionNames.Length; ++i)
227 {
228 if (m_ActionMapIndices[i] != n)
229 continue;
230
231 EditorGUILayout.PropertyField(m_ActionEventsProperty.GetArrayElementAtIndex(i), m_ActionNames[i]);
232 }
233 }
234 }
235 }
236 }
237 }
238
239 // Misc events.
240 EditorGUILayout.PropertyField(m_DeviceLostEventProperty);
241 EditorGUILayout.PropertyField(m_DeviceRegainedEventProperty);
242 EditorGUILayout.PropertyField(m_ControlsChangedEventProperty);
243 }
244 break;
245 }
246
247 // Miscellaneous buttons.
248 DoUtilityButtonsUI();
249
250 if (EditorGUI.EndChangeCheck())
251 serializedObject.ApplyModifiedProperties();
252
253 // Debug UI.
254 if (EditorApplication.isPlaying)
255 DoDebugUI();
256 }
257
258 // This checks changes that are not captured by BeginChangeCheck/EndChangeCheck.
259 // One such case is when the user triggers a "Reset" on the component.
260 bool CheckIfActionAssetChanged()
261 {
262 if (m_ActionsProperty.objectReferenceValue != null)
263 {
264 var assetInstanceID = m_ActionsProperty.objectReferenceValue.GetInstanceID();
265 bool result = assetInstanceID != m_ActionAssetInstanceID;
266 m_ActionAssetInstanceID = (int)assetInstanceID;
267 return result;
268 }
269
270 m_ActionAssetInstanceID = -1;
271 return false;
272 }
273
274 private void DoHelpCreateAssetUI()
275 {
276 if (m_ActionsProperty.objectReferenceValue != null)
277 {
278 // All good. We already have an asset.
279 return;
280 }
281
282 EditorGUILayout.HelpBox("There are no input actions associated with this input component yet. Click the button below to create "
283 + "a new set of input actions or drag an existing input actions asset into the field above.", MessageType.Info);
284 EditorGUILayout.BeginHorizontal();
285 EditorGUILayout.Space();
286 if (GUILayout.Button(m_CreateActionsText, EditorStyles.miniButton, GUILayout.MaxWidth(120)))
287 {
288 // Request save file location.
289 var defaultFileName = Application.productName;
290 var fileName = EditorUtility.SaveFilePanel("Create Input Actions Asset", "Assets", defaultFileName,
291 InputActionAsset.Extension);
292
293 ////TODO: take current Supported Devices into account when creating this
294
295 // Create and import asset and open editor.
296 if (!string.IsNullOrEmpty(fileName))
297 {
298 if (!fileName.StartsWith(Application.dataPath))
299 {
300 Debug.LogError($"Path must be located in Assets/ folder (got: '{fileName}')");
301 EditorGUILayout.EndHorizontal();
302 return;
303 }
304
305 if (!fileName.EndsWith("." + InputActionAsset.Extension))
306 fileName += "." + InputActionAsset.Extension;
307
308 // Load default actions and update all GUIDs.
309 var defaultActionsText = File.ReadAllText(kDefaultInputActionsAssetPath);
310 var newActions = InputActionAsset.FromJson(defaultActionsText);
311 foreach (var map in newActions.actionMaps)
312 {
313 map.m_Id = Guid.NewGuid().ToString();
314 foreach (var action in map.actions)
315 action.m_Id = Guid.NewGuid().ToString();
316 }
317 newActions.name = Path.GetFileNameWithoutExtension(fileName);
318 var newActionsText = newActions.ToJson();
319
320 // Write it out and tell the asset DB to pick it up.
321 File.WriteAllText(fileName, newActionsText);
322
323 // Import the new asset
324 var relativePath = "Assets/" + fileName.Substring(Application.dataPath.Length + 1);
325 AssetDatabase.ImportAsset(relativePath, ImportAssetOptions.ForceSynchronousImport);
326
327 // Load imported object.
328 var importedObject = AssetDatabase.LoadAssetAtPath<InputActionAsset>(relativePath);
329
330 // Set it on the PlayerInput component.
331 m_ActionsProperty.objectReferenceValue = importedObject;
332 serializedObject.ApplyModifiedProperties();
333
334 // Open the asset.
335 AssetDatabase.OpenAsset(importedObject);
336 }
337 }
338 EditorGUILayout.EndHorizontal();
339 EditorGUILayout.Separator();
340 }
341
342 private void DoUtilityButtonsUI()
343 {
344 EditorGUILayout.BeginHorizontal();
345
346 if (GUILayout.Button(m_OpenSettingsText, EditorStyles.miniButton))
347 InputSettingsProvider.Open();
348
349 if (GUILayout.Button(m_OpenDebuggerText, EditorStyles.miniButton))
350 InputDebuggerWindow.CreateOrShow();
351
352 EditorGUILayout.EndHorizontal();
353 }
354
355 private void DoDebugUI()
356 {
357 var playerInput = (PlayerInput)target;
358
359 if (!playerInput.user.valid)
360 return;
361
362 ////TODO: show actions when they happen
363
364 var user = playerInput.user.index.ToString();
365 var controlScheme = playerInput.user.controlScheme?.name;
366 var devices = string.Join(", ", playerInput.user.pairedDevices);
367
368 EditorGUILayout.Space();
369 EditorGUILayout.LabelField(m_DebugText, EditorStyles.boldLabel);
370 EditorGUI.BeginDisabledGroup(true);
371 EditorGUILayout.LabelField("User", user);
372 EditorGUILayout.LabelField("Control Scheme", controlScheme);
373 EditorGUILayout.LabelField("Devices", devices);
374 EditorGUI.EndDisabledGroup();
375 }
376
377 private void OnNotificationBehaviorChange()
378 {
379 Debug.Assert(m_ActionAssetInitialized);
380 serializedObject.ApplyModifiedProperties();
381
382 var notificationBehavior = (PlayerNotifications)m_NotificationBehaviorProperty.intValue;
383 switch (notificationBehavior)
384 {
385 // Create text that lists all the messages sent by the component.
386 case PlayerNotifications.BroadcastMessages:
387 case PlayerNotifications.SendMessages:
388 {
389 var builder = new StringBuilder();
390 builder.Append("Will ");
391 if (notificationBehavior == PlayerNotifications.BroadcastMessages)
392 builder.Append("BroadcastMessage()");
393 else
394 builder.Append("SendMessage()");
395 builder.Append(" to GameObject: ");
396 builder.Append(PlayerInput.DeviceLostMessage);
397 builder.Append(", ");
398 builder.Append(PlayerInput.DeviceRegainedMessage);
399 builder.Append(", ");
400 builder.Append(PlayerInput.ControlsChangedMessage);
401
402 var playerInput = (PlayerInput)target;
403 var asset = playerInput.m_Actions;
404 if (asset != null)
405 {
406 foreach (var action in asset)
407 {
408 builder.Append(", On");
409 builder.Append(CSharpCodeHelpers.MakeTypeName(action.name));
410 }
411 }
412
413 m_SendMessagesHelpText = new GUIContent(builder.ToString());
414 break;
415 }
416
417 case PlayerNotifications.InvokeUnityEvents:
418 {
419 var playerInput = (PlayerInput)target;
420 if (playerInput.m_DeviceLostEvent == null)
421 playerInput.m_DeviceLostEvent = new PlayerInput.DeviceLostEvent();
422 if (playerInput.m_DeviceRegainedEvent == null)
423 playerInput.m_DeviceRegainedEvent = new PlayerInput.DeviceRegainedEvent();
424 if (playerInput.m_ControlsChangedEvent == null)
425 playerInput.m_ControlsChangedEvent = new PlayerInput.ControlsChangedEvent();
426 serializedObject.Update();
427
428 // Force action refresh.
429 m_ActionAssetInitialized = false;
430 Refresh();
431 break;
432 }
433 }
434
435 m_NotificationBehaviorInitialized = true;
436 }
437
438 private void OnActionAssetChange()
439 {
440 serializedObject.ApplyModifiedProperties();
441 m_ActionAssetInitialized = true;
442
443 var playerInput = (PlayerInput)target;
444 var asset = (InputActionAsset)m_ActionsProperty.objectReferenceValue;
445 if (asset == null)
446 {
447 m_ControlSchemeOptions = null;
448 m_ActionMapOptions = null;
449 m_ActionNames = null;
450 m_SelectedDefaultActionMap = -1;
451 m_SelectedDefaultControlScheme = -1;
452 m_InvalidDefaultControlSchemeName = null;
453 return;
454 }
455
456 // If we're sending Unity events, read out the event list.
457 if ((PlayerNotifications)m_NotificationBehaviorProperty.intValue ==
458 PlayerNotifications.InvokeUnityEvents)
459 {
460 ////FIXME: this should preserve the same order that we have in the asset
461 var newActionNames = new List<GUIContent>();
462 var newActionEvents = new List<PlayerInput.ActionEvent>();
463 var newActionMapIndices = new List<int>();
464
465 m_NumActionMaps = 0;
466 m_ActionMapNames = null;
467
468 void AddEntry(InputAction action, PlayerInput.ActionEvent actionEvent)
469 {
470 newActionNames.Add(new GUIContent(action.name));
471 newActionEvents.Add(actionEvent);
472
473 var actionMapIndex = asset.actionMaps.IndexOfReference(action.actionMap);
474 newActionMapIndices.Add(actionMapIndex);
475
476 if (actionMapIndex >= m_NumActionMaps)
477 m_NumActionMaps = actionMapIndex + 1;
478
479 ArrayHelpers.PutAtIfNotSet(ref m_ActionMapNames, actionMapIndex,
480 () => new GUIContent(action.actionMap.name));
481 }
482
483 // Bring over any action events that we already have and that are still in the asset.
484 var oldActionEvents = playerInput.m_ActionEvents;
485 if (oldActionEvents != null)
486 {
487 foreach (var entry in oldActionEvents)
488 {
489 var guid = entry.actionId;
490 var action = asset.FindAction(guid);
491 if (action != null)
492 AddEntry(action, entry);
493 }
494 }
495
496 // Add any new actions.
497 foreach (var action in asset)
498 {
499 // Skip if it was already in there.
500 if (oldActionEvents != null && oldActionEvents.Any(x => x.actionId == action.id.ToString()))
501 continue;
502
503 ////FIXME: adds bindings to the name
504 AddEntry(action, new PlayerInput.ActionEvent(action.id, action.ToString()));
505 }
506
507 m_ActionNames = newActionNames.ToArray();
508 m_ActionMapIndices = newActionMapIndices.ToArray();
509 Array.Resize(ref m_ActionMapEventsUnfolded, m_NumActionMaps);
510 playerInput.m_ActionEvents = newActionEvents.ToArray();
511 }
512
513 // Read out control schemes.
514 var selectedDefaultControlScheme = playerInput.defaultControlScheme;
515 m_InvalidDefaultControlSchemeName = null;
516 m_SelectedDefaultControlScheme = 0;
517 ////TODO: sort alphabetically and ensure that the order is the same in the schemes editor
518 var controlSchemesNames = asset.controlSchemes.Select(cs => cs.name).ToList();
519
520 // try to find the selected Default Control Scheme
521 if (!string.IsNullOrEmpty(selectedDefaultControlScheme))
522 {
523 // +1 since <Any> will be the first in the list
524 m_SelectedDefaultControlScheme = 1 + controlSchemesNames.FindIndex(name => string.Compare(name, selectedDefaultControlScheme,
525 StringComparison.InvariantCultureIgnoreCase) == 0);
526 // if not found, will insert the invalid name next to <Any>
527 if (m_SelectedDefaultControlScheme == 0)
528 {
529 m_InvalidDefaultControlSchemeName = selectedDefaultControlScheme;
530 m_SelectedDefaultControlScheme = 1;
531 controlSchemesNames.Insert(0, $"{selectedDefaultControlScheme}{L10n.Tr("<Not Found>")}");
532 }
533 }
534 else
535 {
536 playerInput.defaultControlScheme = null;
537 }
538
539 m_ControlSchemeOptions = new GUIContent[controlSchemesNames.Count + 1];
540 m_ControlSchemeOptions[0] = new GUIContent(EditorGUIUtility.TrTextContent("<Any>"));
541 for (var i = 0; i < controlSchemesNames.Count; ++i)
542 {
543 m_ControlSchemeOptions[i + 1] = new GUIContent(controlSchemesNames[i]);
544 }
545
546 // Read out action maps.
547 var selectedDefaultActionMap = !string.IsNullOrEmpty(playerInput.defaultActionMap)
548 ? asset.FindActionMap(playerInput.defaultActionMap)
549 : null;
550 m_SelectedDefaultActionMap = asset.actionMaps.Count > 0 ? 1 : 0;
551 var actionMaps = asset.actionMaps;
552 m_ActionMapOptions = new GUIContent[actionMaps.Count + 1];
553 m_ActionMapOptions[0] = new GUIContent(EditorGUIUtility.TrTextContent("<None>"));
554 ////TODO: sort alphabetically
555 for (var i = 0; i < actionMaps.Count; ++i)
556 {
557 var actionMap = actionMaps[i];
558 m_ActionMapOptions[i + 1] = new GUIContent(actionMap.name);
559
560 if (selectedDefaultActionMap != null && actionMap == selectedDefaultActionMap)
561 m_SelectedDefaultActionMap = i + 1;
562 }
563 if (m_SelectedDefaultActionMap <= 0)
564 playerInput.defaultActionMap = null;
565 else
566 playerInput.defaultActionMap = m_ActionMapOptions[m_SelectedDefaultActionMap].text;
567
568 serializedObject.Update();
569 }
570
571 [SerializeField] private bool m_EventsGroupUnfolded;
572 [SerializeField] private bool[] m_ActionMapEventsUnfolded;
573
574 [NonSerialized] private readonly GUIContent m_CreateActionsText = EditorGUIUtility.TrTextContent("Create Actions...");
575 [NonSerialized] private readonly GUIContent m_FixInputModuleText = EditorGUIUtility.TrTextContent("Fix UI Input Module");
576 [NonSerialized] private readonly GUIContent m_OpenSettingsText = EditorGUIUtility.TrTextContent("Open Input Settings");
577 [NonSerialized] private readonly GUIContent m_OpenDebuggerText = EditorGUIUtility.TrTextContent("Open Input Debugger");
578 [NonSerialized] private readonly GUIContent m_EventsGroupText =
579 EditorGUIUtility.TrTextContent("Events", "UnityEvents triggered by the PlayerInput component");
580 [NonSerialized] private readonly GUIContent m_NotificationBehaviorText =
581 EditorGUIUtility.TrTextContent("Behavior",
582 "Determine how notifications should be sent when an input-related event associated with the player happens.");
583 [NonSerialized] private readonly GUIContent m_DefaultControlSchemeText =
584 EditorGUIUtility.TrTextContent("Default Scheme", "Which control scheme to try by default. If not set, PlayerInput "
585 + "will simply go through all control schemes in the action asset and try one after the other. If set, PlayerInput will try "
586 + "the given scheme first but if using that fails (e.g. when not required devices are missing) will fall back to trying the other "
587 + "control schemes in order.");
588 [NonSerialized] private readonly GUIContent m_DefaultActionMapText =
589 EditorGUIUtility.TrTextContent("Default Map", "Action map to enable by default. If not set, no actions will be enabled by default.");
590 [NonSerialized] private readonly GUIContent m_AutoSwitchText =
591 EditorGUIUtility.TrTextContent("Auto-Switch",
592 "By default, when there is only a single PlayerInput, the player "
593 + "is allowed to freely switch between control schemes simply by starting to use a different device. By toggling this property off, this "
594 + "behavior is disabled and even with a single player, the player will stay locked onto the explicitly selected control scheme. Note "
595 + "that you can still change control schemes explicitly through the PlayerInput API.\n\nWhen there are multiple PlayerInputs in the game, auto-switching is disabled automatically regardless of the value of this property.");
596 [NonSerialized] private readonly GUIContent m_DebugText = EditorGUIUtility.TrTextContent("Debug");
597 [NonSerialized] private GUIContent m_UIPropertyText;
598 [NonSerialized] private GUIContent m_CameraPropertyText;
599 [NonSerialized] private GUIContent m_SendMessagesHelpText;
600 [NonSerialized] private GUIContent[] m_ActionNames;
601 [NonSerialized] private GUIContent[] m_ActionMapNames;
602 [NonSerialized] private int[] m_ActionMapIndices;
603 [NonSerialized] private int m_NumActionMaps;
604 [NonSerialized] private int m_SelectedDefaultControlScheme;
605 [NonSerialized] private string m_InvalidDefaultControlSchemeName;
606 [NonSerialized] private GUIContent[] m_ControlSchemeOptions;
607 [NonSerialized] private int m_SelectedDefaultActionMap;
608 [NonSerialized] private GUIContent[] m_ActionMapOptions;
609
610 [NonSerialized] private SerializedProperty m_ActionsProperty;
611 [NonSerialized] private SerializedProperty m_DefaultControlSchemeProperty;
612 [NonSerialized] private SerializedProperty m_DefaultActionMapProperty;
613 [NonSerialized] private SerializedProperty m_NeverAutoSwitchControlSchemesProperty;
614 [NonSerialized] private SerializedProperty m_NotificationBehaviorProperty;
615 #if UNITY_INPUT_SYSTEM_ENABLE_UI
616 [NonSerialized] private SerializedProperty m_UIInputModuleProperty;
617 #endif
618 [NonSerialized] private SerializedProperty m_ActionEventsProperty;
619 [NonSerialized] private SerializedProperty m_CameraProperty;
620 [NonSerialized] private SerializedProperty m_DeviceLostEventProperty;
621 [NonSerialized] private SerializedProperty m_DeviceRegainedEventProperty;
622 [NonSerialized] private SerializedProperty m_ControlsChangedEventProperty;
623
624 [NonSerialized] private bool m_NotificationBehaviorInitialized;
625 [NonSerialized] private bool m_ActionAssetInitialized;
626 [NonSerialized] private int m_ActionAssetInstanceID;
627 }
628}
629#endif // UNITY_EDITOR