TL;DR: Vibe-code your game development remotely from anywhere! 🌍
한줄요약: 이제 집밖에서도 원격으로 바이브코딩으로 게임 개발 가능합니다! 🎮
Connect Unity to OpenClaw AI assistant via HTTP. Works in Editor mode without hitting Play!
This software is in beta. Use at your own risk.
- Always backup your project before using
- Test in a separate project first
- The authors are not responsible for any data loss or project corruption
See LICENSE for full terms.
This plugin supports two connection modes - use whichever fits your workflow:
Telegram/Discord/Web → OpenClaw Gateway → Unity Plugin
- ✅ Remote access from anywhere
- ✅ Chat integration (Telegram, Discord, etc.)
- ✅ Cron jobs, automation, multi-device
⚠️ Requires OpenClaw Gateway running
Claude Code/Desktop → MCP Server → Unity Plugin
- ✅ Direct connection, no middleware
- ✅ Works with Claude Code, Cursor, etc.
- ✅ Lower latency for local development
⚠️ Local only (127.0.0.1)
| Mode | Setup |
|---|---|
| OpenClaw | Just install plugin, Gateway handles connection |
| MCP | Enable MCP Bridge: Window > OpenClaw > Start MCP Bridge |
📖 Setup Guide | 셋업 가이드
- 🎮 Works in Editor & Play Mode - No need to hit Play to use AI tools
- 🔌 Auto-Connect - Connects when Unity starts, maintains connection across mode changes
- 📋 Console Integration - Capture and query Unity logs for debugging
- 🎬 Scene Management - List, load, and inspect scenes
- 🔧 Component Editing - Add, remove, and modify component properties
- 📸 Debug Tools - Screenshots, hierarchy view, and more
- 🎯 Input Simulation - Keyboard, mouse, and UI interaction for game testing
- 🔄 Editor Control - Trigger recompilation and asset refresh remotely
- 🔒 Security Controls - Configure what operations are allowed
| Component | Version |
|---|---|
| Unity | 2021.3+ |
| OpenClaw | 2026.2.3+ |
⚠️ Tested on Unity 6000.3 (Unity 6.3 LTS) only.While designed for Unity 2021.3+, this plugin has only been tested on Unity 6000.3.7f1 (Unity 6.3 LTS). If you encounter issues on other Unity versions, please:
- 🐛 Open an Issue with your Unity version and error details
- 🔧 Submit a Pull Request if you have a fix
Your contributions help make this plugin work across all Unity versions!
- Open Unity Package Manager (
Window > Package Manager) - Click
+→Add package from git URL... - Enter:
https://github.com/TomLeeLive/openclaw-unity-plugin.git
- Clone this repository
- In Unity:
Window > Package Manager→+→Add package from disk... - Select the
package.jsonfile
Copy the gateway extension files to OpenClaw:
# Copy extension files
cp -r OpenClawPlugin~/* ~/.openclaw/extensions/unity/
# Restart gateway to load the extension
openclaw gateway restart
# Verify
openclaw unity statusNote:
OpenClawPlugin~contains the gateway extension that enablesunity_executeandunity_sessionstools. This is required for OpenClaw to communicate with Unity.
See Installation above for Git URL or local package setup.
- Open
Window > OpenClaw Plugin - Set Gateway URL:
http://localhost:18789(default) - Connection is automatic when Unity starts
- Status shows green when connected
Ask OpenClaw to inspect your scene, create objects, or debug issues - all without entering Play mode!
The companion skill provides workflow patterns and tool references for the AI:
# Clone skill to OpenClaw workspace
git clone https://github.com/TomLeeLive/openclaw-unity-skill.git ~/.openclaw/workspace/skills/unity-pluginThe skill provides:
- Quick reference for all 55 tools
- Common workflow patterns (scene inspection, UI testing, etc.)
- Detailed parameter documentation
- Troubleshooting guides
Note: The skill is separate from the gateway extension. The extension enables the tools; the skill teaches the AI how to use them effectively.
- Development Guide - Architecture, extending tools, and contribution guidelines
- Testing Guide - Complete testing guide with examples
| Tool | Description |
|---|---|
console.getLogs |
Get Unity console logs (with type filter) |
console.getErrors |
Get error/exception logs (with optional warnings) |
console.clear |
Clear captured logs |
| Tool | Description |
|---|---|
scene.list |
List all scenes in build settings |
scene.getActive |
Get active scene info |
scene.getData |
Get scene hierarchy data |
scene.load |
Load a scene by name (Play mode) |
scene.open |
Open a scene in Editor mode |
scene.save |
Save active scene (Editor mode) |
scene.saveAll |
Save all open scenes (Editor mode) |
| Tool | Description |
|---|---|
gameobject.find |
Find by name, tag, or component type |
gameobject.getAll |
Get all GameObjects with filtering |
gameobject.create |
Create GameObject or primitive |
gameobject.destroy |
Destroy a GameObject |
gameobject.delete |
Delete a GameObject (alias for destroy) |
gameobject.getData |
Get detailed object data |
gameobject.setActive |
Enable/disable object |
gameobject.setParent |
Change parent |
| Tool | Description |
|---|---|
transform.getPosition |
Get world position (x, y, z) |
transform.getRotation |
Get rotation in Euler angles |
transform.getScale |
Get local scale |
transform.setPosition |
Set world position |
transform.setRotation |
Set rotation (Euler) |
transform.setScale |
Set local scale |
| Tool | Description |
|---|---|
component.add |
Add component to object |
component.remove |
Remove component |
component.get |
Get component data |
component.set |
Set field/property value |
component.list |
List available types |
| Tool | Description |
|---|---|
script.execute |
Execute code/methods (Debug.Log, Time.timeScale, PlayerPrefs, reflection calls) |
script.read |
Read script file contents |
script.list |
List script files in project |
| Tool | Description |
|---|---|
app.getState |
Get play mode, FPS, etc. |
app.play |
Enter play mode (Editor) |
app.pause |
Toggle pause (Editor) |
app.stop |
Exit play mode (Editor) |
| Tool | Description |
|---|---|
debug.log |
Write to console |
debug.screenshot |
Capture screenshot (with UI) |
debug.hierarchy |
Text hierarchy view |
| Tool | Description |
|---|---|
editor.refresh |
Refresh AssetDatabase (triggers recompile) |
editor.recompile |
Request script recompilation |
editor.domainReload |
Force domain reload (reinitializes static fields) |
editor.focusWindow |
Focus Editor window (game/scene/console/hierarchy/project/inspector) |
editor.listWindows |
List all open Editor windows |
| Tool | Description |
|---|---|
input.keyPress |
Press and release a key |
input.keyDown |
Press and hold a key |
input.keyUp |
Release a key |
input.type |
Type text into input field |
input.mouseMove |
Move mouse cursor |
input.mouseClick |
Click at position |
input.mouseDrag |
Drag from A to B |
input.mouseScroll |
Scroll wheel |
input.getMousePosition |
Get current cursor position |
input.clickUI |
Click UI element by name |
⚠️ Input Simulation Limitation: Keyboard/mouse simulation works for UI interactions (Button clicks, InputField typing) but NOT for gameplay input usingInput.GetKey()or legacy Input Manager. This is a Unity limitation -Input.GetKey()reads directly from the OS input buffer. For automated gameplay testing, usetransform.setPositionto move objects directly, or migrate to Unity's new Input System which supports programmatic input injection.
| Tool | Description |
|---|---|
material.create |
Create material with shader, color, metallic, smoothness |
material.assign |
Assign material to GameObject |
material.modify |
Modify material properties (color, metallic, emission, etc.) |
material.getInfo |
Get detailed material info with all shader properties |
material.list |
List materials in project with filtering |
| Tool | Description |
|---|---|
prefab.create |
Create prefab from scene GameObject |
prefab.instantiate |
Instantiate prefab in scene with position |
prefab.open |
Open prefab for editing |
prefab.close |
Close prefab editing mode |
prefab.save |
Save currently edited prefab |
| Tool | Description |
|---|---|
asset.find |
Search assets by query, type, folder |
asset.copy |
Copy asset to new path |
asset.move |
Move/rename asset |
asset.delete |
Delete asset (with trash option) |
asset.refresh |
Refresh AssetDatabase |
asset.import |
Import/reimport specific asset |
asset.getPath |
Get asset path by name |
| Tool | Description |
|---|---|
package.add |
Install package by name or git URL |
package.remove |
Remove installed package |
package.list |
List installed packages |
package.search |
Search Unity package registry |
| Tool | Description |
|---|---|
test.run |
Run EditMode/PlayMode tests with filtering |
test.list |
List available tests |
test.getResults |
Get last test run results |
| Tool | Description |
|---|---|
batch.execute |
Execute multiple tools in one call (10-100x performance) |
Example:
{
"commands": [
{ "tool": "scene.getActive", "params": {} },
{ "tool": "gameobject.find", "params": { "name": "Player" } },
{ "tool": "debug.screenshot", "params": {} }
],
"stopOnError": false
}| Tool | Description |
|---|---|
session.getInfo |
Get session info (project, processId, machineNa) for multi-instance support |
| Tool | Description |
|---|---|
scriptableobject.create |
Create new ScriptableObject asset |
scriptableobject.load |
Load and inspect ScriptableObject fields |
scriptableobject.save |
Save ScriptableObject changes |
scriptableobject.getField |
Get specific field value |
scriptableobject.setField |
Set field value with auto-save |
scriptableobject.list |
List ScriptableObjects in project |
| Tool | Description |
|---|---|
shader.list |
List shaders in project |
shader.getInfo |
Get shader properties and info |
shader.getKeywords |
Get shader keywords |
| Tool | Description |
|---|---|
texture.create |
Create new texture with color fill |
texture.getInfo |
Get texture info (size, format, import settings) |
texture.setPixels |
Fill region with color |
texture.resize |
Resize texture via import settings |
texture.list |
List textures in project |
┌─────────────────────────────────────────────────────────────┐
│ Unity Editor │
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ OpenClawEditorBridge │ │
│ │ [InitializeOnLoad] │ │
│ │ │ │
│ │ • EditorApplication.delayCall → safe init │ │
│ │ • EditorApplication.update → connection polling │ │
│ │ • SessionState → survives Play mode transitions │ │
│ └──────────────────────┬─────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ OpenClawConnectionManager │ │
│ │ (Singleton - shared across modes) │ │
│ │ │ │
│ │ • HTTP polling for commands │ │
│ │ • Main thread execution queue │ │
│ │ • Automatic reconnection │ │
│ │ • JSON parsing with nested object support │ │
│ └──────────────────────┬─────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ OpenClawTools (~80 tools) │ │
│ │ │ │
│ │ • Scene/GameObject/Component manipulation │ │
│ │ • Debug tools (screenshot, hierarchy) │ │
│ │ • Input simulation (keyboard, mouse, UI) │ │
│ │ • Editor control (recompile, refresh) │ │
│ └────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
│
│ HTTP
▼
┌──────────────────────────────────────────────────────────────┐
│ OpenClaw Gateway │
│ http://localhost:18789 │
│ │
│ Endpoints: │
│ • POST /unity/register - Register Unity session │
│ • POST /unity/heartbeat - Keep session alive │
│ • GET /unity/poll - Poll for commands │
│ • POST /unity/result - Send tool execution results │
└──────────────────────────────────────────────────────────────┘
Create via Assets > Create > OpenClaw > Config and place in Resources folder.
| Setting | Description | Default |
|---|---|---|
gatewayUrl |
OpenClaw gateway URL | http://localhost:18789 |
apiToken |
Optional API token | (empty) |
autoConnect |
Connect on start | true |
showStatusOverlay |
Show status in Game view | true |
captureConsoleLogs |
Capture logs for AI | true |
allowCodeExecution |
Allow code execution | true |
allowFileAccess |
Allow file operations | true |
allowSceneModification |
Allow scene changes | true |
You: What GameObjects are in my scene?
OpenClaw: [Executes debug.hierarchy]
Your scene has:
▶ Main Camera [Camera, AudioListener]
▶ Directional Light [Light]
▶ Player [PlayerController, Rigidbody]
▶ Model [MeshRenderer]
▶ UI Canvas [Canvas, GraphicRaycaster]
▶ PlayButton [Button]
You: Test the login flow - enter username "TestPlayer" and click Play
OpenClaw:
[Executes input.clickUI {name: "UsernameInput"}]
[Executes input.type {text: "TestPlayer"}]
[Executes input.clickUI {name: "PlayButton"}]
[Executes debug.screenshot]
Done! Clicked username input, typed "TestPlayer", and clicked Play button.
Screenshot attached showing the result.
You: I updated the PlayerController script, recompile Unity
OpenClaw: [Executes editor.recompile]
Script recompilation requested. Unity will reload shortly.
- Check Gateway status:
openclaw gateway status - Verify URL: default is
http://localhost:18789 - Check
Window > OpenClaw Pluginfor errors
- Plugin uses
SessionStateto survive domain reloads - Auto-reconnects after Play mode transition
- If stuck, use
editor.refreshor click "Force Reconnect"
- In Play mode: Uses
ScreenCapture(includes UI) - In Editor mode: Uses
Camera.main.Render()(no overlay UI) - Use Play mode for accurate game screenshots
When using debug.screenshot remotely (via SSH, screen sharing, etc.):
| Game View Mode | Screen Lock | Screenshot Works? |
|---|---|---|
| Play Focused | ✅ OK | ✅ Yes |
| Normal | ❌ May fail |
Best Practice: Set Game View to "Play Focused" mode before locking the screen. This ensures Unity keeps rendering the game even when the window isn't visible.
To enable: Click the dropdown next to "Scale" in Game View → Select "Play Focused"
Unity's "Enter Play Mode Settings" can skip domain reload for faster iteration, but this prevents script recompilation.
Symptoms:
- Code changes don't take effect when re-entering Play mode
- Old behavior persists despite saving scripts
editor.refreshoreditor.recompilehas no effect during Play mode
Solution:
- Go to
Edit → Project Settings → Editor - Find "Enter Play Mode Settings"
- Check ✅ "Reload Domain"
What this does:
| Setting | Reload Domain ON | Reload Domain OFF |
|---|---|---|
| Script changes | ✅ Applied on Play | ❌ Ignored until manual refresh |
| Play mode entry | ~2-5 seconds | ~0.5 seconds |
| Static variables | Reset | Preserved |
| Best for | Development with active coding | Testing/playing without code changes |
Tip: Keep "Reload Domain" ON during development. Only disable it when you need fast iteration without code changes.
When publishing to ClawHub or installing as a skill, you can configure disableModelInvocation in the skill metadata:
| Setting | AI Auto-Invoke | User Explicit Request |
|---|---|---|
false (default) |
✅ Allowed | ✅ Allowed |
true |
❌ Blocked | ✅ Allowed |
Reason: During Unity development, it's useful for AI to autonomously perform supporting tasks like checking scene hierarchy, taking screenshots, and inspecting GameObjects.
When to use true: For sensitive tools (payments, deletions, message sending, etc.)
# Example skill metadata
metadata:
openclaw:
disableModelInvocation: true # Recommended for Unity plugin- Development Only: Disable
allowCodeExecutionin production builds - TextMeshPro: Plugin works with or without TMPro (uses reflection)
- Unity 6: Deferred initialization prevents UPM EPIPE crashes
See CHANGELOG.md for version history.
MIT License - See LICENSE
Made with 🦞 by the OpenClaw community