Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
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: about 13 hours 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 (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2024-03-03T16:55:06.000Z (8 months ago)
- Last Synced: 2024-10-10T10:06:56.993Z (about 1 month 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: 134
- Watchers: 13
- Forks: 18
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Rosalina
[![openupm](https://img.shields.io/npm/v/com.eastylabs.rosalina?label=openupm®istry_uri=https://package.openupm.com)](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``:
![image](https://user-images.githubusercontent.com/4021025/204278700-989b139c-cbf3-4c56-8ebe-91309258aac2.png)
In the ``Package Manager``, click on the ``+`` on the top left and select ``Add package from git URL...``
![image](https://user-images.githubusercontent.com/4021025/204278730-38f06044-b298-484e-b6ad-43cb1684134e.png)
No use the following path to install Rosalina ``https://github.com/Eastrall/Rosalina.git``
![image](https://user-images.githubusercontent.com/4021025/204278754-8bfa4b2d-dd57-4a59-af45-ff05470272fc.png)
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:![image](https://github.com/Eastrall/Rosalina/assets/4021025/124c946f-1a66-404e-8b91-1a3ed02d7c56)
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...`:![image](https://github.com/Eastrall/Rosalina/assets/4021025/047b3b35-c913-4a38-9fc9-99127b68d887)
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.
![image](https://github.com/Eastrall/Rosalina/assets/4021025/d4bf640a-a653-48b3-badc-602b5ebb4a09)
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`.
![image](https://github.com/Eastrall/Rosalina/assets/4021025/db621190-4a49-43cb-8c28-89592dccf23a)
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:
![image](https://user-images.githubusercontent.com/4021025/204351292-d34f54e3-b3bb-4efb-a79b-b2768fb257fa.png)
And when clicking on that menu item, the custom editor window will appear and you can now interact with the elements:
![image](https://user-images.githubusercontent.com/4021025/204351418-008a1521-c796-4ec6-852c-43a2a5064e4d.png)
## 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!