Weird Enhanced Input Problem (C++ & Blueprint)

I have a strange input problem within a User Widget:

2

When I create the Widget, I add a Input Context and when I destroy it, the context will be removed. This works correct so far:

Within the Widget I consume an Input Action:

3

Everthing work fine when I open the widget, trigger the Event and destroy the Widget. The following messages are shown:

  1. “Construct”
  2. “Confirm”
  3. “Destruct”

But when I open the widget again, and trigger the event (press the button) I got the following messages:

  1. “Construct”
  2. “Confirm”
  3. “Confirm”
  4. “Destruct”

And if I open it the third time:

  1. “Construct”
  2. “Confirm”
  3. “Confirm”
  4. “Confirm”
  5. “Destruct”

a.s.o …

I’m using 5.1, the Enhanced Input System and tested it the C++ and the BluePrint way.

Any ideas are welcome.

Well, obviously: RemoveMappingContext() doesn’t work as you expect it.

Right away I see nothing suspicious in RemoveMappingContext(), so you should start from tracing the problem with c++ debugger from here on your project.

Also i’m not sure that pointers to context you passing to both functions are the same, so you should check this as well

Are you sure you are deleting the previous Widget?
It seems that every time you ‘open’ a Widget, a new instance is created and this new instance is consuming the input with the previous one.

I tested it with two AddMappingContext and the input didn’t duplicate.

UUserWidget::Destruct

Called when a widget is no longer referenced causing the slate resource to destroyed. Just like Construct this event can be called multiple times.

Try to AddToViewport the deleted Widget and see if it works.

2 Likes

Thanks for your answers. Today I learned something new.

The Problem was not the Enhanced Input System, but the way Unreal “destroy” widgets.

If you remove a widget with Remove From Parent, its Destruct event is called BUT this does not mean the widget is destroyed. It still remain in memory AND it still react to events like Input Actions.

With this new knowledge, I have 3 options to solve this Problem:

  • Reuse the widgets as I did on others (but this won’t work well with different Popups)
  • Call GarbageCollect after removing from parent (and after all references are nullptr)
  • Mark Widget as Released and block event from execution

Thanks for you help

1 Like

I have 3 options to solve this Problem:

those aren’t solutions, but only a workarounds. It isn’t the best way of solving problems.

Even if subscriptions are still active before widget get garbage collected despite you attempted to unsubscribe it doesn’t means you have to force\imitate gc, but you should unsubscribe properly.

Nevertheless, it’s up for you if workarounds is enough for your goals.

That’s the way I do it in C++. I use Blueprints mainly for tests and prototyping :wink: