@@ -1464,37 +1464,43 @@ private void ProcessControlStateChange(int mapIndex, int controlIndex, int bindi
1464
1464
// If the binding is part of a composite, check for interactions on the composite
1465
1465
// itself and give them a first shot at processing the value change.
1466
1466
var haveInteractionsOnComposite = false ;
1467
+ var compositeAlreadyTriggered = false ;
1467
1468
if ( bindingStatePtr ->isPartOfComposite )
1468
1469
{
1469
1470
var compositeBindingIndex = bindingStatePtr ->compositeOrCompositeBindingIndex ;
1470
1471
var compositeBindingPtr = & bindingStates [ compositeBindingIndex ] ;
1471
1472
1472
- // If the composite has already been triggered from the very same event, ignore it .
1473
+ // If the composite has already been triggered from the very same event set a flag so it isn't triggered again .
1473
1474
// Example: KeyboardState change that includes both A and W key state changes and we're looking
1474
1475
// at a WASD composite binding. There's a state change monitor on both the A and the W
1475
1476
// key and thus the manager will notify us individually of both changes. However, we
1476
1477
// want to perform the action only once.
1477
- if ( ShouldIgnoreInputOnCompositeBinding ( compositeBindingPtr , eventPtr ) )
1478
- return ;
1479
-
1480
- // Update magnitude for composite.
1481
- var compositeIndex = bindingStates [ compositeBindingIndex ] . compositeOrCompositeBindingIndex ;
1482
- var compositeContext = new InputBindingCompositeContext
1478
+ // NOTE: Do NOT ignore this Event, we still need finish processing the individual button states.
1479
+ if ( ! ShouldIgnoreInputOnCompositeBinding ( compositeBindingPtr , eventPtr ) )
1483
1480
{
1484
- m_State = this ,
1485
- m_BindingIndex = compositeBindingIndex
1486
- } ;
1487
- trigger . magnitude = composites [ compositeIndex ] . EvaluateMagnitude ( ref compositeContext ) ;
1488
- memory . compositeMagnitudes [ compositeIndex ] = trigger . magnitude ;
1489
-
1490
- // Run through interactions on composite.
1491
- var interactionCountOnComposite = compositeBindingPtr ->interactionCount ;
1492
- if ( interactionCountOnComposite > 0 )
1481
+ // Update magnitude for composite.
1482
+ var compositeIndex = bindingStates [ compositeBindingIndex ] . compositeOrCompositeBindingIndex ;
1483
+ var compositeContext = new InputBindingCompositeContext
1484
+ {
1485
+ m_State = this ,
1486
+ m_BindingIndex = compositeBindingIndex
1487
+ } ;
1488
+ trigger . magnitude = composites [ compositeIndex ] . EvaluateMagnitude ( ref compositeContext ) ;
1489
+ memory . compositeMagnitudes [ compositeIndex ] = trigger . magnitude ;
1490
+
1491
+ // Run through interactions on composite.
1492
+ var interactionCountOnComposite = compositeBindingPtr ->interactionCount ;
1493
+ if ( interactionCountOnComposite > 0 )
1494
+ {
1495
+ haveInteractionsOnComposite = true ;
1496
+ ProcessInteractions ( ref trigger ,
1497
+ compositeBindingPtr ->interactionStartIndex ,
1498
+ interactionCountOnComposite ) ;
1499
+ }
1500
+ }
1501
+ else
1493
1502
{
1494
- haveInteractionsOnComposite = true ;
1495
- ProcessInteractions ( ref trigger ,
1496
- compositeBindingPtr ->interactionStartIndex ,
1497
- interactionCountOnComposite ) ;
1503
+ compositeAlreadyTriggered = true ;
1498
1504
}
1499
1505
}
1500
1506
@@ -1503,21 +1509,31 @@ private void ProcessControlStateChange(int mapIndex, int controlIndex, int bindi
1503
1509
// one of higher magnitude) or may even lead us to switch to processing a different binding
1504
1510
// (e.g. when an input of previously greater magnitude has now fallen below the level of another
1505
1511
// ongoing input with now higher magnitude).
1506
- var isConflictingInput = IsConflictingInput ( ref trigger , actionIndex ) ;
1507
- bindingStatePtr = & bindingStates [ trigger . bindingIndex ] ; // IsConflictingInput may switch us to a different binding.
1512
+ //
1513
+ // If Composite has already been triggered, skip this step; it's unnecessary and could also
1514
+ // cause a processing issue if we switch to another binding.
1515
+ var isConflictingInput = false ;
1516
+ if ( ! compositeAlreadyTriggered )
1517
+ {
1518
+ isConflictingInput = IsConflictingInput ( ref trigger , actionIndex ) ;
1519
+ bindingStatePtr = & bindingStates [ trigger . bindingIndex ] ; // IsConflictingInput may switch us to a different binding.
1520
+ }
1508
1521
1509
1522
// Process button presses/releases.
1523
+ // We MUST execute this processing even if Composite has already been triggered to ensure button states
1524
+ // are properly updated (ISXB-746)
1510
1525
if ( ! isConflictingInput )
1511
1526
ProcessButtonState ( ref trigger , actionIndex , bindingStatePtr ) ;
1512
1527
1513
1528
// If we have interactions, let them do all the processing. The presence of an interaction
1514
1529
// essentially bypasses the default phase progression logic of an action.
1530
+ // Interactions are skipped if compositeAlreadyTriggered is set.
1515
1531
var interactionCount = bindingStatePtr ->interactionCount ;
1516
1532
if ( interactionCount > 0 && ! bindingStatePtr ->isPartOfComposite )
1517
1533
{
1518
1534
ProcessInteractions ( ref trigger , bindingStatePtr ->interactionStartIndex , interactionCount ) ;
1519
1535
}
1520
- else if ( ! haveInteractionsOnComposite && ! isConflictingInput )
1536
+ else if ( ! haveInteractionsOnComposite && ! isConflictingInput && ! compositeAlreadyTriggered )
1521
1537
{
1522
1538
ProcessDefaultInteraction ( ref trigger , actionIndex ) ;
1523
1539
}
0 commit comments