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