Enhanced input system triggers bug?

Hi! Feels like found a bug in the enhanced input system, or maybe you guys can clarify the behavior?

Have an input action with Pressed and Released triggers.

In certain scenarios binding can be added or removed for this action with Start and Complete states.

If binding happens while appropriate button is held down, on release it’ll trigger both Start and Complete states despite button was only released.

Apparently because there’s binding to Released state action is triggered, GetTriggerStateChangeEvent sets internal state of ActionData to StartedAndTriggered and then in EvaluateInputDelegates succeeds in condition “BoundTriggerEvent == ETriggerEvent::Started && ActionData->TriggerEventInternal == ETriggerEventInternal::StartedAndTriggered)” and binding is executed.

Thank you

Taras

Steps to Reproduce

Hi Taras,

I’d like to clarify one thing; I am able to reproduce this to some degree, however only on the Triggered state, and not Start. For example, in the 3rd person shooter template the Jump action comes off the Triggered state, and in that case simply holding the space bar until the character has landed, then releasing will cause the character to jump again. However, moving the pin from Triggered to Started, I do not get this behavior.

I tried delaying when the binding of the mapping context happens and I can’t get it to trigger any strange behavior one way or another.

In the case I reproduced, this makes sense since the Jump action itself has two trigger criteria; pressed and released.

If you are getting this action when you bind the mapping, can you elaborate on when/how you are doing the binding? I put a simple delay and held the key down during the delay, but no actions occurred when the mapping was finally set.

Hello Graeme, I’m getting functionality bound to Started And Complete and it seem to be triggering both because in, since last state is None, Triggered is transkated into StartedAndTriggered by GetTriggerStateChangeEvent and when processed in EvaluateInputDelegates triggers Started bound events.

[Image Removed]

Hi Taras,

Sorry for the delayed reply. I was out at BitSummit in Kyoto for the latter half of last week.

So, I misinterpreted what you were doing in the original bug; I thought it occurred when the mappings were added, not when actions themselves were bound. I went back and tried to verify this with delayed action bindings, but everything still worked for me as expected.

I think your analysis is correct -- if the TriggerEvent was None it would get translated to StartedAndTriggered and cause the behavior you’re seeing, however I put a breakpoint at the if statement (which got hit immediately after the actions were bound), and ActionData->TriggerEvent was actually Ongoing, so the if check failed.

So I’m thinking the root cause here is actually that your TriggerEvent became None somehow. Grepping the code a bit, most places that an event can be changed to None don’t apply. However, I did notice two possible places the event can be changed to None which could happen to Pressed/Released triggers. The first is, if the IsBlocking() function of UInputTrigger is overridden and returns true, the trigger state will return None. The second is when the game is paused but the action does not set “Trigger when Paused” to true.

Do either of those cases apply to your situation?

Thank you for answering, good to know it is abnormal to have a None state there. Let me investigate the cause of it and I’ll get back to you

Regards

ok, got a bit deeper into this rabbit hole :smiley:

we’re adding mapping context

RequestRebuildControlMappings is called

RebuildControlMappings sets Mapping.bShouldBeIgnored to true for that particular one since we’re holding it

EvaluateInputDelegates stops processing this one since KeyState->bDown and Mapping.bShouldBeIgnored

Action is cancelled

When we release button it is then started and then released at the same time like explained above.

There’s this flag bIgnoreAllPressedKeysUntilReleaseOnRebuild coming from request disabling which would fix that, but I think it has somewhat deeper implications and not sure I can touch it.

What do you think?

Hi Taras,

AddMappingContext() has a third parameter of type FModifyContextOptions, which is defaulted. In the constructor of FModifyContextOptions, bIgnoreAllPressedKeysUntilRelease is default-initialized to true. So for the general case, RequestRebuildControlMappings() will set bIgnoreAllPressedKeysUntilReleaseOnRebuild to true. I’m assuming you’re passing a FModifyContextOptions which is specifically setting bIgnoreAllPressedKeysUntilRelease to false? If so, I think this is the root cause of what you’re seeing.

Just to confirm I modified my little bug reproduction project to add the mapping with that option set to false, and indeed I get a Triggered event immediately when the context is added.