NOTE: version 1.7 and newer will have gamepad support for menus and inventory, so this tutorial is somewhat irrelevant now. I will leave it up as reference tho.
UE4 by default uses either Slate (C++) or UMG (Blueprints) to render UI and other HUD elements on screen. I wish this would get implemented into the engine by default, because currently gamepad integration doesn’t seem to be very high on the priority list for UMG, so in order to navigate to different buttons and forms, you can either make an array of buttons, set focus manually, change “hover” color manually and so on.. or you can do it kinda like in Destiny, it’s also faster and easier.
The solution is to use a plugin called “GamepadUMGplugin”, the original code for it was written by Nick Darnell from Epic Games and can be viewed HERE. The plugin version was made by Rama and the forum post can be viewed HERE (visit the forums to find the version that you need if it’s not listed on this page). EDIT: new forum broke links, restored link HERE.
As you can see it seems to be abandoned at version 4.16, so I ported it over to newer versions, you can download them here:
Now that you have the version that you need, we can move on with the tutorial.
Step 1: Extract it to your engine plugin folder
Step 2: (NOT REQUIRED FOR 4.26) Create a new folder where your project is and call it Plugins, then copy/paste the same plugin there too
Step 3: Open your project, go to Edit > Plugins and enable it, then restart the Editor
Step 4: You can now call it from any Blueprint that supports “Get Player Controller” to test it out, create a new Widget, add a button to it and recreate this Blueprint graph
As you can see, the idea is to call “Enable Virtual Cursor” when the Widget is opened, and “Disable Virtual Cursor” then it’s closed.
The analog-stick moves the mouse cursor, the “A” button (xbox controller) acts as left mouse click.
You can use this for Main Menu, Inventory, etc.
NOTE: In case the mouse cursor is not moving after first time copying it, restart the editor, it will then initialize it correctly (and each time after that).