Choosing a package
| Package | Use | Target |
|---|---|---|
com.link1345.gua | The UPM package for Unity projects, including automatic startup, UI collection, actions, and screenshots | Unity 6000.0+ |
Gua.Runtime | Shared runtime API for implementing another engine adapter | net10.0 / netstandard2.1 |
Gua.Testing.Unity | Build, launch, and connect to the Unity Editor or Player from external .NET tests | net10.0 / netstandard2.1 |
Gua.Testing | Engine-neutral testing API for locators, assertions, remote connections, and screenshots | Engine-neutral |
Gua.Testing.Visual | Add PNG baseline comparison and diff artifacts to any Gua context, including Unity | net10.0 / netstandard2.1 |
Gua.Testing.Recording | Record and replay semantic actions against any Gua context, including Unity | net10.0 / netstandard2.1 |
Unity public types
| Type | Contract |
|---|---|
GuaUnityRuntime | Automatically started MonoBehaviour; exposes EnsureStarted() and manual RunFrame() |
GuaId | Optional stable Value for uGUI/TMP GameObjects |
GuaScreen | Optional logical screen Value; otherwise active scene name/path |
IGuaUnityControlAdapter | TryDescribe/TryApply extension point for custom uGUI-like controls |
GuaUnityAdapterRegistry | Add control adapters with Register(adapter) |
GuaUnityKeyEvent | Maps protocol keys and modifier bits to Unity Events |
Gua.Runtime surface
Normal Unity projects do not need to call this layer directly because the UPM package manages it. When building a custom engine adapter, GuaRuntime creates and owns the native runtime and destroys its bridge and handle in Dispose(). Its primary API includes StartInspectorBridge/StopInspectorBridge, SetAdapterVersion, BeginFrame/EndFrame, RegisterNode, TryConsumeAction/EmitActionResult, TryConsumeScreenshotRequest/CompleteScreenshot, AddLog, GetUiTreeJson, and GetVersionJson.
Test-host API
| Member | Meaning |
|---|---|
UnityPlayerBuilder.Build | Batch-build a Windows64 Mono Player for one scene |
LoadPlayer | Start a headless Player |
LoadRenderedPlayer | Start a rendered Player |
LoadEditor | Start a scene through the StartPlayMode editor command |
BuildAndLoadPlayer | Build and launch in one call |
Context / RemoteContext | Shared IGuaContext / WebSocket implementation |
CaptureScreenshot | Wait for an on-demand PNG after the current frame sequence |
CreateDiagnosticsSession | Add Unity log and process metadata to shared artifacts |
UI mapping
| Role | UI Toolkit | uGUI / TMP | Actions |
|---|---|---|---|
| button | Button | Button / Button with TMP label | click, focus |
| checkbox | Toggle | Toggle | click, focus, set_checked |
| textbox | TextField | InputField / TMP_InputField | focus, set_value, press_key |
| slider | Slider / SliderInt | Slider | focus, set_value |
| combobox | DropdownField | Dropdown / TMP_Dropdown | focus, select |
| list / listitem | ListView and all itemsSource entries | No standard mapping | focus, select, scroll |
| tablist / tab | TabView / Tab | No standard mapping | select |
| scrollarea | ScrollView | ScrollRect | scroll |
| text / panel | Label / fallback | Text, TMP_Text / fallback | Observe only |
Each frame collects role, label, text/value, visible, enabled, focused, checkbox checked state, ListView item selected state, slider range, parentId, and bounds. Virtualized offscreen ListView entries still get nodes, but unrealized entries have visible: false and zero bounds.
Actions and completion
The adapter consumes only actions declared by the target role. It emits the original requestId after synchronous Unity listeners return; it does not wait for coroutines, async void, or next-frame work. Invalid numbers, choices, and keys return invalid_value; unavailable combinations return unsupported. Exceptions are logged to both Gua and the Unity Console and become failed results.
press_key modifier bits are 1=Shift, 2=Alt, 4=Control, and 8=Command. Enter, Esc, and Arrow* aliases are normalized to Unity KeyCode names. A global key request is routed to the focused textbox.
Engine-neutral specification
version_v1includes an optionaladapterVersionsmap. Unity reports the loaded native runtime version as{"unity":"<runtime version>"}.godotPluginVersionremains for compatibility and is null outside Godot.- Adapter bounds use physical viewport pixels with a top-left origin and positive right/down axes; NaN and Infinity are not allowed.
GuaWebSocketContext, the remote tree, and captured screenshots are available fromGua.Testing.- The C ABI includes
gua_runtime_set_adapter_version(runtime, adapter, version); existing exports remain available. - A screenshot consumed before a session reset completes as
stale_session, preventing an old image from appearing in the new session.
Lifecycle and ownership
BeforeSceneLoad creates two persistent GameObjects: a bootstrap driver and the runtime. Driver LateUpdate() runs begin → collect → end → dispatch actions → service screenshot requests. Destruction stops the bridge and disposes the native handle. The UPM artifact bundles Gua.Core.dll, Gua.Runtime.dll and dependencies, gua.dll, and gua_runtime.dll.
Usage notes
- For screens that need external integer-slider changes, use
Sliderfor now.SliderIntstate can still be observed. - Toggle clicks are delivered as value changes. Custom behavior should listen for value/change events as well as pointer events.
- When registering a custom Control, implement the role's actions in
TryApply. Observation-only controls can use a role without interactive actions. - Parallel Unity test hosts use dynamic ports. Avoid running an unrelated process that pins the same port range.