@@ -90,6 +90,17 @@ public Text rebindPrompt
9090 set => m_RebindText = value ;
9191 }
9292
93+ /// <summary>
94+ /// Optional text component that shows relevant information when waiting for a control to be actuated.
95+ /// </summary>
96+ /// <seealso cref="rebindPrompt"/>
97+ /// <seealso cref="rebindOverlay"/>
98+ public Text rebindInfo
99+ {
100+ get => m_RebindInfo ;
101+ set => m_RebindInfo = value ;
102+ }
103+
93104 /// <summary>
94105 /// Optional UI that is activated when an interactive rebind is started and deactivated when the rebind
95106 /// is finished. This is normally used to display an overlay over the current UI while the system is
@@ -293,7 +304,13 @@ void CleanUp()
293304 UpdateBindingDisplay ( ) ;
294305 CleanUp ( ) ;
295306 } )
296- . WithSuppressedActionPropagation ( )
307+ // We want matching events to be suppressed during rebinding (this is also default).
308+ . WithMatchingEventsBeingSuppressed ( )
309+ // Since this sample has no interactable UI during rebinding we also want to suppress non-matching events.
310+ . WithNonMatchingEventsBeingSuppressed ( )
311+ // We want device state to update but not actions firing during rebinding.
312+ . WithActionsBeingSuppressed ( )
313+ // Since this sample has no UI to cancle rebinding we timeout after not receiving input for a period of time.
297314 . WithTimeout ( 10.0f )
298315 . OnComplete (
299316 operation =>
@@ -329,6 +346,13 @@ void CleanUp()
329346 m_RebindText . text = text ;
330347 }
331348
349+ // Update rebind overlay information, if we have one.
350+ if ( m_RebindInfo != null )
351+ {
352+ m_RebindStartTime = Time . realtimeSinceStartup ;
353+ UpdateRebindInfo ( m_RebindStartTime ) ;
354+ }
355+
332356 // If we have no rebind overlay and no callback but we have a binding text label,
333357 // temporarily set the binding text label to "<Waiting>".
334358 if ( m_RebindOverlay == null && m_RebindText == null && m_RebindStartEvent == null && m_BindingText != null )
@@ -340,6 +364,29 @@ void CleanUp()
340364 m_RebindOperation . Start ( ) ;
341365 }
342366
367+ private void UpdateRebindInfo ( double now )
368+ {
369+ if ( m_RebindOperation == null )
370+ return ;
371+
372+ var elapsed = now - m_RebindStartTime ;
373+ var remainingTimeoutWholeSeconds = ( int ) Math . Floor ( m_RebindOperation . timeout - elapsed ) ;
374+ if ( remainingTimeoutWholeSeconds == m_LastRemainingTimeoutSeconds )
375+ return ;
376+
377+ var text = ( m_RebindOperation . timeout > 0.0f )
378+ ? $ "(This will timeout in <b>{ remainingTimeoutWholeSeconds } </b> seconds if no matching input is received)"
379+ : string . Empty ;
380+ m_RebindInfo . text = text ;
381+ m_LastRemainingTimeoutSeconds = remainingTimeoutWholeSeconds ;
382+ }
383+
384+ protected void Update ( )
385+ {
386+ if ( m_RebindInfo != null )
387+ UpdateRebindInfo ( Time . realtimeSinceStartupAsDouble ) ;
388+ }
389+
343390 protected void OnEnable ( )
344391 {
345392 if ( s_RebindActionUIs == null )
@@ -416,6 +463,10 @@ private static void OnActionChange(object obj, InputActionChange change)
416463 [ SerializeField ]
417464 private Text m_RebindText ;
418465
466+ [ Tooltip ( "Optional text label that will be updated with relevant information during rebinding." ) ]
467+ [ SerializeField ]
468+ private Text m_RebindInfo ;
469+
419470 [ Tooltip ( "Event that is triggered when the way the binding is display should be updated. This allows displaying "
420471 + "bindings in custom ways, e.g. using images instead of text." ) ]
421472 [ SerializeField ]
@@ -435,6 +486,9 @@ private static void OnActionChange(object obj, InputActionChange change)
435486
436487 private static List < RebindActionUI > s_RebindActionUIs ;
437488
489+ private double m_RebindStartTime = - 1 ;
490+ private int m_LastRemainingTimeoutSeconds ;
491+
438492 // We want the label for the action name to update in edit mode, too, so
439493 // we kick that off from here.
440494 #if UNITY_EDITOR
0 commit comments