UE4 UMG to Lua translator tool
During my internship, and some of my work, at Team6 game studios I developed a tool to translate UMG UI assets in Unreal Engine 4 to Lua code files. Team6 had implemented Lua in UE4 to handle the UI, and wanted the ability for artists and designers to use the UMG editor to create menus and such, but for programmers to add functionality to them in Lua afterwards.
This was added to this portfolio website with permission from Team6 game studios.
This was added to this portfolio website with permission from Team6 game studios.
The tool consists of a few separate parts. Above you can see the toolbar of the UMG editor, with an added button to open the Lua translator tool.
To the left you can see the tool window, with all available options for translation. For a more extensive description of the options available in this tool, please read the documentation I wrote for it, as it's a bit too long to include here. ![]()
A short description of the shown options:
Two commands: one to allow the user to select a save directory, and one to start the translation. The name of the target widget, The save directory (editable, also set with the command) The name of the translated file. The translation type (either Menu, Class or loose widget data) Allow overwriting (overwrites previous file content if a file already exists with that name) Insert at line nr, for allowing to add to an existing file rather than overwriting it. |
The tool can be used to translate a UMG UI Widget into Lua code that creates an equivalent result. Below you can see a simple example widget, and part of the generated Lua. Not all generated lines of code are always necessary, but removing those lines is left to the programmer as the tool has no knowledge of the default values of the equivalent Lua classes.
Below you can see snippets from the code that generates the toolbar button and the tool window. When the module starts up, during the engine startup sequence, it registers a new button at the relevant module, as well as the relevant commands. When that button is pressed a new instance of the tool window is opened, closing any other existing windows for this tool. This ensures only one instance of this tool is ever open at any time.
The third and fourth code snippets show the translation sequence, gathering widget data and then translating it. The translation code will be shown a bit later.
The third and fourth code snippets show the translation sequence, gathering widget data and then translating it. The translation code will be shown a bit later.
an ImAfterTheOnce the widget data has been gathered and passed to the translator, it goes through several phases of translation.
In the code samples below there are several #defines that are used:
INDENT_INCREASE and decrease increase the number of tab characters in the Indent string variable.
WIDGET_NAME gets the name of the widget we are currently translating from the map containing the widget data.
WIDGET is simply a way of accessing the current source widget we are translating from the total widget data, used for quick access.
First we check what we are translating as, usually a menu (image 1 below). This adds the necessary lines around the translated widget data.
Then we translate the individual source widgets that make up the user widget (image 2 below). For this we refer to a relevant translation function via a map containing function pointers.
After that we translate the parenting hierarchy (image 3 below), at the end of the file since all source widgets will have been created at that point.
The final image shows an example translation function for a source widget, in this case an Image.
In the code samples below there are several #defines that are used:
INDENT_INCREASE and decrease increase the number of tab characters in the Indent string variable.
WIDGET_NAME gets the name of the widget we are currently translating from the map containing the widget data.
WIDGET is simply a way of accessing the current source widget we are translating from the total widget data, used for quick access.
First we check what we are translating as, usually a menu (image 1 below). This adds the necessary lines around the translated widget data.
Then we translate the individual source widgets that make up the user widget (image 2 below). For this we refer to a relevant translation function via a map containing function pointers.
After that we translate the parenting hierarchy (image 3 below), at the end of the file since all source widgets will have been created at that point.
The final image shows an example translation function for a source widget, in this case an Image.
These are but a few samples of the code in this tool, as there is too much code to quickly cover here.