Graphene
Graphene for Unity UI Toolkit is a lightweight and modular framework for building user interfaces
Install / Use
/learn @LudiKha/GrapheneREADME
Graphene is a lightweight and modular framework for building runtime user interfaces with Unity's UI Toolkit.
Intro
Graphene superconducts your creativity for efficiently building modern interactive UI for games. It takes care of the heavy lifting by providing a framework inspired by Web standards, right into Unity.
It's lightweight and modular - you get to pick and choose which parts you need for your projects.
- Declarative Hierarchy: Graphene makes it painless to design interactive UI. Use the familiar GameObjects hierarchy to design simple
Viewsas sections of the screen or nested states. - Reduce Boilerplate: Focus on your custom logic and design of building UI instead of repeating low-level tasks for each unique screen you are building. Graphene comes with a number of
Controlsthat greatly enhance the speed of creating interactive UI, whilst reducing the need of custom view controllers in C# by exposing vital functionality in Uxml. - Attribute-Based: Instruct your UI to both draw and bind templates using any data-container with a
[Bind]attribute. Primitives, objects, collections, one-way, two-way binding, specific control selection: the parts you'll be most frequently developing with in C# are exposed via attributes - State-Based Routing: Use the GameObject hierarchy dynamically construct your router's states. Its functionality mimics url-based addresses:
index/settings/video. - Template Composition: Reuse your static assets by writing atomic templates, and dynamically compose them in runtime.
It comes with a component-kit library, sample project several VisualElement extensions and an online demo to get you started.
Online Demo
Check out the WebGL demo
Installation
Using Unity Package Manager (For Unity 2018.3 or later)
<details> <summary>You can install the package via UPM by adding the line below to your project's `Packages/manifest.json` file.</summary>
</details>You can find this file by opening your project's Packages folder in a file browser, it is not displayed in the editor.
{
"dependencies": {
"com.graphene.core": "https://github.com/LudiKha/Graphene.git?path=/src",
"com.graphene.components": "https://github.com/LudiKha/Graphene-Components.git?path=/src",
...
},
}
Do note that although both components and demo are optional packages, it is recommended you use them to kickstart your own Graphene-based development environment.
Staying updated
Updating the package can be done via Window/Graphene/Check for updates. Unity currently does not support updating Git packages via the Package Manager automatically.
Using UPM Git Extension
The best way to install Graphene and stay up to date with the latest versions, is to use UPM Git Extension.
- Follow the installation instructions
- In the Package Manager, click the
button, and add https://github.com/LudiKha/Graphene.gitunder subdirectorysrc, with the latest version. - Voilá! As an added bonus you are now able to update the package via the package manager.
Quickstart
For a quick start, Graphene comes with a component library and sample project - it is highly recommended to start your new project using the demo scene and resources provided within this project.
1: Constructing the hierarchy
- Construct the high-level UI hierarchy, where each unique state is represented by a GameObject
- Add a
Platecomponent to each GameObject in the tree, with aGraphenecomponent at the root. - For each Plate in the tree, assign a static asset to its UIDocument. Root states will typically need a Layout-style
templatefor their children to be fitted in.
Press play - Graphene will now dynamically construct the VisualTree based on your GameObject hierarchy. You've completed the required part of Graphene - however, we are still getting started.
Let's draw and bind some data onto our UI.
2: Rendering & binding a model
-
Add a
Themeto the root Graphene component. -
Add one or more
Renderercomponents to eachPlatethat has dynamic (instantiated) content -
Assign a
Modelto the Renderer - this is a data container that serves as the model for the data-binding. -
In the type(s) assigned as model, select the members you wish to expose for binding by adding
BindAttributes. Add an additionalDrawAttributeto dynamically instantiate controls in runtime usingTemplates.
Press play - Graphene will draw templates, and bind them to the model. If a static asset contained a control with a binding-path (e.g. a label with Model.Title), this will be bound to the model too.
The hierarchy is created and detail fields are rendered dynamically - now all that remains is to switch states.
3: Routing
- Add a
StringRouterto the root GameObject. - Add a
StringStateHandleto eachPlateGameObject that needs to be activated or deactivated based on states. Children are automatically deactivated with their parents. Give the StateHandleStateIdunique names (e.g. "start", "load", "exit"). - For each
Platethat has one or more children using states, select which child state is enabled by default by tickingenableWithParent - In order to navigate, we can instantiate controls with a
RouteAttributeor statically type them in UXML. Make sure to set the route member to a value that corresponds the available states.
Note: It is also possible to encapsulate a button within a Route element.
<gr:Route route="/settings"> <ui:Button text="Clicking me will change state"/> </gr:Route> <gr:Route binding-path="~Model/ExitState">
Press play - The router constructs its state tree from the Plate hierarchy. When clicking a route element (or child button), the router will attempt to change states and the view will display this state change accordingly.
Congrats! You're now done with the Quickstart and ready to tackle your first project using Graphene.
Core Concepts
Graphene decouples fine-grained authoring from high-level logic, and in doing so aims to leverage UI Toolkit's innovations to the fullest.
Plates
A Plate represents a view controller in the VisualTree, and is used by Graphene to display the hierarchy, its states and views.
A Graphene hierarchy consists of nested components called Plates, with a Graphene component at the root. Plates are the core of Graphene, are analogous for a general-purpose UI controller that can be switched on or off. Other, optional MonoBehaviour components may hook into a plate, and have their functionality based on whether a plate is active or not.
The following components and logic depends on plates:
- View
These can be authored in the familiar GameObject hierarchy. Graphene then constructs the VisualElement tree at runtime into a nested view.
Views
A View represents a section of the screen, and is defined as a VisualElement within the Plate's UXML asset. It contains an 'id', which serves as a unique identifier within the plate. Examples of views include a sidebar, a content area, a header or footer.
Views can be used to compose static content (i.e. child Plates composing into parent Views), or to render dynamic content into (i.e. a renderer drawing a list of items into a View).
By default, Graphene components assume these two types of views will be present on a Plate:
- Content View: A view that is used to render dynamic content into, using a
Renderercomponent. - Children View: A view that is used to compose child plates into, based on the GameObject hierarchy.
Rendering & Binding
Rendering refers to the process of drawing and binding a model to the view. This is done using a Renderer component. It requires a Model to be assigned, which serves as the data container for the binding.
I
