https://github.com/eastrall/rosalina
Rosalina is a code generation tool for Unity's UI documents. It generates C# code-behind script based on a UXML template.
https://github.com/eastrall/rosalina
binding-generator code-behind code-generation csharp dotnet roslyn ui-builder ui-elements ui-toolkit uielements unity unity-editor unity-plugin unity-tool unity-tools unity-ui unity-uielement unity3d unity3d-plugin
Last synced: 16 days ago
JSON representation
Rosalina is a code generation tool for Unity's UI documents. It generates C# code-behind script based on a UXML template.
- Host: GitHub
- URL: https://github.com/eastrall/rosalina
- Owner: Eastrall
- License: mit
- Created: 2022-01-04T12:52:14.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-03-03T16:55:06.000Z (about 1 year ago)
- Last Synced: 2025-04-25T07:35:03.411Z (23 days ago)
- Topics: binding-generator, code-behind, code-generation, csharp, dotnet, roslyn, ui-builder, ui-elements, ui-toolkit, uielements, unity, unity-editor, unity-plugin, unity-tool, unity-tools, unity-ui, unity-uielement, unity3d, unity3d-plugin
- Language: C#
- Homepage:
- Size: 19.6 MB
- Stars: 146
- Watchers: 11
- Forks: 20
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Rosalina
[](https://openupm.com/packages/com.eastylabs.rosalina/)
Rosalina is a code generation tool for Unity's UI documents make with the new UI Toolkit. It automatically generates C# UI binding scripts based on a UXML document template.
## Key features
* [UI Documents](https://docs.unity3d.com/Manual/UIE-simple-ui-toolkit-workflow.html)
* Automatic C# bindings generation
* C# document script
* [`EditorWindow`](https://docs.unity3d.com/ScriptReference/EditorWindow.html) support
* Automatic C# bindings generation
* C# document script
* Custom Components
* Automatic C# bindings generation
* C# document script## 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``### Installing via OpenUPM
Rosalina is now available via OpenUPM:
https://openupm.com/packages/com.eastylabs.rosalina/OpenUPM provides a detailed explanation of how to add packages to unity.
### Installing via git repository
In Unity, navigate to ``Window -> Package Manager``:

In the ``Package Manager``, click on the ``+`` on the top left and select ``Add package from git URL...``

No use the following path to install Rosalina ``https://github.com/Eastrall/Rosalina.git``

You can now start to work with Rosalina.
## How it works
Rosalina watches your changes related to all `*.uxml` files contained in the `Assets` folder of your project, 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`**
```xml
```
Rosalina's `AssetProcessor` will automatically genearte the following C# UI bindings script:
> ℹ️ Note: All generated files are located in the `Assets/Rosalina/AutoGenerated/` folder.
**`SampleDocument.g.cs`**
```csharp
//
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 => _document?.rootVisualElement;
public void InitializeDocument()
{
TitleLabel = Root?.Q("TitleLabel");
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.
According to Unity's UI Builder warnings, a `VisualElement` names 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:```xml
```
Rosalina will generate the following property:
```csharp
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.
## How to use
After installing Rosalina, the code generation process is disabled by default, and should be enabled.
Go to `Edit > Project Settings > Rosalina` and enable it:
Once Rosalina is enabled, you will need to manually add a UXML file to the Rosalina's code generation processor.
To do so, right-click on a UXML file, go to `Rosalina > Properties...`:
The Rosalina's properties window opens next to the inspector tab, and you can enable it to add the current file to the Rosalina's code generation processor.

Rosalina provides three generator types:
* Document
* Component
* EditorChoose the generator type according to your needs.
When generating a UXML file binding-script, it will be automatically created and will be located at `Assets/Rosalina/AutoGenerated` and share it's name with a `.g.cs` extension.
You should **NOT** edit this file in any way or form, as it will be recreated on each change to the corresponding ``Visual Tree Asset`` document.
### UI Document
Generator Type: `Document`
When generating an UI Script, Rosalina will generate the following code:
```csharp
using UnityEngine;public partial class SampleDocument : MonoBehaviour
{
private void OnEnable()
{
InitializeDocument();
}
}
```
The `InitializeDocument()` method contains all the UI properties initialization. Every interaction with UI properties such as assigning a text to a label or an clicked event action to a button **MUST** be defined **after** the `InitializeDocument()` call. Otherwise, you will have a `NullReferenceException`.```csharp
using UnityEngine;public partial class SampleDocument : MonoBehaviour
{
private void OnEnable()
{
InitializeDocument();
TitleLabel.text = "Hello world!";
Button.clicked += OnConfirmButtonClicked;
}private void OnButtonClicked()
{
TitleLabel.text = "Button clicked";
}
}
```> Note, even if this file has been generated, you still can edit it because it will not be overwritten each time you change a UXML file.
### Custom components
To use a UI Document as an Unity's Editor Window, set the Generator type in Rosalina's properties window, to `Component`.

Take this UXML file for example:
```xml
```
Rosalina's code generator will generate the following class:
```csharp
//
using UnityEngine.UIElements;public partial class CustomComponent
{
public Label TitleLabel { get; private set; }public Button SampleButton { get; private set; }
public VisualElement Root { get; }
public CustomComponent(VisualElement root)
{
Root = root;
TitleLabel = Root?.Q("TitleLabel");
SampleButton = Root?.Q("SampleButton");
}
}
```Then when using this component in another UI Document, Editor or component, Rosalina will automatically initialize it using it's constructor:
```xml
```
```csharp
//
using UnityEngine;
using UnityEngine.UIElements;public partial class SampleDocument
{
[SerializeField]
private UIDocument _document;// Other UI element properties...
public CustomComponent MyCustomComponent { get; private set; }
public VisualElement Root => _document?.rootVisualElement;
public void InitializeDocument()
{
// Other initializations...CustomLabel = new CustomComponent(Root?.Q("MyCustomComponent"));
}
}
```
In your `SampleDocument` script, you can access the `CustomLabel` just like any other UI element or object instance:
```csharp
using UnityEngine;public partial class SampleDocument : MonoBehaviour
{
private void OnEnable()
{
InitializeDocument();
// Setting the TitleLabel's text within the CustomLabel component.
CustomLabel.TitleLabel.text = "Hello world!";
}
}
```### Editor Window
To use a UI Document as an Unity's Editor Window, set the Generator type in Rosalina's properties window, to `Editor`.
Take this UXML file for example:
```xml
```
Rosalina's code generator will generate you a class that extends the `UnityEditor.EditorWindow`:
```csharp
//
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;public partial class CustomEditorWindow : EditorWindow
{
public Button SampleButton { get; private set; }public void CreateGUI()
{
VisualTreeAsset asset = AssetDatabase.LoadAssetAtPath("Assets/...");
VisualElement ui = asset.CloneTree();
rootVisualElement.Add(ui);
SampleButton = rootVisualElement?.Q("SampleButton");
OnCreateGUI();
}partial void OnCreateGUI();
}
```When generating an UI Script, Rosalina will generate the following code:
```csharp
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;public partial class CustomEditorWindow : EditorWindow
{
partial void OnCreateGUI()
{
}
}
```Every interaction with UI properties such as assigning a text to a label or an clicked event action to a button **MUST** be defined **inside** the `OnCreateGUI()` method:
```csharp
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;public partial class CustomEditorWindow : EditorWindow
{
partial void OnCreateGUI()
{
SampleButton.clicked += OnSampleButtonClicked;
}private void OnSampleButtonClicked()
{
Debug.Log("Hello world!");
}
}
```If you want, you can also control the behavior of the window and tell Unity how to open it; for instance, with from a `Menu Item`:
```csharp
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;public partial class CustomEditorWindow : EditorWindow
{
[MenuItem("Window/My Custom Editor Window")]
public static void ShowWindow()
{
EditorWindow.CreateWindow("My Custom Editor Window!");
}partial void OnCreateGUI()
{
SampleButton.clicked += OnSampleButtonClicked;
}private void OnSampleButtonClicked()
{
Debug.Log("Hello world!");
}
}
```This will add a new entry named `My Custom Editor Window` to the `Window` menu item:

And when clicking on that menu item, the custom editor window will appear and you can now interact with the elements:

## Notes
As pointed out by [JuliaP_Unity](https://forum.unity.com/members/juliap_unity.4707193/) on [Unity Forums](https://forum.unity.com/threads/share-your-ui-toolkit-projects.980061/#post-7799040) 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!*## Known limitations
* The generated files share the name of the `Visual Tree Asset`. Currently, it's not possible to change the script names.
* Rosalina currently does not support namespaces.## Final words
If you like the project, don't hesitate to contribute! All contributions are welcome!