> For the complete documentation index, see [llms.txt](https://docs.flatredball.com/gum/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flatredball.com/gum/code/getting-started/setup/adding-initializing-gum/unity.md).

# Unity

{% hint style="warning" %}
The Unity package is experimental. It supports Windows x64 and macOS (Intel and Apple silicon). Linux, Android, iOS, and WebGL are not supported yet.
{% endhint %}

Gum for Unity draws Gum UI (layout, Forms controls, and `.gumj` projects) with SkiaSharp. It needs two Unity packages: Gum, and SkiaGameRendering (v0.20.0 or newer), which supplies SkiaSharp.

## Quick Start

1. Install the two packages (see **Install the Packages** below). Gum requires Unity 6 or newer.
2. In the Project window, create a C# script (**Assets > Create > Scripting > MonoBehaviour Script**) named `GumExample`, and replace its contents with the script under **Full Script** below. It is the whole setup: it creates the `Gum` GameObject with `GumRenderer` and `GumInput`, so you don't add anything to your scene.
3. Press **Play**. A button labeled "Click me" appears in the Game view.

`GumRenderer` sets up Gum in `Awake`, so your own code can create UI from `Start` or later. Gum updates and draws itself, so the script has no `Update` or `Draw`.

## Install the Packages

1. Open **Window > Package Manager**.
2. Click the **+** button, then **Install package from git URL**.
3. Paste this URL and click **Install**:

   ```
   https://github.com/vchelaru/SkiaGameRendering.git#upm
   ```
4. Repeat with this URL:

   ```
   https://github.com/vchelaru/Gum.git#upm
   ```

You can also add both lines to `Packages/manifest.json` instead:

```json
"com.vchelaru.skiagamerendering": "https://github.com/vchelaru/SkiaGameRendering.git#upm",
"com.vchelaru.gum": "https://github.com/vchelaru/Gum.git#upm"
```

The `#upm` at the end of each URL tells Unity to use the ready-to-install copy of the package that Gum publishes with each release. It always points at the newest one. Unity does not update on its own, so to upgrade, reinstall the package or use the update button in Package Manager.

To stay on a specific Gum version, end the Gum URL with `#upm/v<version>` instead, for example `#upm/v2026.10.2-preview.2.2`. Each version is listed under [Gum's tags on GitHub](https://github.com/vchelaru/Gum/tags) as `upm/v<version>`.

## What the Components Do

* `GumRenderer` sets up Gum and draws the UI over the screen.
* `GumInput` passes Unity's mouse, touch, keyboard, and gamepad input to Gum each frame. It belongs on the same GameObject as `GumRenderer`.

## Input

The Input System package is optional. If your project uses it and **Edit > Project Settings > Player > Active Input Handling** is **Input System Package (New)** or **Both**, `GumInput` reads it for the mouse, touch, keyboard, and gamepads. If **Active Input Handling** is **Input Manager (Old)**, `GumInput` reads Unity's legacy `Input` class for the mouse, touch, and keyboard. Gamepads are not available with the legacy Input Manager.

Mouse and touch work right away. To move between Forms controls with the keyboard or a gamepad, call `GumUI.UseKeyboardDefaults()` or `GumUI.UseGamepadDefaults()` in your script.

## Using the Code Samples in These Docs

Most code samples on other pages are written for a `Game` class. In Unity, adapt them like this:

* Code under a `// Initialize` comment goes in your script's `Start` method.
* Code under a `// Update` comment goes in your script's `Update` method. Skip any `GumUI.Update` call, since `GumRenderer` already updates Gum.
* Skip any `GumUI.Draw` call, since `GumRenderer` already draws Gum.
* Add `GumService GumUI => GumService.Default;` to your script, as in **Full Script**.

Samples that use MonoGame types such as `GameTime`, `GraphicsDevice`, or `Microsoft.Xna.Framework.Color` do not apply to Unity.

## Loading a Gum Project

1. Copy your Gum project folder into `Assets/StreamingAssets`.
2. Set `GumRenderer.ProjectFile` to the `.gumj` path inside that folder, for example `GumProject/GumProject.gumj`.

If you add the components from code, add them to an inactive GameObject, set `ProjectFile`, then activate the GameObject.

## Rendering

Gum draws on the GPU through SkiaGameRendering on every graphics API it supports, including Direct3D 11 and Metal. On any other API, such as WebGL, `GumRenderer` logs an error and disables itself; there is no CPU fallback. `GumRenderer.Texture` holds the result. Turn off `GumRenderer.DrawToScreen` to display the texture yourself.

## IL2CPP

If you build with IL2CPP, add an `Assets/link.xml` file that keeps `netstandard`:

```xml
<linker>
  <assembly fullname="netstandard" preserve="all" />
</linker>
```

## Generated Code in an Assembly With No Engine References

Code generated by the Gum tool registers its types at startup. In Unity it does this with Unity's `RuntimeInitializeOnLoadMethod` attribute, which lives in `UnityEngine`. An assembly definition with **No Engine References** checked cannot see `UnityEngine`, so that attribute does not compile there.

To use generated code in such an assembly, define `GUM_NO_UNITY_ENGINE` in **Edit > Project Settings > Player > Scripting Define Symbols**. The generated code then uses `[System.Runtime.CompilerServices.ModuleInitializer]` instead of the Unity attribute.

Unity does not run `[ModuleInitializer]` methods, so call the registration yourself at startup, before you create any generated screen or component:

* Each generated element's `RegisterRuntimeType()` method.
* `StandardElementsCodeGenRegistration.RegisterFallbackStandardElements()`, which the tool generates into your project's root namespace. It is `internal`, so call it from the same assembly. Without it, standard element states and categories assigned by generated code silently do nothing.

## Full Script

```csharp
using Gum;
using Gum.Forms;
using Gum.Forms.Controls;
using Gum.Unity;
using UnityEngine;

public class GumExample : MonoBehaviour
{
    GumService GumUI => GumService.Default;

    // Optional: a Gum project copied into Assets/StreamingAssets (see Loading a Gum Project below).
    // Leave empty to build the UI in code only.
    const string ProjectFile = "";

    // Runs once after the first scene loads, so the script does not need to be on a GameObject.
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    static void Bootstrap()
    {
        // Inactive while it is set up: GumRenderer initializes Gum in Awake, which runs as soon as
        // the GameObject becomes active.
        var host = new GameObject("Gum");
        host.SetActive(false);

        var renderer = host.AddComponent<GumRenderer>();
        renderer.ProjectFile = ProjectFile;
        host.AddComponent<GumInput>(); // Passes Unity's mouse, touch, keyboard, and gamepad input to Gum

        host.AddComponent<GumExample>();
        host.SetActive(true);
    }

    void Start()
    {
        // Optional: move between Forms controls with the keyboard or a gamepad (see Input).
        GumUI.UseKeyboardDefaults();
        GumUI.UseGamepadDefaults();

        var button = new Button();
        button.Text = "Click me";
        button.AddToRoot();
        button.Click += (_, _) => button.Text = $"Clicked\n{System.DateTime.Now}";
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.flatredball.com/gum/code/getting-started/setup/adding-initializing-gum/unity.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
