1. Add the UPM package
- Open the latest release
Download the Unity
.tgzfrom Assets. - Add it in Package Manager
Choose + → Add package from tarball and select the downloaded archive.
- Import the sample
Open Samples on the Gua package page and import Runtime UI Fixture for a scene containing the supported UI systems.
2. Understand automatic startup
Godot game code calls attach() and update(). The Unity UPM package owns the equivalent work automatically, so each scene does not need a Gua initialization script.
| Internal step | What it means for game code |
|---|---|
GuaUnityRuntime.EnsureStarted() | Creates the runtime and WebSocket bridge once before scenes load. |
GuaUnityBootstrap.LateUpdate() | Collects UI after ordinary Update work for the frame. |
BeginFrame → collect → EndFrame | Publishes UI Toolkit, uGUI, and TMP as one consistent semantic snapshot. |
| Action dispatch | Applies remote requests to Unity controls and returns request-correlated results. |
3. Implement UI Toolkit controls
Place standard controls below a runtime UIDocument; name or viewDataKey provides stable identity.
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<ui:Button name="start" text="Start Game" />
</ui:UXML>Read the UXML
| Code | Meaning |
|---|---|
<ui:UXML xmlns:ui="UnityEngine.UIElements"> | Creates a UXML document using standard UI Toolkit elements. |
<ui:Button name="start" text="Start Game" /> | Creates the button; name=start is also a stable Gua ID candidate. |
using UnityEngine;
using UnityEngine.UIElements;
public sealed class TitleScreen : MonoBehaviour
{
[SerializeField] private UIDocument document;
private void OnEnable()
{
var root = document.rootVisualElement;
var start = root.Q<Button>("start");
start.clicked += () => Debug.Log("Start Game");
}
}Read the UI Toolkit script
| Code | Meaning |
|---|---|
using UnityEngine.UIElements; | Imports UIDocument, VisualElement, and Button. |
public sealed class TitleScreen : MonoBehaviour | This is an ordinary game MonoBehaviour, not a Gua base class. |
[SerializeField] private UIDocument document; | Receives the scene UIDocument through the Inspector. |
private void OnEnable() | Registers the listener when the GameObject becomes active. |
document.rootVisualElement | Gets the root of the VisualElement tree created from UXML. |
root.Q<Button>("start") | Finds the UXML button by name; Gua uses that name for identity too. |
start.clicked += ... | Registers a normal Unity listener. Remote Gua clicks follow the same event path. |
Buttons, toggles, text fields, sliders, dropdowns, and lists are reflected automatically.
4. Implement uGUI or TextMeshPro controls
Place standard controls below a Canvas. Add GuaId when a GameObject needs a stable long-lived test ID.
using Gua.Unity;
using UnityEngine;
using UnityEngine.UI;
public sealed class TitleScreen : MonoBehaviour
{
[SerializeField] private Button startButton;
private void Awake()
{
var id = startButton.GetComponent<GuaId>()
?? startButton.gameObject.AddComponent<GuaId>();
id.Value = "start";
startButton.onClick.AddListener(() => Debug.Log("Start Game"));
}
}Read the uGUI script
| Code | Meaning |
|---|---|
using Gua.Unity; | Imports Unity-facing types such as GuaId. |
[SerializeField] private Button startButton; | Receives the Canvas button through the Inspector. |
private void Awake() | Prepares identity and listeners before the first collected frame. |
startButton.GetComponent<GuaId>() | Reuses an existing identity component. |
?? startButton.gameObject.AddComponent<GuaId>() | Adds GuaId only when one is missing. |
id.Value = "start" | Pins an ID that survives hierarchy refactoring. |
startButton.onClick.AddListener(...) | Registers the normal uGUI listener used by both users and Gua actions. |
TextMeshPro buttons, input fields, dropdowns, and text are collected from the same Canvas hierarchy. See GuaRuntimeUiSample.cs and GuaUnityFixture.cs for complete examples.
5. Add stable identity where needed
UI Toolkit prefers viewDataKey, then name. uGUI/TMP prefers GuaId.Value, otherwise it derives an ID from scene path, Transform names, and sibling indices.
using Gua.Unity;
startButton.gameObject.AddComponent<GuaId>().Value = "start";
screenRoot.AddComponent<GuaScreen>().Value = "title";What identity and screen names do
| Code | Meaning |
|---|---|
using Gua.Unity; | Makes GuaId and GuaScreen available. |
AddComponent<GuaId>().Value = "start" | Exposes the button under stable node ID start. Reuse an existing component in production code. |
AddComponent<GuaScreen>().Value = "title" | Publishes title as the logical screen name; keep one component per logical screen. |
6. Connect external tools
The bridge listens on 8765 by default. Set GUA_BRIDGE_PORT before process startup to override it. Inspector and gui-mcp use the same bridge as other Gua adapters.
Observation rules
- Hidden controls remain observable with
visible: false; disabled state is reflected separately. - Bounds use physical screenshot pixels, top-left origin, X rightward, Y downward.
- Actions are applied to Unity controls and completed with a request-correlated result.
- Rendered Player and Play Mode support PNG capture. Batchmode or
-nographicsreportsheadless.