{"id":13663056,"url":"https://github.com/LudiKha/Graphene","last_synced_at":"2025-04-25T13:31:23.038Z","repository":{"id":52232418,"uuid":"295206457","full_name":"LudiKha/Graphene","owner":"LudiKha","description":"Graphene for Unity UI Toolkit is a lightweight and modular framework for building user interfaces","archived":false,"fork":false,"pushed_at":"2024-01-29T17:55:40.000Z","size":2039,"stargazers_count":147,"open_issues_count":1,"forks_count":9,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-11-10T19:33:41.632Z","etag":null,"topics":["attributes","csharp","css","game-development","graphene","html","toolkit","ui","ui-components","unity","unity3d","uss","uxml","web"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LudiKha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["LudiKha"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-09-13T17:53:35.000Z","updated_at":"2024-07-25T18:52:22.000Z","dependencies_parsed_at":"2024-08-02T05:16:39.930Z","dependency_job_id":"dce675be-3d1b-4138-8626-66bacf4906de","html_url":"https://github.com/LudiKha/Graphene","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LudiKha%2FGraphene","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LudiKha%2FGraphene/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LudiKha%2FGraphene/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LudiKha%2FGraphene/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LudiKha","download_url":"https://codeload.github.com/LudiKha/Graphene/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250824938,"owners_count":21493368,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["attributes","csharp","css","game-development","graphene","html","toolkit","ui","ui-components","unity","unity3d","uss","uxml","web"],"created_at":"2024-08-02T05:02:16.223Z","updated_at":"2025-04-25T13:31:21.558Z","avatar_url":"https://github.com/LudiKha.png","language":"C#","funding_links":["https://github.com/sponsors/LudiKha"],"categories":["C\\#"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/LudiKha/Graphene/master/docs/images/graphene-logo-full.png\" /\u003e\n\u003c/p\u003e\n\n\u0026nbsp;\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ![last-commit](https://img.shields.io/github/last-commit/LudiKha/Graphene) ![open-issues](https://img.shields.io/github/issues/LudiKha/Graphene) [![](https://img.shields.io/twitter/follow/LudiKha.svg?label=Follow\u0026style=social)](https://twitter.com/intent/follow?screen_name=LudiKha)\n\nGraphene is a lightweight and modular framework for building runtime user interfaces with Unity's [UI Toolkit][0f273cb2].\n\n[0f273cb2]: https://docs.unity3d.com/2020.1/Documentation/Manual/UIElements.html \"UI Toolkit\"\n\n\u0026nbsp;\n\n# Intro\n\nGraphene **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.\n\nIt's **lightweight** and modular - you get to pick and choose which parts you need for your projects.\n\n- **Declarative Hierarchy**: Graphene makes it painless to design interactive UI. Use the familiar GameObjects hierarchy to design simple `Views` as sections of the screen or nested states.\n- **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 `Controls` that greatly enhance the speed of creating interactive UI, whilst reducing the need of custom view controllers in C# by exposing vital functionality in Uxml.\n- **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\n- **State-Based Routing**: Use the GameObject hierarchy dynamically construct your router's states. Its functionality mimics url-based addresses: `index/settings/video`.\n- **Template Composition**: Reuse your static assets by writing atomic templates, and dynamically compose them in runtime.\n\nIt comes with a **[component-kit][e593c071]** library, **[sample project][05f1d8f6]** several VisualElement extensions and an **[online demo][84ed822d]** to get you started.\n\n  [e593c071]: https://github.com/LudiKha/Graphene-Components \"Graphene Components\"\n  [05f1d8f6]: https://github.com/LudiKha/Graphene-Sample-Project \"Graphene-Sample-Project\"\n  [84ed822d]: https://ludikha.github.io/Graphene-WebGL-Demo/ \"Graphene-WebGL-Demo\"\n\n\n## Online Demo\n### [Check out the WebGL demo ][f45eaa31]\n\n  [f45eaa31]: https://ludikha.github.io/Graphene-WebGL-Demo/ \"Graphene WebGL demo\"\n\n\n## Installation\n### Using Unity Package Manager (For Unity 2018.3 or later)\n\n\u003cdetails\u003e\n  \u003csummary\u003eYou can install the package via UPM by adding the line below to your project's `Packages/manifest.json` file.\u003c/summary\u003e\n\n\u0026nbsp;\n\n  \u003eYou can find this file by opening your project's *Packages* folder in a file browser, it is not displayed in the editor.\n\n\u003c/details\u003e\n\n```\n{\n  \"dependencies\": {\n    \"com.graphene.core\": \"https://github.com/LudiKha/Graphene.git?path=/src\",\n    \"com.graphene.components\": \"https://github.com/LudiKha/Graphene-Components.git?path=/src\",\n    ...\n  },\n}\n```\n\n\u003eDo note that although both components and demo are optional packages, it is recommended you use them to kickstart your own Graphene-based development environment.\n\n#### Staying updated\nUpdating the package can be done via `Window/Graphene/Check for updates`. Unity currently does not support updating Git packages via the Package Manager automatically.\n\n\n### Using UPM Git Extension\nThe best way to install Graphene and stay up to date with the latest versions, is to use [UPM Git Extension][49fed258].\n   1. Follow the [installation instructions][2ddc031d]\n   2. In the Package Manager, click the ![Git button](docs/images/installation/git.png) button, and add `https://github.com/LudiKha/Graphene.git` under subdirectory `src`, with the latest version.\n   3. Voilá! As an added bonus you are now able to update the package via the package manager.\n\n  [49fed258]: https://github.com/mob-sakai/UpmGitExtension \"Upm Git Extension\"\n  [2ddc031d]: https://github.com/mob-sakai/UpmGitExtension#installation \"UP Git Extension Installation Instructions\"\n\n\n\u0026nbsp;\n\n---\n\n\u0026nbsp;\n\n# Quickstart\n\nFor a quick start, Graphene comes with a component library and [sample project][52a86b14] - it is **highly** recommended to start your new project using the demo scene and resources provided within this project.\n\n  [52a86b14]: https://github.com/LudiKha/Graphene-Sample-Project \"Graphene Sample Project\"\n\n#### 1: Constructing the hierarchy\n- Construct the high-level UI hierarchy, where each unique state is represented by a GameObject\n- Add a [`Plate`][0fb2479e] component to each GameObject in the tree, with a `Graphene` component at the root.\n- For each Plate in the tree, assign a static asset to its UIDocument. Root states will typically need a Layout-style [`template`](https://github.com/LudiKha/Graphene#template) for their children to be fitted in.\n\nPress 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.\n\nLet's draw and bind some data onto our UI.\n\n#### 2: Rendering \u0026 binding a model\n- Add a [`Theme`][a617f693] to the root Graphene component.\n- Add one or more [`Renderer`][b39c255d] components to each `Plate` that has dynamic (instantiated) content\n- Assign a [`Model`][19f2ae47] to the Renderer - this is a data container that serves as the model for the data-binding.\n- In the type(s) assigned as model, select the members you wish to expose for binding by adding [`BindAttribute`][b3387189]s. Add an additional `DrawAttribute` to dynamically instantiate controls in runtime using [`Templates`][fe269940].\n\n  [a617f693]: https://github.com/LudiKha/Graphene#theming \"Theming\"\n\nPress 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`][04efb446]), this will be bound to the model too.\n\n  [04efb446]: https://github.com/LudiKha/Graphene#scopes \"Scopes\"\n\nThe hierarchy is created and detail fields are rendered dynamically - now all that remains is to switch states.\n\n#### 3: Routing\n- Add a [`StringRouter`][1015cb88] to the root GameObject.\n- Add a `StringStateHandle` to each `Plate` GameObject that needs to be activated or deactivated based on states. Children are automatically deactivated with their parents. Give the StateHandle `StateId` unique names (e.g. \"start\", \"load\", \"exit\").\n- For each `Plate` that has one or more children using states, select which child state is enabled by default by ticking `enableWithParent`\n- In order to navigate, we can instantiate controls with a `RouteAttribute` or statically type them in UXML. Make sure to set the route member to a value that corresponds the available states.\n\n\n\u003e Note: It is also possible to encapsulate a button within a Route element.\n\u003e ```html\n\u003e\u003cgr:Route route=\"/settings\"\u003e\n\u003e  \u003cui:Button text=\"Clicking me will change state\"/\u003e\n\u003e\u003c/gr:Route\u003e\n\u003e\n\u003e\u003cgr:Route binding-path=\"~Model/ExitState\"\u003e\n\u003e```\n\n\nPress 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.\n\n  [0fb2479e]: https://github.com/LudiKha/Graphene#plates \"Plates\"\n  [b39c255d]: https://github.com/LudiKha/Graphene#rendering \"Renderer\"\n  [19f2ae47]: https://github.com/LudiKha/Graphene#model \"Model\"\n  [1015cb88]: https://github.com/LudiKha/Graphene#routing \"Router\"\n  [b3387189]: https://github.com/LudiKha/Graphene#binding \"Binding\"  \n  [fe269940]: https://github.com/LudiKha/Graphene#templating \"Templating\"\n\nCongrats! You're now done with the Quickstart and ready to tackle your first project using Graphene.\n\n\u0026nbsp;\n\n---\n\n\u0026nbsp;\n\n# Core Concepts\n\nGraphene decouples fine-grained authoring from high-level logic, and in doing so aims to leverage UI Toolkit's innovations to the fullest.\n\n## Plates\nA `Plate` represents a view controller in the VisualTree, and is used by Graphene to display the hierarchy, its states and views.\n\nA Graphene hierarchy consists of nested components called `Plates`, with a `Graphene` component at the root. `Plate`s 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.\n\nThe following components and logic depends on plates:\n- View\n\nThese can be authored in the familiar GameObject hierarchy. Graphene then constructs the VisualElement tree at runtime into a nested view.\n\n## Views\n\n## Rendering\n\n## Model\n\n## Templating\n### Template\nA `Template` is a semantic name for static asset that represents a chunk of UXML of varying granularity and complexity, which are used as building blocks to build and render the application. Moreover, templates can be declared directly in UXML based, and will be rendered at runtime based on the `Renderer` template configuration. Templates are wrapped in a `TemplateAsset` ScriptableObject, where additional variants can be created without needing to create and maintain copies of the base template.\n\n#### Why use templates\n\nWhen creating a simple element, such as a button, it may quickly end up consisting of several carefully configured elements and bindings:\n\n```html\n\u003cui:Button text=\"Button\" name=\"ButtonFramed\" focusable=\"true\" tooltip=\"This is a button\" binding-path=\"Value\" class=\"button button-framed light\"\u003e\n  \u003cui:Style src=\"ButtonFramed.uss\" /\u003e\n  \u003cgr:Route binding-path=\"Route\" class=\"button__route\" /\u003e\n  \u003cgr:Tooltip binding-path=\"Description\" class=\"button__tooltip\" /\u003e\n  \u003cui:VisualElement class=\"button__background\" /\u003e\n  \u003cui:Label text=\"Label\" binding-path=\"Label\" /\u003e\n  \u003cui:VisualElement class=\"button__hover\" /\u003e\n  \u003cui:VisualElement class=\"button__frame\" /\u003e\n\u003c/ui:Button\u003e\n```\n\nMaintaining multiple versions and instances of the same chunk of UXML throughout multiple files can be both error prone and time intensive. Graphene allows you to reuse the same template, and instantiate them at runtime when required.\n\n#### Creating a template\n\nCreate a `TemplateAsset` via the following menu command:\n\u003e  `Assets/Create/Graphene/Templating/TemplateAsset`\n\nAssign a static UXML template, and give it an appropriate name.\n\n#### Instantiating a template via CSharp\nTemplates can be instantiated directly in C# via a reference of the `TemplateAsset`.\n```csharp\nvar clone = myTemplateAsset.Instantiate();\n...\n\n```\n#### Instantiating a template via UXML\n Graphene allows you to statically type control types using the following syntax:\n\n```html\n\u003cgr:Button text=\"Button\" name=\"ButtonFramed\" focusable=\"true\" tooltip=\"This is a button\" binding-path=\"Value\" class=\"button button-framed light\" /\u003e\n```\nAt runtime, the button will be rendered to the full syntax of the first snippet, using the `Template` configuration of the `Renderer` component that initiates the binding.\n\n## Binding\n\n### Binding Modes\nGraphene supports 3 modes of binding a model to the view. These can either be specified in the BindAttribute on the model, or using the Binder API directly.\n- **OneTime**: Instructs the `Binder` to only \"print\" the model once onto the view. No continuous binding will be attempted. Useful for immutable data, such as titles, labels or button callbacks.\n\u003eNote: Prefixing the binding-path with the `::` syntax instructs the binder to use a one-time binding.\n\u003e```html\n\u003e\u003cui:Label binding-path=\"::Title\" /\u003e\n\u003e```\n\n- **OneWay**: Creates a continuous binding from the model to the view. Updates are polled continuously but only for bindings that are currently visible (based on `Plate` state). Polling rate can be configured in the `Graphene` component.\n- **TwoWay**: Creates a two-directional binding (from model to view, and view to model) for controls that support two-way binding. View to model binding is based on `INotifyPropertyChange` callbacks.\n\n### Scopes\n- Scope drilldown `.` `Renderer.Model.ChildObject.Title`\n- Scope transferral `~` `~Renderer.Model` \u003e `ChildObject.Title`\n\n### Binding Passes\n1. Static\n2. Dynamic\n### Static Binding\n\n### Dynamic Binding\n\n## Routing\n\n## Theming\n### Theme\nA `Theme` is a data asset that can be used to author high-level styling configurations for (parts of) the VisualTree. It consists of a collection of [StyleSheets][3ca719d7], and can be nested to create reusable styling configurations using overrides.\n\n  [3ca719d7]: https://docs.unity3d.com/Manual/UIE-USS.html \"Unity USS Stylesheet\"\n\n#### Using themes\n\nCreate a theme via the following menu command:\n\u003e  `Assets/Create/Graphene/Theming/Theme`\n\nThemes are assigned to the VisualTree when assigned to the `Graphene` component, or a sub-section when assigned to a `Plate`.\n\nTo manually apply a theme to a VisualElement, the following method is available.\n\n```csharp\nmyTheme.ApplyStyles(el);\n\n```\n\n## Localization\n\n## Step-by-step process\n1. Static view composition\n2. Static binding pass\n3. Render templates from dynamic model\n4. Dynamic binding pass\n5. Runtime one-way/two-way binding\n\n\n\u0026nbsp;\n\n---\n\n\u0026nbsp;\n\n# Inspector Extensions\nGraphene supports two third party inspector extensions out of the box: [Sirenix Odin Inspector][5855fee6] (paid) and [NaughtyAttributes][06602d8c] (free). Graphene relies on these to expose optional enhanced functionality to the inspector windows.\n\n[5855fee6]: https://odininspector.com/ \"Sirenix Odin Inspector\"\n[06602d8c]: https://github.com/dbrizov/NaughtyAttributes \"Naughty Attributes\"\n\n## Installation\n### Odin Inspector\nThis asset is automatically setup when it is included in the project.\n \u003e Define symbol: `ODIN_INSPECTOR`\n\n### Naughty Attributes\nThis package requires you to follow the following steps:\n1. Add the package to the project `Packages/manifest.json` file:\n\n   \u003e`\"com.dbrizov.naughtyattributes\": \"https://github.com/dbrizov/NaughtyAttributes.git#upm\"`\n2. In Project Settings/Player/Scripting define symbols, add the following entry: `NAUGHTY_ATTRIBUTES;`\n\nAfter recompilation, your project will now have enhanced inspector functionality for Graphene components.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLudiKha%2FGraphene","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLudiKha%2FGraphene","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLudiKha%2FGraphene/lists"}