Announcement

Collapse
No announcement yet.

Improved Keyboard/Gamepad Input & Widget Focus Handling for UMG Menus

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    [EDITOR] Improved Keyboard/Gamepad Input & Widget Focus Handling for UMG Menus

    One area I've found to be particularly cumbersome is handling gamepad input & widget focus in UMG menus. I'll do my best to annotate specific issues & how I think they could be fixed. First, here's a quick video demoing my front end menu system:

    https://drive.google.com/open?id=0B9...G1uSHhsRm1INkk

    If the issues below can be resolved, it'd remove SO much complex blueprint bookkeeping that's currently required.

    ------------------------------------------

    1. Communicating Widget Focus to the User

    Problem:
    There is no simple way to clearly communicate which widget currently has gamepad (or keyboard) focus.

    Suggestion for Fix:
    Add a new "Focused" style for all relevant widgets (button, checkbox, combo box, slider, etc.) and focus sound events. I view keyboard focus & mouse hover as kinda the same thing. IMHO, there should be an analog "focus" implementation for every "hover" implementation.
    Click image for larger version

Name:	ButtonFocus.png
Views:	1
Size:	34.8 KB
ID:	1220920



    2. Handling Widget Focus Events & Tracking Widget Focus

    Problem:
    There is no simple way to track which widget currently has focus or when a widget changes focus.

    Suggestion for Fix:
    There are blueprint callbacks for user defined widgets like OnFocusReceived & OnFocusLost, but there are no events for core widgets like Buttons. Again, in the spirit of matching "hover" implementations, adding new "On Focused" & "On Unfocused" bindings here could help. In addition, it would be really useful to be able to query which widget currently has focus at any given time. In all my time searching, I haven't been able to find a blueprint function (or function in code, for that matter) that can do that.
    Click image for larger version

Name:	FocusBinding.png
Views:	1
Size:	47.4 KB
ID:	1220921



    3. Losing Widget Focus w/ Unhandled Mouse Clicks

    Problem:
    When you mouse click an area of the screen that has no effect for a menu, you lose current keyboard focus. I've included some examples of other users running into this problem. Moderators say it's "working as intended", but it's SUPER confusing/annoying in practice.
    - https://answers.unrealengine.com/que...evel-view.html
    - https://answers.unrealengine.com/que...ackground.html
    - https://answers.unrealengine.com/que...-viewport.html
    - https://forums.unrealengine.com/show...eaks-all-input

    The answer on this post is actually what I'm doing to handle this issue and it's a giant pain for complex menus:
    - https://answers.unrealengine.com/que...use-click.html

    Suggestion for Fix:
    Add an option to keep current widget focus if user has unhandled mouse click event...or something. This one I'm less sure about how to handle, but the current workarounds are not great.



    4. Focus Brush Is Difficult to Work With

    Problem:
    It took me FOREVER just to figure out how to turn it off and there's no way to change its look.

    Suggestion for Fix:
    I don't really see how this would be needed if all of the above are taken care of.
    Attached Files
    Check out my ★★★★★ UE4 plugin if you want to go fast!
    • Feedback Event Factory: Perfect for managing sounds, particle systems, force feedback, camera shakes, time dilation, animations & more...all within a single Blueprint!

    #2
    1. It's much more complex than that. Describing focus is more complicated than a brush swap. Think Final Fantasy's Hand icon that bounces next to focused items in the menu. Additionally, the focused sound is an interesting problem, see you can't just signal for focusing, you've also got to allow people to be notified when focus was attempted, but failed, that way you can have menus that go, dink dink dink wwwng when you try to focus in a direction that doesn't take you anywhere. Anyway - valid complaint, it's something I'm considering.

    2. Yeah, planning to do something like that.

    3. Yup that problem is tough. I don't want to choose anything that prevents games from seamlessly moving from a mouse or controller UI when the user's input style changes.

    4. The focus brush isn't intended to be something people use in production, but it is useful when you're trying to figure out where focus is in development. Not sure what I'll do with it.

    I appreciate the feedback. I'm working on this stuff now that I'm done with the clipping changes, not sure when the changes will be ready.

    Comment


      #3
      Originally posted by Nick Darnell View Post
      1. It's much more complex than that. Describing focus is more complicated than a brush swap. Think Final Fantasy's Hand icon that bounces next to focused items in the menu. Additionally, the focused sound is an interesting problem, see you can't just signal for focusing, you've also got to allow people to be notified when focus was attempted, but failed, that way you can have menus that go, dink dink dink wwwng when you try to focus in a direction that doesn't take you anywhere. Anyway - valid complaint, it's something I'm considering.

      2. Yeah, planning to do something like that.

      3. Yup that problem is tough. I don't want to choose anything that prevents games from seamlessly moving from a mouse or controller UI when the user's input style changes.

      4. The focus brush isn't intended to be something people use in production, but it is useful when you're trying to figure out where focus is in development. Not sure what I'll do with it.

      I appreciate the feedback. I'm working on this stuff now that I'm done with the clipping changes, not sure when the changes will be ready.
      Thanks for responding, Nick! Just a few quick follow up comments:

      1. Describing focus could be more complicated than a brush swap, but I would then propose that describing hover could be more complicated than a brush swap, as well. As long as we have a simple option for describing it (brush swap) and events for doing more (see point 2), then I think we're set! For sound, I would propose a sound triggered upon focus, just like sound on a hover, is most important. Having an option to signal a failed focus might be nice, too, but less important, IMHO.

      2. Sweet!

      3. I agree you wouldn't want to lose any of the current functionality that allows switching between UI and viewport. However, I would definitely propose that we need a simple, clean solution for preventing it when we know we're in a state where it should never happen (e.g. typical pause menu in most games).

      4. Gotcha. I didn't realize it's not intended for use outside development, but that totally makes sense. If it's a debug tool, maybe have it off by default? It took me forever to find out how to turn it off cause I didn't even know what to call it when searching in the editor or on the internet
      Check out my ★★★★★ UE4 plugin if you want to go fast!
      • Feedback Event Factory: Perfect for managing sounds, particle systems, force feedback, camera shakes, time dilation, animations & more...all within a single Blueprint!

      Comment


        #4
        Sure. Need 'focus-events' for binding on init stage (constructor) in widget, for example.
        It would be help for develop navigation menu systems specially for gamepad/keyboard input.

        But 1st step with visual/audial stuff for 'focus' is not really need. Possible just use 'hover' for dat in WidgetBP logic like so.

        Any way if using keyboard/gamepad and mouse at same time need always to check what is your primary input device (to hide mouse cursor or not until mouse doesn't move/use).

        If 2nd feature request will be, it would be nice.

        Comment


          #5
          2nd feature.That's why I got here.I can't do that at all.

          Comment


            #6
            Hey how about this?Click image for larger version

Name:	Снимо1к.PNG
Views:	1
Size:	193.6 KB
ID:	1131602

            Comment


              #7
              Originally posted by Silêncio View Post
              Hey how about this?
              Looks interesting... It'd be great to see that in action [MENTION=805332]Silêncio[/MENTION]... Any chance of a Video etc?
              I often give up on focus. Just accept inputs to everything & filter using Gates + Game-States.

              Comment


                #8
                99% of the time the issues with focus that people have are because widgets that you *don't* want to be focusable often are. Make sure you uncheck the bIsFocusable flag in Blueprint, and set the widget visibility to something non-hit testable. Both are things you should do anyway really while building the widget.

                Comment


                  #9
                  Good evening, first of all with the focused and unFocused events the problems of making widgets with gampad or keyboard would be solved very much.

                  I've been a programmer for some time (Delphi, java, c ++ ... = but it's the first time I've programmed a videogame and use unreal engine 4.18.

                  After a lot of reading through forums and not getting much ... I have come up with a solution that I think is elegant that I am using (until we have the onFocus and onUnFocus events) and I wanted to share it with you ..

                  The code consists of the following_

                  Step 1: I enter manually All widget buttons in an array in the begin play event

                  In my case they are always inside a vertical box

                  Note: I do not think there is an array with all the elements of the widget, it's a pity because it would be very useful

                  Step 2: In a tick event I use a loop I check if the button is focused with a branch.

                  If this focus changed the normal style "imitating" hovered and if it is not, change to normal style

                  Step3: To not have the sound in loop I use a doOnce event that is reset each time the style is changed to focused with the variable focused

                  The integer variable "focused" saves the last element "focused", if the variable changes, it resets the doOnce function

                  Note1: The UnFocusButton function is simple because my buttons are transparent

                  Note2: I'm sorry for my english ... it's very bad

                  -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                  Buenas noches, antes de nada con los eventos focused y unFocused se solucionaría mucho los problemas de hacer widgets con gampad o teclado.

                  Soy programador desde hace tiempo (Delphi, java, c++...= pero es la primera vez que programo un videojuego y uso unreal engine 4.18.

                  Después de mucho leer por foros y no conseguir gran cosa... he llegado a una solución que me parece elegante que estoy utilizando (hasta que tengamos los eventos onFocus y onUnFocus) y quería compartirla con vosotros..

                  El código consiste en lo siguiente_

                  Paso 1: Introduzco manualmente Todos los botones del widget en un array en el evento begin play

                  En mi caso están siempre dentro de un vertical box

                  PD: Creo que no existe un array con todos los elementos del widget, es una lastima porque seria de gran utilidad

                  Paso 2: En un evento tick utilizo un loop compruebo si el boton esta focused con una rama.

                  Si esta focused cambio el estilo normal "imitando" hovered y si no lo esta, cambio a stilo normal

                  Paso3: Para no tener el sonido en loop utilizo un evento doOnce que es reseteado cada vez que cambia el estilo a focused con la variable focused

                  La variable integer "focused" guarda el ultimo elemento "focused", si la variable cambia, resetea la funcion doOnce

                  PD1: La funncion UnFocusButton es simple porque mis botones son transparentes
                  PD2: I' m sorry por mi ingles... es muy malo

                  Comment


                    #10
                    I never understood the focus in UMG, in the end I decided to create a custom UserWidget with a focus and lost focus custom delegates, all my widget inherited from this, and then when I receive inputs I look for all widgets of this class and only those marked as focusable, then by comparing their screen absolute position with the one in focus I was able to determine if something is focusable for the axis, let say if it was nothing at right then is not possible lost my focus, but if it was, then you can focus something new and broadcast the delegate for every widget,

                    Probably not the smart idea ever, but it does the job!

                    And why? because for that project I expended 2 days dealing with my widgets just in a effort to use properly the focus feature inside UE, but in change I expended just 1 day to implement my own,

                    I agree with the guy who began this thread, UMG is powerful but some stuff like this is confusing, not hard but confusing enough for me to create my own
                    Last edited by ZkarmaKun; 11-08-2017, 02:40 PM.

                    Comment


                      #11
                      I added this function to track widget focus in Ticks which is super gross/not optimized, but it makes for some WAY cleaner HUD blueprints.

                      Code:
                      UWidget* APFPlayerController::GetCurrentWidgetFocus()
                      {
                          for (TObjectIterator<UWidget> Itr; Itr; ++Itr)
                          {
                              if (Itr->HasUserFocus(this))
                                  return *Itr;
                          }
                      
                          return nullptr;
                      }
                      Check out my ★★★★★ UE4 plugin if you want to go fast!
                      • Feedback Event Factory: Perfect for managing sounds, particle systems, force feedback, camera shakes, time dilation, animations & more...all within a single Blueprint!

                      Comment


                        #12
                        Here is a brief description of my implementation.
                        For me, Focus means Hovered. same thing. So I edited SWidget.h to do that.
                        was a very simple change.
                        Code:
                            /** @return True if this widget hovered */
                            virtual bool IsHovered() const
                            {
                                return bIsHovered || HasKeyboardFocus();
                            }
                        Keyboard focus is the same for gamepad as well so this works. My buttons then get the Hovered Style through navigation provided I set the User Focus to a button. I made my own subclass of UUserWidget to manage focus, at well as addition and removal from the screen. This class keeps the last focused element. It's important in large UMGs to call focus when you show and hide panels, but otherwise nagivation works well.

                        in the Player controller I created an array of Widgets in a sort of stack (it's not really lifo because you could remove something that's not at index 0). and this is called by MyUserWidget. This allows me to automatically set the user focus back to the last focussed objects if I close a popup, or if I click outside the area with the mouse. We assume the player doesn't want to see focus at this point and focus is lost so everything works for them.

                        in MyGameViewportClient (subclass of GameViewportClient) I override InputAxis and InputKey which allows me to check if I pushed a gamepad or keyboard. This sends a message to my player controller which will refocus on the last element based on the Widget on top of my stack.

                        Hope that helps and I'm always ready to talk about it if you have questions or share some code.

                        Comment


                          #13
                          If you don't want to mess with engine code, you can re-implement your own button widget entirely using a UserWidget and add your own focus handling logic. It's a pain, unfortunately. There should be more exposed controls over focus handling logic. For an engine that focus consoles, it's a shame every dev has to hack together their own gamepad navigation code.

                          Comment


                            #14
                            Oh good. I thought I was being dumb for hacking together my own gamepad navigation because I just couldn't figure out how to use the built in stuff.

                            Comment


                              #15
                              I see from the previous comments that there may not be an easy solution to this, but I'm hoping there's a Blueprint solution that I'm overlooking.

                              As shown in the first image, I have a Main Menu that starts with the focus on the "Play" button from which the player can navigate with arrow keys down to select the other buttons.

                              As shown in the second image, pressing the "Option" button opens a different Options Menu widget with focus set on the "Video" button. However, when exiting this menu to reveal the Main Menu underneath, I cannot restore focus back to the "Play" button. *Note: When navigating with arrow keys the focus/navigation occurs on both in the Options menu in front as well as the Main Menu beneath. That is to say all focus has not truly shifted solely to the Options Menu when opened to conceal the Main Menu.

                              I'm not sure if this is possible. If not, I was hoping as a workaround to destroy the Main Menu widget beneath and recreate it upon exiting the Option Menu with the focus set to "Play" upon event construct. Unfortunately I have not been able to accomplish this either.

                              Any help with the proper way to fix this or even an ugly workaround would be greatly appreciated.
                              Attached Files

                              Comment

                              Working...
                              X