This question was created in reference to: [Can enhanced input action nodes be disabled in user [Content removed]
Hi there,
Looks like the fix for linked issue above has generated a new bug. UUserWidget has it’s input component created on Initialize and now destroyed on Destruct. However, the counterpart to Destruct is supposed to be Construct, not Initialize, as Initialize is only called once ever. This means that after the first Destruct is called, the InputComponent is destroyed and never created again, even when the widget is re-added to a parent and ready to receive input once again.
This means when we return to a widget and re-add it to a parent, our Input Actions no longer fire in this widget.
I would suggest moving or adding the following code to the NativeConstruct in the UUserWidget class:
if ( !InputComponent ) { InitializeInputComponent(); check(InputComponent); UInputDelegateBinding::BindInputDelegates(GetClass(), InputComponent, this); }This code ^ is copied in part from the NativeOnInitialized function and the ListenForInputAction function on the UUserWidget class. I tested the above code in my own widget, where I had overridden NativeConstruct and added in those calls and now it works perfectly fine.
Just for reference, our use case (and where we ran into this bug) is that we have a menu stack (Menus are UserWidgets). When we go deeper into another menu, we remove the previous menu from the screen but keep it in a stack, so we can re-add it again on return. Moving to another menu like this causes the previous menu to be removed from parent (Destruct) but it’s still valid as it’s stored in the stack. Input should resume again once we return to the previous menu and it’s re-added (Construct).
In the meantime, recreating the widget would fix our issue obviously (as initialize will be called again) but this is not ideal. We don’t want to create the widget newly again as our menu widgets should keep their previous state when returned to.
Thanks for the detailed report. This does seem to be the same underlying issue as the bug reported earlier. I’m going to dig deeper into this and get back to you with an update soon.
I am pinging you because I noticed that you added the fix for the input bindings staying alive after destruction (CL 35418859). I was wondering why the input component is initialised in NativeOnInitialized instead of NativeConstruct. The solution we found for the new issue described by my colleague was to actually call InitializeInputComponent and UInputDelegateBinding::BindInputDelegates in NativeConstruct.
The new issue you describe should be resolved in UE5/Main with 44358204. We will not bind the delegates once still on native construct, but correctly push/pop the input component to the stack on NativeConstruct and NativeDestruct.
This looks like a much more elegant solution than the quick fix I proposed - happy to see it! Thank you for taking care of the bug and I look forward to upgrading to 5.7!