A game about forced loneliness, made by TACStudios
1#if UNITY_EDITOR
2using System;
3using System.Collections.Generic;
4using System.Linq;
5using UnityEditor;
6using UnityEngine.InputSystem.Controls;
7using UnityEngine.InputSystem.Utilities;
8
9namespace UnityEngine.InputSystem.Editor
10{
11 /// <summary>
12 /// UI that edits the properties of an <see cref="InputAction"/>.
13 /// </summary>
14 /// <remarks>
15 /// Right-most pane in <see cref="InputActionEditorWindow"/> when an action is selected.
16 /// </remarks>
17 internal class InputActionPropertiesView : PropertiesViewBase
18 {
19 public static FourCC k_PropertiesChanged => new FourCC("PROP");
20
21 public InputActionPropertiesView(SerializedProperty actionProperty, Action<FourCC> onChange = null)
22 : base("Action", actionProperty, onChange, actionProperty.FindPropertyRelative("m_ExpectedControlType").stringValue)
23 {
24 m_ExpectedControlTypeProperty = actionProperty.FindPropertyRelative(nameof(InputAction.m_ExpectedControlType));
25 m_ActionTypeProperty = actionProperty.FindPropertyRelative(nameof(InputAction.m_Type));
26 m_ActionFlagsProperty = actionProperty.FindPropertyRelative(nameof(InputAction.m_Flags));
27
28 m_SelectedActionType = (InputActionType)m_ActionTypeProperty.intValue;
29 m_WantsInitialStateCheck = (m_ActionFlagsProperty.intValue & (int)InputAction.ActionFlags.WantsInitialStateCheck) != 0;
30
31 BuildControlTypeList();
32 m_SelectedControlType = Array.IndexOf(m_ControlTypeList, m_ExpectedControlTypeProperty.stringValue);
33 if (m_SelectedControlType == -1)
34 m_SelectedControlType = 0;
35
36 if (s_ControlTypeLabel == null)
37 s_ControlTypeLabel = EditorGUIUtility.TrTextContent("Control Type", m_ExpectedControlTypeProperty.GetTooltip());
38 if (s_ActionTypeLabel == null)
39 s_ActionTypeLabel = EditorGUIUtility.TrTextContent("Action Type", m_ActionTypeProperty.GetTooltip());
40 if (s_WantsInitialStateCheckLabel == null)
41 s_WantsInitialStateCheckLabel = EditorGUIUtility.TrTextContent("Initial State Check",
42 "Whether in the next input update after the action was enabled, the action should "
43 + "immediately trigger if any of its bound controls are currently in a non-default state. "
44 + "This check happens implicitly for Value actions but can be explicitly enabled for Button and Pass-Through actions.");
45 }
46
47 protected override void DrawGeneralProperties()
48 {
49 EditorGUI.BeginChangeCheck();
50
51 m_SelectedActionType = EditorGUILayout.EnumPopup(s_ActionTypeLabel, m_SelectedActionType);
52 if ((InputActionType)m_SelectedActionType != InputActionType.Button)
53 m_SelectedControlType = EditorGUILayout.Popup(s_ControlTypeLabel, m_SelectedControlType, m_ControlTypeOptions);
54
55 if ((InputActionType)m_SelectedActionType != InputActionType.Value)
56 m_WantsInitialStateCheck = EditorGUILayout.Toggle(s_WantsInitialStateCheckLabel, m_WantsInitialStateCheck);
57
58 if (EditorGUI.EndChangeCheck())
59 {
60 if ((InputActionType)m_SelectedActionType == InputActionType.Button)
61 m_ExpectedControlTypeProperty.stringValue = "Button";
62 else if (m_SelectedControlType == 0)
63 m_ExpectedControlTypeProperty.stringValue = string.Empty;
64 else
65 m_ExpectedControlTypeProperty.stringValue = m_ControlTypeList[m_SelectedControlType];
66
67 m_ActionTypeProperty.intValue = (int)(InputActionType)m_SelectedActionType;
68
69 if (m_WantsInitialStateCheck)
70 m_ActionFlagsProperty.intValue |= (int)InputAction.ActionFlags.WantsInitialStateCheck;
71 else
72 m_ActionFlagsProperty.intValue &= ~(int)InputAction.ActionFlags.WantsInitialStateCheck;
73
74 m_ActionTypeProperty.serializedObject.ApplyModifiedProperties();
75 UpdateProcessors(m_ExpectedControlTypeProperty.stringValue);
76
77 onChange(k_PropertiesChanged);
78 }
79 }
80
81 private void BuildControlTypeList()
82 {
83 var types = new List<string>();
84 var allLayouts = InputSystem.s_Manager.m_Layouts;
85 foreach (var layoutName in allLayouts.layoutTypes.Keys)
86 {
87 if (EditorInputControlLayoutCache.TryGetLayout(layoutName).hideInUI)
88 continue;
89
90 // If the action type is InputActionType.Value, skip button controls.
91 var type = allLayouts.layoutTypes[layoutName];
92 if ((InputActionType)m_SelectedActionType == InputActionType.Value &&
93 typeof(ButtonControl).IsAssignableFrom(type))
94 continue;
95
96 ////TODO: skip aliases
97
98 if (typeof(InputControl).IsAssignableFrom(type) &&
99 !typeof(InputDevice).IsAssignableFrom(type))
100 {
101 types.Add(layoutName);
102 }
103 }
104 // Sort alphabetically.
105 types.Sort((a, b) => string.Compare(a, b, StringComparison.OrdinalIgnoreCase));
106 // Make sure "Any" is always topmost entry.
107 types.Insert(0, "Any");
108
109 m_ControlTypeList = types.ToArray();
110 m_ControlTypeOptions = m_ControlTypeList.Select(x => new GUIContent(ObjectNames.NicifyVariableName(x)))
111 .ToArray();
112 }
113
114 private readonly SerializedProperty m_ExpectedControlTypeProperty;
115 private readonly SerializedProperty m_ActionTypeProperty;
116 private readonly SerializedProperty m_ActionFlagsProperty;
117
118 private string m_ExpectedControlLayout;
119 private string[] m_ControlTypeList;
120 private GUIContent[] m_ControlTypeOptions;
121 private int m_SelectedControlType;
122 private Enum m_SelectedActionType;
123 private bool m_WantsInitialStateCheck;
124
125 private static GUIContent s_ActionTypeLabel;
126 private static GUIContent s_ControlTypeLabel;
127 private static GUIContent s_WantsInitialStateCheckLabel;
128 }
129}
130#endif // UNITY_EDITOR