From e5eed4f90e34706bf410cf8b72e9dc384e9f88a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Thu, 29 Feb 2024 10:00:58 +0100 Subject: [PATCH 1/2] FIX: ISXB-543 GamepadButton property drawer now has consistent behaviour for which aliased enum value is selected and drop-down shows alias mapping. --- Packages/com.unity.inputsystem/CHANGELOG.md | 1 + .../PropertyDrawers/EnumPropertyDrawer.cs | 63 +++++++++++++++++++ .../EnumPropertyDrawer.cs.meta | 2 + .../GamepadButtonPropertyDrawer.cs | 43 +++++++++++++ .../GamepadButtonPropertyDrawer.cs.meta | 3 + 5 files changed, 112 insertions(+) create mode 100644 Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs create mode 100644 Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs.meta create mode 100644 Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/GamepadButtonPropertyDrawer.cs create mode 100644 Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/GamepadButtonPropertyDrawer.cs.meta diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index 85e67099ed..4a5cc7ff96 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -56,6 +56,7 @@ however, it has to be formatted properly to pass verification tests. - Fixed Project Settings header title styling for Input Actions editor. - Fixed Input Actions Editor losing reference to current ControlScheme upon entering Play Mode [ISXB-770](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-770). - Fixed headers in InputActionEditor windows becoming squashed when there is a large number of Action Maps/Actions. +- Fixed an issue where aliased enum values for ´GamepadButton´ would be seemingly randomly picked from an Inspector value picker. This is resolved with a custom property drawer that maps to a designated aliased type. [ISXB-543](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-543). ## [1.8.0-pre.2] - 2023-11-09 diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs new file mode 100644 index 0000000000..ddd4b48929 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs @@ -0,0 +1,63 @@ +#if UNITY_EDITOR + +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEngine.UIElements; + +namespace UnityEngine.InputSystem.Editor +{ + /// + /// Abstract base class for a generic property drawer for aliased enums. + /// + internal abstract class AliasedEnumPropertyDrawer : PropertyDrawer where T : Enum + { + private string[] m_EnumDisplayNames; + + public override VisualElement CreatePropertyGUI(SerializedProperty property) + { + ProcessDisplayNamesForAliasedEnums(); + return base.CreatePropertyGUI(property); + } + + protected abstract string GetNonAliasedNames(string enumValue); + + private void ProcessDisplayNamesForAliasedEnums() + { + var enumNamesAndValues = new Dictionary(); + var enumDisplayNames = Enum.GetNames(typeof(T)); + var enumValues = Enum.GetValues(typeof(T)).Cast().ToArray(); + var enumStringValues = enumValues.Select(v => v.ToString()).ToArray(); + + for (var i = 0; i < enumDisplayNames.Length; ++i) + { + var enumName = enumDisplayNames[i]; + var aliasedName = GetNonAliasedNames(enumStringValues[i]); + if (!string.IsNullOrEmpty(aliasedName) && enumName != aliasedName) + enumName = $"{enumName} ({aliasedName})"; + + enumNamesAndValues.Add(enumName, (int)enumValues.GetValue(i)); + } + + var sortedEntries = enumNamesAndValues + .OrderBy(x => x.Value) + .ThenBy(x => x.Key.Contains("(")); + + m_EnumDisplayNames = sortedEntries.Select(x => x.Key).ToArray(); + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + EditorGUI.BeginProperty(position, label, property); + + if (property.propertyType == SerializedPropertyType.Enum) + { + property.enumValueIndex = EditorGUI.Popup(position, label.text, property.enumValueIndex, m_EnumDisplayNames); + } + + EditorGUI.EndProperty(); + } + } +} + #endif // UNITY_EDITOR diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs.meta new file mode 100644 index 0000000000..3316a21c24 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 578041934f9694948bbdaab9f133b85f \ No newline at end of file diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/GamepadButtonPropertyDrawer.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/GamepadButtonPropertyDrawer.cs new file mode 100644 index 0000000000..3b22fcbb83 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/GamepadButtonPropertyDrawer.cs @@ -0,0 +1,43 @@ +#if UNITY_EDITOR + +using UnityEditor; +using UnityEngine.InputSystem.LowLevel; + +namespace UnityEngine.InputSystem.Editor +{ + /// + /// Property drawer for + /// + [CustomPropertyDrawer(typeof(GamepadButton))] + internal class GpadButtonPropertyDrawer : AliasedEnumPropertyDrawer + { + protected override string GetNonAliasedNames(string name) + { + switch (name) + { + case nameof(GamepadButton.North): + case nameof(GamepadButton.Y): + case nameof(GamepadButton.Triangle): + return nameof(GamepadButton.North); + + case nameof(GamepadButton.South): + case nameof(GamepadButton.A): + case nameof(GamepadButton.Cross): + return nameof(GamepadButton.South); + + case nameof(GamepadButton.East): + case nameof(GamepadButton.B): + case nameof(GamepadButton.Circle): + return nameof(GamepadButton.East); + + case nameof(GamepadButton.West): + case nameof(GamepadButton.X): + case nameof(GamepadButton.Square): + return nameof(GamepadButton.West); + + default: return string.Empty; + } + } + } +} +#endif // UNITY_EDITOR diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/GamepadButtonPropertyDrawer.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/GamepadButtonPropertyDrawer.cs.meta new file mode 100644 index 0000000000..2194273b9d --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/GamepadButtonPropertyDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dbfe7102f5cf44ce875297b9f395dd65 +timeCreated: 1709195897 \ No newline at end of file From c1f4c9e2004fc47641042851006d2f29dc357b06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Thu, 29 Feb 2024 14:01:27 +0100 Subject: [PATCH 2/2] FIX: Removed mix of UITK and IMGUI code in property drawer. Modified to lazily initialize array if lost in domain reload. --- .../Editor/PropertyDrawers/EnumPropertyDrawer.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs index ddd4b48929..262738d754 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/PropertyDrawers/EnumPropertyDrawer.cs @@ -15,15 +15,9 @@ internal abstract class AliasedEnumPropertyDrawer : PropertyDrawer where T : { private string[] m_EnumDisplayNames; - public override VisualElement CreatePropertyGUI(SerializedProperty property) - { - ProcessDisplayNamesForAliasedEnums(); - return base.CreatePropertyGUI(property); - } - protected abstract string GetNonAliasedNames(string enumValue); - private void ProcessDisplayNamesForAliasedEnums() + private void Initialize() { var enumNamesAndValues = new Dictionary(); var enumDisplayNames = Enum.GetNames(typeof(T)); @@ -53,6 +47,9 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten if (property.propertyType == SerializedPropertyType.Enum) { + if (m_EnumDisplayNames == null) + Initialize(); + property.enumValueIndex = EditorGUI.Popup(position, label.text, property.enumValueIndex, m_EnumDisplayNames); }