-
Notifications
You must be signed in to change notification settings - Fork 332
Expand file tree
/
Copy pathActionLabel.cs
More file actions
161 lines (140 loc) · 5.24 KB
/
ActionLabel.cs
File metadata and controls
161 lines (140 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
using System;
using System.Collections.Generic;
using UnityEngine.Events;
using UnityEngine.UI;
namespace UnityEngine.InputSystem.Samples.RebindUI
{
public class ActionLabel : MonoBehaviour
{
[Tooltip("Reference to action that is to be rebound from the UI.")]
[SerializeField]
private InputActionReference m_Action;
[SerializeField]
private string m_BindingId;
[SerializeField]
private InputBinding.DisplayStringOptions m_DisplayStringOptions;
[Tooltip("Text label that will receive the current, formatted binding string.")]
[SerializeField]
private Text m_BindingText;
[Tooltip("Event that is triggered when the way the binding is display should be updated. This allows displaying "
+ "bindings in custom ways, e.g. using images instead of text.")]
[SerializeField]
private UpdateBindingUIEvent m_UpdateBindingUIEvent;
private static List<ActionLabel> s_InputActionUIs;
/// <summary>
/// Reference to the action that is to be rebound.
/// </summary>
public InputActionReference actionReference
{
get => m_Action;
set
{
m_Action = value;
UpdateBindingDisplay();
}
}
/// <summary>
/// ID (in string form) of the binding that is to be rebound on the action.
/// </summary>
/// <seealso cref="InputBinding.id"/>
public string bindingId
{
get => m_BindingId;
set
{
m_BindingId = value;
UpdateBindingDisplay();
}
}
/// <summary>
/// Text component that receives the display string of the binding. Can be <c>null</c> in which
/// case the component entirely relies on <see cref="updateBindingUIEvent"/>.
/// </summary>
public Text bindingText
{
get => m_BindingText;
set
{
m_BindingText = value;
UpdateBindingDisplay();
}
}
/// <summary>
/// Display options for the binding.
/// </summary>
public InputBinding.DisplayStringOptions displayStringOptions
{
get => m_DisplayStringOptions;
set
{
m_DisplayStringOptions = value;
UpdateBindingDisplay();
}
}
/// <summary>
/// Trigger a refresh of the currently displayed binding.
/// </summary>
public void UpdateBindingDisplay()
{
var displayString = string.Empty;
var deviceLayoutName = default(string);
var controlPath = default(string);
// Get display string from action.
var action = m_Action?.action;
if (action != null)
{
var bindingIndex = action.bindings.IndexOf(x => x.id.ToString() == m_BindingId);
if (bindingIndex != -1)
displayString = action.GetBindingDisplayString(bindingIndex, out deviceLayoutName, out controlPath, displayStringOptions);
}
// Set on label (if any).
if (m_BindingText != null)
m_BindingText.text = displayString;
// Give listeners a chance to configure UI in response.
m_UpdateBindingUIEvent?.Invoke(this, displayString, deviceLayoutName, controlPath);
}
protected void OnEnable()
{
if (s_InputActionUIs == null)
s_InputActionUIs = new List<ActionLabel>();
s_InputActionUIs.Add(this);
if (s_InputActionUIs.Count == 1)
InputSystem.onActionChange += OnActionChange;
UpdateBindingDisplay();
}
protected void OnDisable()
{
s_InputActionUIs.Remove(this);
if (s_InputActionUIs.Count == 0)
{
s_InputActionUIs = null;
InputSystem.onActionChange -= OnActionChange;
}
}
// When the action system re-resolves bindings, we want to update our UI in response
// to show the currently relevant binding.
private static void OnActionChange(object obj, InputActionChange change)
{
if (change != InputActionChange.BoundControlsChanged)
return;
var action = obj as InputAction;
var actionMap = action?.actionMap ?? obj as InputActionMap;
var actionAsset = actionMap?.asset ?? obj as InputActionAsset;
for (var i = 0; i < s_InputActionUIs.Count; ++i)
{
var component = s_InputActionUIs[i];
var referencedAction = component.actionReference?.action;
if (referencedAction == null)
continue;
if (referencedAction == action ||
referencedAction.actionMap == actionMap ||
referencedAction.actionMap?.asset == actionAsset)
component.UpdateBindingDisplay();
}
}
}
[Serializable]
public class UpdateBindingUIEvent : UnityEvent<ActionLabel, string, string, string>
{
}
}