Software Engineering
| Olaf Spiewok |
11 July 2023
In part 1 of this series, we started exploring how the right tools can make your game development processes easier and more efficient, using the example of our BuildAndDeploy package.
Creating tools helps you to improve your productivity. Tools can save time, reduce the cost spent on repetitive tasks and reduce the risk of errors by streamlining the build and deploy processes. The time and effort saved by using a tool will enable you to spend that time on more important tasks or may simply help you to shorten your time to market and make your builds available much faster – especially for Games as a Service, shortening release cycles is critical for the success of a game.
In this part, let’s look at another Unity tool our team developed.
UI Toolkit – UXML Binding Generator
- Developer(s): Robert Stamm, Robert Geithe, Olaf Spiewok
- Unity compatibility: 2019.x – latest
- UXML Binding Generator on Github
Introduction
Unity has implemented its new UI Toolkit, which allows you to create UIs by decoupling the interface within XML-like files (called *.uxml) and binding them to the appropriate game and UI state. The XML contains the structure of the UI hierarchy and allows you to customise the appearance of each node with various attributes, like name, size, colour, margin etc. This is especially helpful in a large-scale project since it reduces collision between UI, logic and scene by having multiple files and a well-documented history of UI changes.
One drawback of this decoupling is that splitting UI from logic can result in incorrect code assignments if the UI component name attribute or type changes and the logic code is not updated correctly. That’s where our Binding Generator comes into play.
Our motivation
The Binding Generator creates a code class for each UI XML file, which will allow you to easily detect changes in your UIs. Once a UXML file is changed by adding new elements or changing its type or the name attributes of an element node, the generated code will allow you to throw compiler errors wherever those nodes get used within the code. This prevents runtime exceptions and corrupted UI states and gives you a consistent overview of all ‘UI content’ while developing any one specific UI. This helps to improve your productivity – and gives you that warm feeling that everything is going well. Similar approaches apply to the Microsoft XAML UI, Android UI or iOS interface builders.
Usage and benefits
We tried to make the tool as easy to use as possible, so we made a package. Simply add it using the Unity package manager, and you are ready to go. Follow the instructions in the documentation (./getting-started.md) to get an overview of how to use the tool. To give you a head start, here’s a sneak preview and some benefits the Binding tool may give you:
1. You can customise your Binding approach using the Uxml Binding Settings within the Project Settings. Besides selecting the template file, which is used to generate the code, you will find various properties to customise your auto-generated code file. You can change the namespace, class name format and the output directory to which all your bindings will be saved. In addition, there are multiple ‘Binding Generator Types’, which allow you to be more memory-, performance- or debug-aware when auto-generating your code files.2. After a Unity UXML file is changed, right-click on the file(s) or folder(s) and use the context menu to trigger the code generator for each file. You can also toggle “On Changed” binding generation within the UXML Binding settings to automate this. Once the binding class is created, you need to instantiate it within your code and associate it to your VisualTreeAsset to get your queries and your properties filled. Since all properties now reflect an element in your UI hierarchy, any changes or an updated generator file will let the compiler report any inconsistencies at compile time.
3. The tool is highly customisable, and you can change the Script Template used for the auto-generation process. You want to have a class or struct? Derive it from a given base class or interface? Contain multiple convenient methods? Just change the template, and you can tailor the generated files to your requirements!
4. You can convert all UXML files at once using the file context menu, which will spare you lots of manual conversions. If you want to exclude some folders from the process, you can select these as ‘ignored folders’. Using CI systems, you can also update the code as a ‘pre-build’ step to ensure all your files are up to date.
5. Querying code within your logic UI classes is moved to the Binding classes/structs, which makes your code clean and robust.
6. The UXML Binding Generator is a lightweight package that you don’t need to add to your published code. Once all binding files have been generated, the generator package can be removed without dependency issues since only the generated code itself is needed.
The only drawback of all this file-binding is that, depending on your generator type, a slight memory footprint may remain when you create thousands of Binding classes/structs. You can minimise that footprint by changing the generator type and, in edge-case scenarios where lists create thousands of visual tree assets, adding static methods inside the templates. Thus, you can find the binding approach best suited for your project and even derive or partialise your auto-generated binding classes to make the most of them.
A practical example
To demonstrate how helpful the binding package can be, imagine a complex UI like the one in Unity’s Dragon Crashers sample.
A vast number of buttons, labels, list items, tabs and the like are grouped within various UI files and reflect each UI element within the sample.
All node entries have a type and a name attribute with which you can identify the VisualElement within your code. In a project without the UXML Binding Generator package, you would have to query each individual node element by using the query method:
Somewhere within your business logic, a number of query methods combined with constant string declarations will allow you to access and use the corresponding node element, which hopefully matches the loaded UXML file.
But what happens if a designer or developer changes the name attribute or type of the queried element? You’ll have to change the constant or adjust the query type manually… a step that is easily forgotten, which can lead to exceptions or issues that you can only detect at runtime.
Using the Binding Generator – and training your team to remember to generate the corresponding code files after changing a UI – will move all of this querying code to an automatically generated file, which can be instantiated and accessed by using properties instead:
Whenever the UXML gets changed, an update of the Binding file will be instantly reflected in the code since the properties have changed and give you compile time feedback.
No null references at runtime and no longer hours of remapping between UI and business logic needed… fantastic, right?!
Conclusion
The UXML Binding Generator gives you a lot of flexibility to convert the XML files created by UI designers into code-generated files which you can work with on the programming side. This will bypass many headaches around changes in UI files, which you’d often only detect within runtime. Since all related changes will now be reflected in properties available at compile time, the compiler can support you with any inconsistencies.
Whenever we have a project using UI Toolkit, we include this package to avoid all the manual querying.
No matter if your project contains 1 or 1000 UXML files, using the Binding Generator gives you the freedom to get the UI filled up with logic and the ability to wire a safety net around the relationship between the two.
Olaf Spiewok
Senior Developer
Olaf has been part of Endava for more than 13 years, with his focus being on game development. As a universal game development whizz, he is comfortable working with different platforms, like standalone systems, Nintendo DS, television, or mobile, and frameworks, among them Unity, React, Cocos, Android, and iOS – and the associated variety of programming language skills. Olaf is proficient in a diverse range of game development areas, including UI, workflow, gameplay, integration, and maintenance. Besides his development work, Olaf spends his free time with his family and dog, playing games – digital and analogue, indoors and outdoors – as well as learning to understand the Berlin dialect.ALL CATEGORIES
Related Articles
-
04 July 2023
Boost Your Game’s Success with Tools – Part 1
-
25 January 2023
The Joy and Challenge of being a Video Game Tester
-
14 November 2022
Can Software Really Be Green
-
17 May 2022
An R&D Project on AI in 3D Asset Creation for Games
-
25 January 2022
Scalable Microservices Architecture with .NET Made Easy – a Tutorial