/Rosalina

Rosalina is a code generation tool for Unity's UI documents. It generates C# code-behind script based on a UXML template.

Primary LanguageC#MIT LicenseMIT

Rosalina

openupm

Rosalina is a code generation tool for Unity's UI documents. It allows developers to generate C# UI bindings and code-behind scripts based on a UXML template.

How to install

Rosalina can either be installed via OpenUPM: https://openupm.com/packages/com.eastylabs.rosalina/ Or by using the following git repository: https://github.com/Eastrall/Rosalina.git

For a more detailed explanation, see our documentation.

How to use

We provided some introduction to Rosalina's file generation in our documentation. Just follow this link.

How it works

Rosalina watches your changes related to all *.uxml files, parses its content and generates the according C# UI binding code based on the element's names.

Take for instance the following UXML template:

SampleDocument.uxml

<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements"
         xsi="http://www.w3.org/2001/XMLSchema-instance"
         engine="UnityEngine.UIElements" editor="UnityEditor.UIElements"
         noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
    <ui:VisualElement>
        <ui:Label text="Label" name="TitleLabel"/>
        <ui:Button text="Button" name="Button"/>
    </ui:VisualElement>
</ui:UXML>

Rosalina's AssetProcessor will automatically genearte the following C# UI bindings script:

SampleDocument.g.cs

// <autogenerated />
using UnityEngine;
using UnityEngine.UIElements;

public partial class SampleDocument
{
    [SerializeField]
    private UIDocument _document;
    public Label TitleLabel { get; private set; }

    public Button Button { get; private set; }

    public VisualElement Root
    {
        get
        {
            return _document?.rootVisualElement;
        }
    }

    public void InitializeDocument()
    {
        TitleLabel = (Label)Root?.Q("TitleLabel");
        Button = (Button)Root?.Q("Button");
    }
}

⚠️ This script behing an auto-generated code based on the UXML template, you should not write code inside this file. It will be overwritten everytime you update your UXML template file.

Rosalina provides a context-menu option to generate a C# UI script where you can place your UI related code without the risk of behing overwritten by Rosalina's asset processor. Just right click on the UXML and access Rosalina menu-item, then select Genearte UI script.

image

This option will generate the following code:

SampleDocument.cs

using UnityEngine;

public partial class SampleDocument : MonoBehaviour
{
    private void OnEnable()
    {
        InitializeDocument();
    }
}

Notes

As pointed out by JuliaP_Unity on Unity Forums the document initialization process (element queries) should be done on the OnEnable() hook, since the UIDocument visual tree asset is instancied at this moment. Thank you for the tip!

According to Unity's UI Builder warnings, a VisualElement name can only contains letters, numbers, underscores and dashes. Since a name with dashes is not a valid name within a C# context, during the code generation process, Rosalina will automatically convert dashed-names into PascalCase. Meaning that if you have the following UXML:

<ui:VisualElement>
    <ui:Button text="Button" name="confirm-button"/>
</ui:VisualElement>

Rosalina will generate the following property:

public Button ConfirmButton { get; private set; }

In case you already have a ConfirmButton as a VisualElement name, do not worry, Rosalina will detect it for you during the code generation process and throw an error letting you know there is a duplicate property in your UXML document.

Known limitations

For now, Rosalina only generates the UI Document bindings and code behding scripts based on the UI element names. You still need to create on your own the GameObject with a UIDocument component and then add the UI script (not the UI binding scripts).

ℹ️ In next versions, we could think of an extension that automatically creates a GameObject with the UI script attached to it. 😄

Final words

If you like the project, don't hesitate to contribute! All contributions are welcome!