@@ -407,17 +407,25 @@ public void Actions_InteractiveRebinding_IgnoresNoisyControls()
407
407
InputSystem . RegisterLayout ( layout ) ;
408
408
var device = InputSystem . AddDevice ( "TestLayout" ) ;
409
409
410
- using ( var rebind = action . PerformInteractiveRebinding ( ) . OnMatchWaitForAnother ( 0 ) . Start ( ) )
410
+ using ( var rebind = new InputActionRebindingExtensions . RebindingOperation ( )
411
+ . WithAction ( action )
412
+ . OnMatchWaitForAnother ( 0 )
413
+ . Start ( ) )
411
414
{
412
415
Set ( ( ButtonControl ) device [ "noisyButton" ] , 0.678f ) ;
413
416
414
417
Assert . That ( rebind . completed , Is . False ) ;
415
418
Assert . That ( action . bindings [ 0 ] . overridePath , Is . Null ) ;
416
419
420
+ Set ( ( ButtonControl ) device [ "noisyButton" ] , 0f ) ;
421
+
417
422
// Can disable the behavior. This is most useful in combination with a custom
418
423
// OnPotentialMatch() callback or when the selection-by-magnitude logic will do
419
424
// a good enough job.
420
- rebind . WithoutIgnoringNoisyControls ( ) ;
425
+ rebind . Cancel ( ) ;
426
+ rebind
427
+ . WithoutIgnoringNoisyControls ( )
428
+ . Start ( ) ;
421
429
422
430
Set ( ( ButtonControl ) device [ "noisyButton" ] , 0.789f ) ;
423
431
@@ -449,25 +457,23 @@ public void Actions_InteractiveRebinding_UsesSyntheticControlsOnlyWhenBestMatch(
449
457
// a candidate as well as leftStick/x. However, leftStick/right is synthetic so X axis should
450
458
// win. Note that if we set expectedControlType to "Button", leftStick/x will get ignored
451
459
// and leftStick/left will get picked.
452
- InputSystem . QueueStateEvent ( gamepad , new GamepadState { leftStick = new Vector2 ( 1 , 0 ) } ) ;
453
- InputSystem . Update ( ) ;
460
+ Set ( gamepad . leftStick , Vector2 . right ) ;
454
461
455
462
Assert . That ( rebind . completed , Is . False ) ;
456
463
Assert . That ( rebind . candidates , Is . EquivalentTo ( new [ ] { gamepad . leftStick . x , gamepad . leftStick . right } ) ) ;
457
464
Assert . That ( rebind . scores , Has . Count . EqualTo ( 2 ) ) ;
458
465
Assert . That ( rebind . scores [ 0 ] , Is . GreaterThan ( rebind . scores [ 1 ] ) ) ;
459
466
460
467
// Reset.
461
- InputSystem . QueueStateEvent ( gamepad , new GamepadState ( ) ) ;
462
- InputSystem . Update ( ) ;
463
- rebind . RemoveCandidate ( gamepad . leftStick . x ) ;
464
- rebind . RemoveCandidate ( gamepad . leftStick . right ) ;
468
+ Set ( gamepad . leftStick , Vector2 . zero ) ;
465
469
466
470
// Switch to looking only for buttons. leftStick/x will no longer be a suitable pick.
467
- rebind . WithExpectedControlType ( "Button" ) ;
471
+ rebind . Cancel ( ) ;
472
+ rebind
473
+ . WithExpectedControlType ( "Button" )
474
+ . Start ( ) ;
468
475
469
- InputSystem . QueueStateEvent ( gamepad , new GamepadState { leftStick = new Vector2 ( 1 , 0 ) } ) ;
470
- InputSystem . Update ( ) ;
476
+ Set ( gamepad . leftStick , Vector2 . right ) ;
471
477
472
478
Assert . That ( rebind . completed , Is . True ) ;
473
479
Assert . That ( action . bindings [ 0 ] . overridePath , Is . EqualTo ( "<Gamepad>/leftStick/right" ) ) ;
@@ -572,33 +578,71 @@ public void Actions_InteractiveRebinding_RespectsExpectedControlLayoutIfSet()
572
578
}
573
579
}
574
580
575
- // If a control is already actuated when we initiate a rebind, we first require it to go
576
- // back to its default value.
581
+ // We want to be able to deal with controls that are already actuated when the rebinding starts and
582
+ // also with controls that don't usually go back to default values at all.
583
+ //
584
+ // What we require is that when we detect sufficient actuation on a control in an event, we compare
585
+ // it to the control's current actuation level when we first considered it. This is expected to work
586
+ // regardless of whether we are suppressing events or not.
587
+ //
588
+ // https://fogbugz.unity3d.com/f/cases/1215784/
577
589
[ Test ]
578
590
[ Category ( "Actions" ) ]
579
- public void Actions_InteractiveRebinding_RequiresControlToBeActuatedStartingWithDefaultValue ( )
591
+ public void Actions_InteractiveRebinding_WhenControlAlreadyActuated_HasToCrossMagnitudeThresholdFromCurrentActuation ( )
580
592
{
581
593
var action = new InputAction ( binding : "<Gamepad>/buttonSouth" ) ;
582
594
var gamepad = InputSystem . AddDevice < Gamepad > ( ) ;
583
595
584
- // Put buttonNorth in pressed state .
585
- InputSystem . QueueStateEvent ( gamepad , new GamepadState ( ) . WithButton ( GamepadButton . North ) ) ;
586
- InputSystem . Update ( ) ;
596
+ // Actuate some controls .
597
+ Press ( gamepad . buttonNorth ) ;
598
+ Set ( gamepad . leftTrigger , 0.75f ) ;
587
599
588
- using ( var rebind = new InputActionRebindingExtensions . RebindingOperation ( ) . WithAction ( action ) . Start ( ) )
600
+ using ( var rebind = new InputActionRebindingExtensions . RebindingOperation ( )
601
+ . WithAction ( action )
602
+ . WithMagnitudeHavingToBeGreaterThan ( 0.25f )
603
+ . Start ( ) )
589
604
{
590
- // Reset buttonNorth to unpressed state.
591
- InputSystem . QueueStateEvent ( gamepad , new GamepadState ( ) ) ;
592
- InputSystem . Update ( ) ;
605
+ Release ( gamepad . buttonNorth ) ;
593
606
594
607
Assert . That ( rebind . completed , Is . False ) ;
608
+ Assert . That ( rebind . candidates , Is . Empty ) ;
595
609
596
- // Now press it again.
597
- InputSystem . QueueStateEvent ( gamepad , new GamepadState ( ) . WithButton ( GamepadButton . North ) ) ;
598
- InputSystem . Update ( ) ;
610
+ Set ( gamepad . leftTrigger , 0.9f ) ;
611
+
612
+ Assert . That ( rebind . completed , Is . False ) ;
613
+ Assert . That ( rebind . candidates , Is . Empty ) ;
614
+
615
+ Set ( gamepad . leftTrigger , 0f ) ;
616
+
617
+ Assert . That ( rebind . completed , Is . False ) ;
618
+ Assert . That ( rebind . candidates , Is . Empty ) ;
619
+
620
+ Set ( gamepad . leftTrigger , 0.7f ) ;
599
621
600
622
Assert . That ( rebind . completed , Is . True ) ;
601
- Assert . That ( action . bindings [ 0 ] . overridePath , Is . EqualTo ( "<Gamepad>/buttonNorth" ) ) ;
623
+ Assert . That ( action . bindings [ 0 ] . overridePath , Is . EqualTo ( "<Gamepad>/leftTrigger" ) ) ;
624
+ }
625
+ }
626
+
627
+ [ Test ]
628
+ [ Category ( "Actions" ) ]
629
+ public void Actions_InteractiveRebinding_CanGetActuationMagnitudeOfCandidateControls ( )
630
+ {
631
+ var action = new InputAction ( binding : "<Gamepad>/buttonSouth" ) ;
632
+ var gamepad = InputSystem . AddDevice < Gamepad > ( ) ;
633
+
634
+ using ( var rebind = new InputActionRebindingExtensions . RebindingOperation ( )
635
+ . WithAction ( action )
636
+ . WithMagnitudeHavingToBeGreaterThan ( 0.25f )
637
+ . OnMatchWaitForAnother ( 1 )
638
+ . Start ( ) )
639
+ {
640
+ Set ( gamepad . leftTrigger , 0.75f ) ;
641
+
642
+ Assert . That ( rebind . candidates , Has . Count . EqualTo ( 1 ) ) ;
643
+ Assert . That ( rebind . magnitudes , Has . Count . EqualTo ( rebind . candidates . Count ) ) ;
644
+ Assert . That ( rebind . candidates [ 0 ] , Is . SameAs ( gamepad . leftTrigger ) ) ;
645
+ Assert . That ( rebind . magnitudes [ 0 ] , Is . EqualTo ( 0.75 ) . Within ( 0.00001 ) ) ;
602
646
}
603
647
}
604
648
@@ -801,14 +845,12 @@ public void Actions_InteractiveRebinding_CanSpecifyMagnitudeThreshold()
801
845
. WithMagnitudeHavingToBeGreaterThan ( 0.5f )
802
846
. Start ( ) )
803
847
{
804
- InputSystem . QueueStateEvent ( gamepad , new GamepadState { leftTrigger = 0.4f } ) ;
805
- InputSystem . Update ( ) ;
848
+ Set ( gamepad . leftTrigger , 0.4f ) ;
806
849
807
850
Assert . That ( rebind . completed , Is . False ) ;
808
851
Assert . That ( rebind . candidates , Is . Empty ) ;
809
852
810
- InputSystem . QueueStateEvent ( gamepad , new GamepadState { leftTrigger = 0.6f } ) ;
811
- InputSystem . Update ( ) ;
853
+ Set ( gamepad . leftTrigger , 0.6f ) ;
812
854
813
855
Assert . That ( rebind . completed , Is . True ) ;
814
856
Assert . That ( action . bindings [ 0 ] . overridePath , Is . EqualTo ( "<Gamepad>/leftTrigger" ) ) ;
0 commit comments