Remote debugging for Unity: connect any running player to OmniDebugLink and let your AI coding tool traverse the scene, tap the UI and read logs — over the internet, no USB cable.
The Unity SDK is a UPM package (com.omnidebuglink.unity) that attaches to a running Unity player — the editor, a device build, a standalone desktop build or a WebGL build — and bridges it to your AI tool over MCP. The AI can dump the live hierarchy, find objects by name, displayed text or component type, take screenshots, read logs, check performance, click buttons through Unity's real event pipeline, and edit component fields via reflection — no rebuild in the loop.
Editor, device, standalone and WebGL. The bundled transport picks the browser WebSocket (jslib) on WebGL and ClientWebSocket everywhere else.
No background threads: socket events, reconnects and heartbeats are all driven from the main thread, so task handlers can use the Unity API freely.
Hierarchy dumps that carry live rendered text, per-node component views, and reflection-based field reads and writes — UGUI, NGUI and FairyGUI included.
Clicks are raycast through the EventSystem and delivered as pointerDown/Up/Click on the topmost clickable object — tutorial overlays receive them like a real tap.
One flag disables every write operation. The read-only state is announced on connect, so the AI knows up front what it may do.
The bundled UnityWebSocket copy is renamed at the type, symbol and file level — it will not clash if your project already ships that library.
com.unity.nuget.newtonsoft-json, which is resolved automatically.clientToken goes into your build; your AI tool signs in with your account instead.In Unity, open Package Manager → Add package from git URL and paste:
https://github.com/omnidebuglink/omnidebuglink_unity.git
To pin a released tag for reproducibility, append it to the URL. Drop the #vX.Y.Z suffix to track main (bleeding edge).
https://github.com/omnidebuglink/omnidebuglink_unity.git#v0.7.0
One call connects, registers every built-in task, announces capabilities and starts the log buffer. OmniDebugLink.Stop() shuts it down cleanly.
using OmniDebugLink;
public class Boot : MonoBehaviour
{
void Start()
{
OmniDebugLink.Start("<clientToken>");
}
}
Set this before Start for a strict read-only session — every write task is refused while reads, screenshots and logs keep working.
OmniDebugLink.ActionsEnabled = false; // default is true
Register a handler with a name, a short description and a payload schema. Handlers run on the main thread in the player loop, the returned object is serialized back to the AI, and a thrown exception becomes an error result. Any registry change re-announces capabilities automatically — no server-side changes.
OmniDebugLink.Tasks.Register("my_task", handler, description, payloadSchema);
Everything below ships in the package and is advertised to the AI on connect. Write tasks are all gated by ActionsEnabled.
| Task | What it does |
|---|---|
scene_traverse | Full hierarchy dump (3000-node cap). Nodes that render text carry the live text value — UGUI Text, TextMeshPro, InputField — so the AI reads labels straight from the tree. |
find_objects | Search by node name (substring or regex), displayed text, or component type. Hits carry center coordinates and a click_target (nearest clickable ancestor) that feeds ui_click. |
view_component | One node in depth: UGUI and layout properties, NGUI and FairyGUI dictionaries, plus reflection-based field inspection for anything else. |
list_component | List the components attached to a node. |
wait_for | Poll until a path appears or a component field reaches a value (200 ms interval). Timeouts return found: false instead of an error. |
screenshot | JPEG capture at end of frame, returned as a native image block; auto-compresses to fit the relay frame budget. |
read_logs | 1000-entry ring buffer of Debug.Log, warnings and exceptions with stack traces, filterable by level, substring, limit and time. |
get_perf | Mono and total memory, GC counts, fps and frame-time percentiles (p50/p95/p99), FrameTiming cpu/gpu times where available, battery. |
prefs | Read or list PlayerPrefs. The same task also writes and deletes — see below. |
| Task | What it does |
|---|---|
ui_click | Physically delivered: raycasts from the target's center through the EventSystem and runs pointerDown/Up/Click on the topmost clickable object, so overlays and intercept layers see it like a real tap. Locates by path or rendered text (text="Start" clicks the button labelled Start); index disambiguates. |
tap_screen | Tap at normalized 0-1 coordinates (bottom-left origin), through the same raycast pipeline. |
swipe | Drag between two points over a duration with per-frame deltas, so ScrollRect inertia works. |
long_press | Press, hold (default 800 ms) and release without triggering a click. |
input_text | Type into a UGUI InputField or TMP field, firing the change events. |
set_component | Reflection-based write of any component field. |
set_active | Toggle a GameObject's active state. |
set_time_scale | Set Time.timeScale — slow motion or freeze for inspection. |
send_key | Soft-dispatch UGUI submit and cancel events (hardware keys cannot be injected in a running player). |
prefs | Write and delete PlayerPrefs. |
| Task | What it does |
|---|---|
echo / ping | Round-trip checks that the path to your player is alive. |
get_stats | Connection and runtime statistics for a quick health read. |
read_logs only sees entries from the moment Start() attached the buffer — call it early in boot.send_key dispatches UGUI submit/cancel events instead; keys like Escape or Android back cannot be injected into a running player.get_perf reports memory, GC, fps percentiles, FrameTiming and battery, but not draw-call counts.scene_traverse stops at 3000 nodes and find_objects at 20 000 scanned nodes; hitting a cap is reported as truncated.Task.Run inside a task handler — the SDK itself is fully event-driven on the main thread.