1. UPMパッケージを追加する
- Latest Releaseを開く
AssetsからUnity用
.tgzをダウンロードします。 - Package Managerへ追加
+ → Add package from tarballを選択して、ダウンロードしたファイルを指定します。
- サンプルを取り込む
Package ManagerのGua詳細画面でSamplesを開き、Runtime UI FixtureをImportすると、対応UIをまとめたシーンを確認できます。
2. 自動起動の仕組みを理解する
Godot版ではゲーム側がattach()とupdate()を呼びますが、Unity版ではUPMパッケージが同じ責務を自動で引き受けます。sceneごとにGua初期化scriptを追加する必要はありません。
| 内部処理 | 利用者から見た意味 |
|---|---|
GuaUnityRuntime.EnsureStarted() | scene読込前にruntimeとWebSocket bridgeを一度だけ作ります。 |
GuaUnityBootstrap.LateUpdate() | 通常のUpdate()後に、そのframeのUI状態を収集します。 |
BeginFrame → collect → EndFrame | UI Toolkit、uGUI、TMPを一つの整合したSemantic UI Treeとして公開します。 |
| action配送 | 外部requestをUnity Controlのevent/value変更へ適用し、request ID付き結果を返します。 |
3. UI Toolkitで実装する
BeforeSceneLoadでbootstrap driverとruntimeの2つの非表示・永続GameObjectが作られます。driverのLateUpdate()がruntimeのframe処理を進めます。利用者による初期化、semantic node登録、毎フレーム呼び出し、破棄処理は不要です。
UIDocument以下へ標準Controlを配置します。nameまたはviewDataKeyがGuaの安定IDとして使われます。
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<ui:Button name="start" text="Start Game" />
</ui:UXML>UXMLの各記述
| 記述 | 意味 |
|---|---|
<ui:UXML xmlns:ui="UnityEngine.UIElements"> | UI Toolkit標準elementを使うUXML documentのルートです。 |
<ui:Button name="start" text="Start Game" /> | 表示textがStart GameのButtonを作り、name=startをGuaの安定ID候補にします。 |
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");
}
}UI Toolkit scriptを上から読む
| 記述 | 意味 |
|---|---|
using UnityEngine.UIElements; | UIDocument、VisualElement、ButtonなどUI Toolkit型を読み込みます。 |
public sealed class TitleScreen : MonoBehaviour | scene上のGameObjectへ付ける通常のgame scriptです。Gua専用base classではありません。 |
[SerializeField] private UIDocument document; | Inspectorから、このscriptが操作するUIDocumentを割り当てます。 |
private void OnEnable() | GameObjectが有効になった時点でButton listenerを登録します。 |
var root = document.rootVisualElement; | UIDocumentが生成したVisualElement treeのルートを取得します。 |
root.Q<Button>("start") | UXMLのname=startを持つButtonを検索します。このnameはGuaのnode IDにも使われます。 |
start.clicked += ... | 通常のUnity click listenerです。Guaの外部clickもこのevent経路を通るため、test専用分岐は不要です。 |
上の例ではUXML側のButtonへname="start"を設定します。Button、Toggle、TextField、Slider、DropdownField、ListViewなどは自動的にSemantic UI Treeへ反映されます。
4. uGUI / TextMeshProで実装する
Canvas以下へ標準uGUI Controlを配置します。長期間テストから参照するGameObjectにはGuaIdを追加して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"));
}
}uGUI scriptを上から読む
| 記述 | 意味 |
|---|---|
using Gua.Unity; | 任意の安定IDを付けるGuaIdなどUnity向け公開型を読み込みます。 |
[SerializeField] private Button startButton; | Canvas上のuGUI ButtonをInspectorから割り当てます。 |
private void Awake() | listenerやIDを、最初のGua frameが収集される前に準備します。 |
startButton.GetComponent<GuaId>() | 既にGuaIdが付いていれば再利用します。 |
?? startButton.gameObject.AddComponent<GuaId>() | 無い場合だけGuaIdを追加し、componentの重複を避けます。 |
id.Value = "start" | scene階層変更に影響されない固定node IDを設定します。 |
startButton.onClick.AddListener(...) | 通常のuGUI listenerを登録します。Gua clickもこのlistenerを発火させます。 |
TextMeshProのButton、InputField、Dropdown、Textも同じCanvas階層から収集されます。サンプル全体はGuaRuntimeUiSample.csとGuaUnityFixture.csで確認できます。
5. 安定IDと画面名を付ける
IDは自動生成されますが、テストから長期間参照する要素にはGuaIdを付けます。UI ToolkitはviewDataKey、次にnameを優先します。uGUI/TMPはGuaId.Valueが無ければscene path、Transform名、sibling indexから生成します。
using Gua.Unity;
startButton.gameObject.AddComponent<GuaId>().Value = "start";
screenRoot.AddComponent<GuaScreen>().Value = "title";IDと画面名の意味
| 記述 | 意味 |
|---|---|
using Gua.Unity; | GuaIdとGuaScreen componentを参照できるようにします。 |
AddComponent<GuaId>().Value = "start" | ButtonのGameObjectを外部testからstartという固定IDで参照できるようにします。既存componentがある場合はGetComponentで再利用してください。 |
AddComponent<GuaScreen>().Value = "title" | 現在の論理画面名をtitleとして公開します。画面単位のroot GameObjectへ一つだけ付けます。 |
6. 外部接続を許可する
既定のWebSocketポートは8765です。プロセス起動前にGUA_BRIDGE_PORTを設定すると変更できます。Inspectorとgui-mcpはGodot版と同じブリッジへ接続します。
観測と操作の原則
- 非表示nodeは消去せず、
visible: falseとして観測します。無効状態もenabledへ反映します。 - boundsはスクリーンショットと同じ物理pixel座標です。原点は左上、Xは右、Yは下です。
- クリック、focus、値変更、選択、scroll、キー入力はUnityのControlへ適用され、request ID付きのaction結果が返ります。
- 画面キャプチャはrendered Player/Play Modeで利用できます。batchmodeまたは
-nographicsではheadlessを返します。