I got this weird problem last week that I managed to figure out what’s happening, but I don’t know how to solve…
So, what happens is that when I start a dialogue with an NPC, I create a widget to handle skipping lines, but after finishing the dialogue, I’m unable to dash (they share the same keys for their InputActions).
I tried moving the skip InputAction to another used key to check if it was the dash, but no.
I tried removing the widget, but there’s both no way to destroy it (for whatever reason) and even when I managed to remove it’s references and call the garbage collector, it still wouldn’t dash (but it stopped calling the PrintString I put at the end of the SkipDialogue call).
It seems that creating the widget “activates” a new InputAction that has precedent over the old one, but I don’t know how to revert that.
I tried already to call EnableInput on my character to try and put it at the top of the input stack, but no success.
Also, I tried setting the SkipDialogue InputAction to not consume the input and then I could dash (but I ‘really’ don’t want to keep calling SkipDialogue, as that seems ripe to crash randomly).
Does any one have any ideas as to what’s going on and what I can do to solve this conflict?
Thanks in advance ^^
I don’t know if there’s any other snippet that would be useful, but I can get them too if needed.
The PlayerController is mostly empty.
I’ve since deleted the tests of trying to remove the widget or calling EnableInput on the player actor, but I could also redo them if it helps.
If that’s the case you could try rebinding the dash to the input when the widget closes, or set it to not consume input, but manually remove the widget skip dialog input from the queue when dialog ends.
What do you mean by ‘no’ in this context? No, the dash didn’t work anyway?
I suspect the widget you create each time. Make sure the widget is actually removed and garbage collected otherwise it might still control the input.
You can debug the widget class and see how many instances of it you have spawned. You should have only one of course when its working and nothing when its removed.
Make sure you RemoveFromTheParent the widget when it’s done and also GarbageCollect it. This can all be done in BP.
Also as rule of thumb. I would keep all the inputs in one class only and wouldnt create new classes that also handle input.
For example you can choose you player controller class to handle the input and incase that there is a dialogue widget spawned it will control it and all its functionality.
This will help you keep your code more manageable and if you have input errors, you know they are all probably coming from the same class.
Hey @GPallas! Just to piggy back on xlman’s thoughts here, I’m thinking it’s likely that the widget isn’t being garbage collected right away, and also that it’s input is set to “Consume Inputs”. I recently handled a case of this where a ghost widget stayed alive because it was destroyed during construction, and it was also eating all inputs because it was an “any key” input.
That would be odd. I never had the issue but it might be because I use my own widget managers to update the input mode (player controller) to Game instantly when no interactable widgets are left on the viewport.
Sorry, I should have worded that better… What I meant was that I tried to check if the dash was the problem by moving the SkipDialogue to another key and no, it wasn’t the problem. I could dash normally, but couldn’t do the other thing anymore.
Maybe it’s creating each time, but that’s not what’s creating this issue.
I’m now creating it just once on my character’s BeginPlay, just to test this issue.
Also, I had tried (and tried again just now) to call both RemoveFromParent and CollectGarbage to see if it would work and it doesn’t…
So, I just tried something.
I created a new third person c++ project, created a new InputAction Skip with Space Bar as the input, created a Widget that uses Skip to print Hello and set this in the character’s BeginPlay
I thought you could manually add/remove inputs from the input queue, but after investigating for a bit, it isn’t a good practice at all if that would be the case. For this, it looks like you need a Input Mapping Context more info here
I suggest you try handling all the input with you player controller. The widget should only have the functionality implemented but the call should be made from the controller. This way you know only one class is handling input and fighting with other classes.
Try and test it quickly and see if it fixes the problem.
Alright, I finally figured out what I had to do (it was simple, and I feel kinda dumb xD).
So, all I had to do was, at the end of the dialogue, to call DisableInput on my PlayerController.
It never crossed my mind that that could be the solution, until I was reading about the Input Mapping Context that @barracius-AOne suggested and feeling that while that may do what I need, it seemed like a way more complex way of doing exactly what the input stack already does (in my case).
Also, thanks @xlman for suggesting a centralized input solution. I tried it in the template test I had made today and it worked, but I’d have to refactor some stuff I’d rather not. I’ll keep that in mind for when we finish the prototype ^^