Installation
Installing Rish is simple. You can add the package via the Unity Package Manager using the Git URL, or by modifying your manifest.json file directly.
Add the following package URL: https://github.com/clockworklabs/rish#[target-version].
Dependencies
Rish requires the following dependencies to function correctly:
- Unity: 2022.3 or higher.
- Collections:
com.unity.collections(version1.2.4+). - Sappy:
io.clockworklabs.sappy(version1.0.0+).
Rishenerator (Source Generator)
Rish comes with a Roslyn Source Generator called Rishenerator. While it is technically possible to write all your Rish code manually, we strongly recommend using Rishenerator.
Why use Rishenerator?
- Drastically reduces development time by automating boilerplate.
- Eliminates errors associated with manual implementation.
- Optimizes performance and memory efficiency automatically.
Installing Rishenerator
- Open the Package Manager.
- Select the Rish package.
- Go to the Samples tab and import Rishenerator.
- In your project assets, locate the imported
Rishenerator.dll. - Crucial Step: In the Inspector for the DLL:
- Ensure the Select platforms for plugin list is empty (no platforms selected).
- Add (if not present already) the
RoslynAnalyzerlabel.
Setup
You can run multiple Rish apps simultaneously (e.g., one for Screen Space UI and another for World Space HUDs). Each app manages its own UI Toolkit tree.
To set up a Rish App in your scene:
- Create an empty GameObject (e.g., named “UI_Root”).
- Add the
RishRootcomponent to it. This will automatically add aUIDocumentcomponent if one is missing. - Assign your Panel Settings to the
UIDocument. - Create a class that implements
IAppand assign it to theRishRoot. - Assign all the USS style sheets your app will need to the
RishRoot.
Defining an App
A Rish App is the entry point for your UI. It is not an Element itself; rather, it defines the root element for the entire tree.
Basic Example
For a stateless, simple UI:
public class App : IApp
{
// The 'recovered' parameter indicates if the app has been recovered and relaunched after a crash.
// You can use this to show a message or something.
Element IApp.GetRoot(bool recovered) => H1.Create(text: "Hello, world!");
}Advanced Example (Stateful Root)
A common pattern is to have a “Root” element that manages high-level state (like loading progress) and mounts the rest of the application.
public partial class App : IApp
{
Element IApp.GetRoot(bool recovered) => Root.Create();
// The internal Root element manages the application state
private partial class Root : RishElement<NoProps, RootState>, IMountingListener
{
void IMountingListener.ElementDidMount() {
if(StaticData.IsLoaded)
{
// If data is already ready, set progress immediately
SetLoadingProgress(1);
} else {
// Subscribe to loading progress events
StaticData.OnLoadingProgress += SetLoadingProgress;
}
}
void IMountingListener.ElementWillUnmount() {
// Unsubscribe from loading progress events
StaticData.OnLoadingProgress -= SetLoadingProgress;
}
protected override Element Render() {
if(State.loaded) {
return GameScreen.Create();
}
return LoadingScreen.Create(progress: State.loadingProgress);
}
}
[RishValueType]
public struct RootState {
public float loadingProgress;
public bool loaded => loadingProgress >= 1;
}
}Next Steps
Now that you have the library installed, we recommend installing Roots and importing its samples to see working code in action.