Skip to content

Commit 59c7c40

Browse files
authored
FIX: Improved Samples/Visualizers and particularly GamepadVisualizer (ISXB-1243) (#2063)
1 parent be8287f commit 59c7c40

File tree

3 files changed

+220
-32
lines changed

3 files changed

+220
-32
lines changed

Assets/Samples/Visualizers/GamepadVisualizer.unity

Lines changed: 149 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ RenderSettings:
4242
--- !u!157 &3
4343
LightmapSettings:
4444
m_ObjectHideFlags: 0
45-
serializedVersion: 13
46-
m_BakeOnSceneLoad: 0
45+
serializedVersion: 12
4746
m_GISettings:
4847
serializedVersion: 2
4948
m_BounceScale: 1
@@ -218,7 +217,7 @@ LightingSettings:
218217
m_PrefabInstance: {fileID: 0}
219218
m_PrefabAsset: {fileID: 0}
220219
m_Name: Settings.lighting
221-
serializedVersion: 9
220+
serializedVersion: 8
222221
m_EnableBakedLightmaps: 1
223222
m_EnableRealtimeLightmaps: 1
224223
m_RealtimeEnvironmentLighting: 1
@@ -272,6 +271,18 @@ LightingSettings:
272271
m_PVRFilteringAtrousPositionSigmaIndirect: 2
273272
m_PVRFilteringAtrousPositionSigmaAO: 1
274273
m_RespectSceneVisibilityWhenBakingGI: 0
274+
--- !u!114 &2122909276 stripped
275+
MonoBehaviour:
276+
m_CorrespondingSourceObject: {fileID: 5802899217532024206, guid: b8429651427a640919754290f3704312,
277+
type: 3}
278+
m_PrefabInstance: {fileID: 5430831075364511436}
279+
m_PrefabAsset: {fileID: 0}
280+
m_GameObject: {fileID: 0}
281+
m_Enabled: 1
282+
m_EditorHideFlags: 0
283+
m_Script: {fileID: 11500000, guid: 50c7363fac4d24ae8a679e3e8f1fa838, type: 3}
284+
m_Name:
285+
m_EditorClassIdentifier:
275286
--- !u!1001 &5430831075364511436
276287
PrefabInstance:
277288
m_ObjectHideFlags: 0
@@ -280,6 +291,86 @@ PrefabInstance:
280291
serializedVersion: 3
281292
m_TransformParent: {fileID: 0}
282293
m_Modifications:
294+
- target: {fileID: 5430831073950378564, guid: b8429651427a640919754290f3704312,
295+
type: 3}
296+
propertyPath: m_UseCurrentDevice
297+
value: 1
298+
objectReference: {fileID: 0}
299+
- target: {fileID: 5430831074071876626, guid: b8429651427a640919754290f3704312,
300+
type: 3}
301+
propertyPath: m_UseCurrentDevice
302+
value: 1
303+
objectReference: {fileID: 0}
304+
- target: {fileID: 5430831074153646139, guid: b8429651427a640919754290f3704312,
305+
type: 3}
306+
propertyPath: m_UseCurrentDevice
307+
value: 1
308+
objectReference: {fileID: 0}
309+
- target: {fileID: 5430831074316365814, guid: b8429651427a640919754290f3704312,
310+
type: 3}
311+
propertyPath: m_UseCurrentDevice
312+
value: 1
313+
objectReference: {fileID: 0}
314+
- target: {fileID: 5430831074333637590, guid: b8429651427a640919754290f3704312,
315+
type: 3}
316+
propertyPath: m_UseCurrentDevice
317+
value: 1
318+
objectReference: {fileID: 0}
319+
- target: {fileID: 5430831074406035310, guid: b8429651427a640919754290f3704312,
320+
type: 3}
321+
propertyPath: m_UseCurrentDevice
322+
value: 1
323+
objectReference: {fileID: 0}
324+
- target: {fileID: 5430831074569589722, guid: b8429651427a640919754290f3704312,
325+
type: 3}
326+
propertyPath: m_UseCurrentDevice
327+
value: 1
328+
objectReference: {fileID: 0}
329+
- target: {fileID: 5430831074657706043, guid: b8429651427a640919754290f3704312,
330+
type: 3}
331+
propertyPath: m_UseCurrentDevice
332+
value: 1
333+
objectReference: {fileID: 0}
334+
- target: {fileID: 5430831074722065634, guid: b8429651427a640919754290f3704312,
335+
type: 3}
336+
propertyPath: m_UseCurrentDevice
337+
value: 1
338+
objectReference: {fileID: 0}
339+
- target: {fileID: 5430831074890777048, guid: b8429651427a640919754290f3704312,
340+
type: 3}
341+
propertyPath: m_UseCurrentDevice
342+
value: 1
343+
objectReference: {fileID: 0}
344+
- target: {fileID: 5430831074908778959, guid: b8429651427a640919754290f3704312,
345+
type: 3}
346+
propertyPath: m_UseCurrentDevice
347+
value: 1
348+
objectReference: {fileID: 0}
349+
- target: {fileID: 5430831074960731594, guid: b8429651427a640919754290f3704312,
350+
type: 3}
351+
propertyPath: m_UseCurrentDevice
352+
value: 1
353+
objectReference: {fileID: 0}
354+
- target: {fileID: 5430831075105443483, guid: b8429651427a640919754290f3704312,
355+
type: 3}
356+
propertyPath: m_UseCurrentDevice
357+
value: 1
358+
objectReference: {fileID: 0}
359+
- target: {fileID: 5430831075159756558, guid: b8429651427a640919754290f3704312,
360+
type: 3}
361+
propertyPath: m_UseCurrentDevice
362+
value: 1
363+
objectReference: {fileID: 0}
364+
- target: {fileID: 5430831075192722340, guid: b8429651427a640919754290f3704312,
365+
type: 3}
366+
propertyPath: m_UseCurrentDevice
367+
value: 1
368+
objectReference: {fileID: 0}
369+
- target: {fileID: 5430831075336578713, guid: b8429651427a640919754290f3704312,
370+
type: 3}
371+
propertyPath: m_UseCurrentDevice
372+
value: 1
373+
objectReference: {fileID: 0}
283374
- target: {fileID: 5430831075476541849, guid: b8429651427a640919754290f3704312,
284375
type: 3}
285376
propertyPath: m_Name
@@ -335,6 +426,61 @@ PrefabInstance:
335426
propertyPath: m_LocalEulerAnglesHint.z
336427
value: 0
337428
objectReference: {fileID: 0}
429+
- target: {fileID: 5430831075516136799, guid: b8429651427a640919754290f3704312,
430+
type: 3}
431+
propertyPath: m_UseCurrent
432+
value: 1
433+
objectReference: {fileID: 0}
434+
- target: {fileID: 5430831075516136799, guid: b8429651427a640919754290f3704312,
435+
type: 3}
436+
propertyPath: m_UseCurrentDevice
437+
value: 1
438+
objectReference: {fileID: 0}
439+
- target: {fileID: 5430831075516136799, guid: b8429651427a640919754290f3704312,
440+
type: 3}
441+
propertyPath: m_UseCurrentForControlIndex
442+
value: 1
443+
objectReference: {fileID: 0}
444+
- target: {fileID: 5430831075640135793, guid: b8429651427a640919754290f3704312,
445+
type: 3}
446+
propertyPath: m_UseCurrentDevice
447+
value: 1
448+
objectReference: {fileID: 0}
449+
- target: {fileID: 5430831075882524474, guid: b8429651427a640919754290f3704312,
450+
type: 3}
451+
propertyPath: m_UseCurrentDevice
452+
value: 1
453+
objectReference: {fileID: 0}
454+
- target: {fileID: 5430831075888579014, guid: b8429651427a640919754290f3704312,
455+
type: 3}
456+
propertyPath: m_UseCurrentDevice
457+
value: 1
458+
objectReference: {fileID: 0}
459+
- target: {fileID: 5430831075958221745, guid: b8429651427a640919754290f3704312,
460+
type: 3}
461+
propertyPath: m_UseCurrentDevice
462+
value: 1
463+
objectReference: {fileID: 0}
464+
- target: {fileID: 5430831075990510060, guid: b8429651427a640919754290f3704312,
465+
type: 3}
466+
propertyPath: m_UseCurrentDevice
467+
value: 1
468+
objectReference: {fileID: 0}
469+
- target: {fileID: 5802899217532024206, guid: b8429651427a640919754290f3704312,
470+
type: 3}
471+
propertyPath: m_Master
472+
value:
473+
objectReference: {fileID: 2122909276}
474+
- target: {fileID: 5802899217532024206, guid: b8429651427a640919754290f3704312,
475+
type: 3}
476+
propertyPath: m_UseCurrentDevice
477+
value: 1
478+
objectReference: {fileID: 0}
479+
- target: {fileID: 6586345530156004295, guid: b8429651427a640919754290f3704312,
480+
type: 3}
481+
propertyPath: m_UseCurrentDevice
482+
value: 1
483+
objectReference: {fileID: 0}
338484
m_RemovedComponents: []
339485
m_RemovedGameObjects: []
340486
m_AddedGameObjects: []

Assets/Samples/Visualizers/InputControlVisualizer.cs

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,30 @@ public int controlIndex
138138
+ "which of the controls to visualize.")]
139139
[InputControl, SerializeField] private string m_ControlPath;
140140
[Tooltip("If multiple controls match 'Control Path' at runtime, this property decides "
141-
+ "which control to visualize from the list of candidates. It is a zero-based index.")]
141+
+ "which control to visualize from the list of candidates. It is a zero-based index. " +
142+
"This is ignored if using current device instead.")]
142143
[SerializeField] private int m_ControlIndex;
143144

145+
[Tooltip("If set, ignores control index and maps a control of the current device (if it exist) or none.")]
146+
[SerializeField] private bool m_UseCurrentDevice;
147+
144148
[NonSerialized] private InputControl m_Control;
145149

146150
private static List<InputControlVisualizer> s_EnabledInstances;
147151

152+
private static InputControl ResolveCurrentControl(InputControlList<InputControl> candidates)
153+
{
154+
// Only accept control that belongs to the current device of the same device type as candidate control device type.
155+
foreach (var candidate in candidates)
156+
{
157+
var currentDevice = GetCurrentDevice(candidate.device);
158+
if (candidate.device == currentDevice)
159+
return candidate;
160+
}
161+
162+
return null;
163+
}
164+
148165
private void ResolveControl()
149166
{
150167
m_Control = null;
@@ -154,7 +171,9 @@ private void ResolveControl()
154171
using (var candidates = InputSystem.FindControls(m_ControlPath))
155172
{
156173
var numCandidates = candidates.Count;
157-
if (numCandidates > 1 && m_ControlIndex < numCandidates && m_ControlIndex >= 0)
174+
if (m_UseCurrentDevice)
175+
m_Control = ResolveCurrentControl(candidates);
176+
else if (numCandidates > 1 && m_ControlIndex < numCandidates && m_ControlIndex >= 0)
158177
m_Control = candidates[m_ControlIndex];
159178
else if (numCandidates > 0)
160179
m_Control = candidates[0];
@@ -163,30 +182,52 @@ private void ResolveControl()
163182
SetupVisualizer();
164183
}
165184

166-
private void SetupVisualizer()
185+
void Update()
167186
{
168-
if (m_Control == null)
187+
// There is currently no callback when current device changes so we will reattempt to resolve control
188+
if (m_UseCurrentDevice)
169189
{
170-
m_Visualizer = null;
171-
return;
190+
if (m_Control != null && m_Control.device != GetCurrentDevice(m_Control.device))
191+
m_Control = null;
192+
if (m_Control == null)
193+
ResolveControl();
172194
}
195+
}
173196

174-
switch (m_Visualization)
197+
private static InputDevice GetCurrentDevice(InputDevice device)
198+
{
199+
if (device is Gamepad) return Gamepad.current;
200+
if (device is Mouse) return Mouse.current;
201+
if (device is Pen) return Pen.current;
202+
if (device is Pointer) return Pointer.current; // should be last, because it's a base class for Mouse and Pen
203+
204+
throw new ArgumentException(
205+
$"Expected device type that implements .current, but got '{device.name}' (deviceId: {device.deviceId}) instead ");
206+
}
207+
208+
private static VisualizationHelpers.Visualizer CreateVisualizer(Mode mode, InputControl control, int historySamples)
209+
{
210+
switch (mode)
175211
{
176212
case Mode.Value:
177213
{
178-
var valueType = m_Control.valueType;
214+
// This visualization mode requires a control
215+
if (control == null)
216+
return null;
217+
218+
VisualizationHelpers.Visualizer visualizer = null;
219+
var valueType = control.valueType;
179220
if (valueType == typeof(Vector2))
180-
m_Visualizer = new VisualizationHelpers.Vector2Visualizer(m_HistorySamples);
221+
visualizer = new VisualizationHelpers.Vector2Visualizer(historySamples);
181222
else if (valueType == typeof(float))
182-
m_Visualizer = new VisualizationHelpers.ScalarVisualizer<float>(m_HistorySamples)
223+
visualizer = new VisualizationHelpers.ScalarVisualizer<float>(historySamples)
183224
{
184225
////TODO: pass actual min/max limits of control
185226
limitMax = 1,
186227
limitMin = 0
187228
};
188229
else if (valueType == typeof(int))
189-
m_Visualizer = new VisualizationHelpers.ScalarVisualizer<int>(m_HistorySamples)
230+
visualizer = new VisualizationHelpers.ScalarVisualizer<int>(historySamples)
190231
{
191232
////TODO: pass actual min/max limits of control
192233
limitMax = 1,
@@ -196,67 +237,66 @@ private void SetupVisualizer()
196237
{
197238
////TODO: generic visualizer
198239
}
199-
break;
240+
return visualizer;
200241
}
201242

202243
case Mode.Events:
203244
{
204-
var visualizer = new VisualizationHelpers.TimelineVisualizer(m_HistorySamples)
245+
var visualizer = new VisualizationHelpers.TimelineVisualizer(historySamples)
205246
{
206247
timeUnit = VisualizationHelpers.TimelineVisualizer.TimeUnit.Frames,
207-
historyDepth = m_HistorySamples,
248+
historyDepth = historySamples,
208249
showLimits = true,
209250
limitsY = new Vector2(0, 5) // Will expand upward automatically
210251
};
211-
m_Visualizer = visualizer;
212252
visualizer.AddTimeline("Events", Color.green,
213253
VisualizationHelpers.TimelineVisualizer.PlotType.BarChart);
214-
break;
254+
return visualizer;
215255
}
216256

217257
case Mode.MaximumLag:
218258
{
219-
var visualizer = new VisualizationHelpers.TimelineVisualizer(m_HistorySamples)
259+
var visualizer = new VisualizationHelpers.TimelineVisualizer(historySamples)
220260
{
221261
timeUnit = VisualizationHelpers.TimelineVisualizer.TimeUnit.Frames,
222-
historyDepth = m_HistorySamples,
262+
historyDepth = historySamples,
223263
valueUnit = new GUIContent("ms"),
224264
showLimits = true,
225265
limitsY = new Vector2(0, 6)
226266
};
227-
m_Visualizer = visualizer;
228267
visualizer.AddTimeline("MaxLag", Color.red,
229268
VisualizationHelpers.TimelineVisualizer.PlotType.BarChart);
230-
break;
269+
return visualizer;
231270
}
232271

233272
case Mode.Bytes:
234273
{
235-
var visualizer = new VisualizationHelpers.TimelineVisualizer(m_HistorySamples)
274+
var visualizer = new VisualizationHelpers.TimelineVisualizer(historySamples)
236275
{
237276
timeUnit = VisualizationHelpers.TimelineVisualizer.TimeUnit.Frames,
238277
valueUnit = new GUIContent("bytes"),
239-
historyDepth = m_HistorySamples,
278+
historyDepth = historySamples,
240279
showLimits = true,
241280
limitsY = new Vector2(0, 64)
242281
};
243-
m_Visualizer = visualizer;
244282
visualizer.AddTimeline("Bytes", Color.red,
245283
VisualizationHelpers.TimelineVisualizer.PlotType.BarChart);
246-
break;
284+
return visualizer;
247285
}
248286

249287
case Mode.DeviceCurrent:
250-
{
251-
m_Visualizer = new VisualizationHelpers.CurrentDeviceVisualizer();
252-
break;
253-
}
288+
return new VisualizationHelpers.CurrentDeviceVisualizer();
254289

255290
default:
256-
throw new NotImplementedException();
291+
throw new ArgumentOutOfRangeException(mode.ToString());
257292
}
258293
}
259294

295+
private void SetupVisualizer()
296+
{
297+
m_Visualizer = CreateVisualizer(m_Visualization, m_Control, m_HistorySamples);
298+
}
299+
260300
private static void OnDeviceChange(InputDevice device, InputDeviceChange change)
261301
{
262302
if (change != InputDeviceChange.Added && change != InputDeviceChange.Removed)

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ however, it has to be formatted properly to pass verification tests.
2929
- Fixed a CS0105 compiler warning due to duplicate using statement in test source code (ISXB-1247).
3030
- Fixed tooltip support in the UI Toolkit version of the Input Actions Asset editor.
3131
- Fixed documentation to clarify bindings with modifiers `overrideModifiersNeedToBePressedFirst` configuration [ISXB-806](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-806).
32+
- Fixed an issue in `Samples/Visualizers/GamepadVisualizer.unity` sample where the visualization wouldn't handle device disconnects or current device changes properly (ISXB-1243).
3233

3334
### Changed
3435
- Added back the InputManager to InputSystem project-wide asset migration code with performance improvement (ISX-2086).
3536
- Changed `OnScreenControl` to automaticaly switch, in Single Player with autoswitch enabled, to the target device control scheme when the first component is enabled to prevent bad interactions when it start.
3637
- Changed paremeter `overrideModifiersNeedToBePressedFirst` to obsolete for `ButtonWithOneModifier`, `ButtonWithTwoModifiers`, `OneModifierComposite` and `TwoModifiersComposite` in favour the new `modifiersOrder` parameter which is more explicit.
38+
- Changed `Samples/Visualizers/GamepadVisualizer.unity` to visualize the control values of the current device instead of the first device.
3739

3840
## [1.11.2] - 2024-10-16
3941

0 commit comments

Comments
 (0)