Skip to content

AI Code Mode extension for Unity featuring UTCP Server with MCP wrapper

License

Notifications You must be signed in to change notification settings

RomaRogov/unity-code-mode

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

11 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Code Mode for Unity Editor

Code Mode for Unity turns the Unity Editor into an AI-controllable tool. It runs an HTTP server inside the editor that exposes scene manipulation, asset management, and property inspection as structured tool calls via UTCP Protocol - letting AI agents build, inspect, and modify Unity projects the same way a developer would through the UI. These tools are combined in UTCP Code Mode environment to achieve maximum performance and token efficiency for AI agents, letting them call the tools in isolated JS sandbox.

Quickstart

  1. Install extension in the Unity project
  2. Integrate extension with CodeMode MCP Server
  3. Design a system prompt for you agent or use provided example
  4. Ask AI to help you and see how it learns!

What is Code Mode?

In contrast to rigid MCP tool defenitions, which always kept in LLM context, CodeMode is an approach which helps AI to call tools in the most familiar way - by writing JavaScript code based on TypeScript defenitions of tools. This helps AI to keep token consumption low, implement loops and chained calls for complex tasks, organize output in compact form and reuse output from different existing servers and endpoints in one JavaScript execution context, isolating LLM context from unnecessary data. This opens endless possibilities for interaction between different environments. Here is some examples:

  1. Move scene from blender with Blender MCP, exporting particular objects as FBX straight into Unity project
  2. Use Figma MCP to fetch UI layout from figma and implement these layouts in your project in the smart way instead of blindly recreating every panel
  3. Use Cocos Code Mode to perform game porting between engines
  4. Bring your own examples πŸ™ƒ

All this becomes possible with community-friendly, flexible and open solution from UTCP team: CodeMode and it's MCP Server. You can read more about Code Mode concept in papers from Anthropic, Apple and Cloudflare.

Tools

Tools <> UI Mapping

Category Tools Purpose
Scene GameObjectGetTree, GameObjectGetAtPath, GameObjectCreate, GameObjectCreatePrimitive, GameObjectOperate Navigate and build scene hierarchy
Components GameObjectComponentsGet, GameObjectComponentAdd, GameObjectComponentRemove, GameObjectGetAvailableComponentTypes Attach, remove, and discover components
Inspector InspectorGetInstanceDefinition, InspectorGetInstanceProperties, InspectorSetInstanceProperties Introspect types and read/write properties
Assets AssetGetTree, AssetGetAtPath, AssetCreate, AssetImport, AssetOperate, AssetGetPreview Browse, create, and manage project assets
Editor EditorOperate, EditorGetLogs, EditorGetScenePreview Control editor state and capture previews
Settings SettingsGetDefinition, SettingsGetProperties, SettingsSetProperties Read and modify project settings

How It Works

This extension architecture follows a discover, then act pattern. AI agents never guess at property names or component structures β€” they query for the real definitions first.

1. Get the scene tree         β†’  find the object you need
2. Get its type definition    β†’  learn its actual properties
3. Set properties by name     β†’  make precise changes

Example

// Find the camera
const tree = UnityEditor.GameObjectGetTree({});
const cameraTransform = tree.children[0].components[0]; // Transform ref

// Discover what properties Transform has
const def = UnityEditor.InspectorGetInstanceDefinition({ reference: cameraTransform });
// β†’ "export class Transform { localPosition: Vector3; localRotation: Vector3; localScale: Vector3; }"

// Set multiple properties in one call
UnityEditor.InspectorSetInstanceProperties({
  reference: cameraTransform,
  propertyPaths: ["localPosition", "localRotation"],
  values: [{ x: 0, y: 5, z: -10 }, { x: 30, y: 0, z: 0 }]
});

Technical implementation details

Tool Execution

HTTP requests arrive on a background thread. All tool execution is marshaled to Unity's main thread via an EditorApplication.update queue.

  • Fire-and-forget tools (void / UniTask return) β€” enqueued and return { success: true } immediately. The caller doesn't wait.
  • Value-returning tools (T / UniTask<T> return) β€” enqueued with a completion source. The HTTP response waits until the tool finishes on the main thread.

This means chained calls from AI agents don't block on side-effect-only operations like property changes or editor commands.

Tool Declarations

Tools are plain static methods marked with [UtcpTool]. The ToolRegistry finds them at startup via Unity's TypeCache, generates JSON schemas from their C# signatures, and serves a UTCP manual at /utcp endpoint.

[UtcpTool("Get the hierarchy tree of a GameObject", httpMethod: "GET",
    tags: new[] { "scene", "hierarchy", "tree" })]
public static SceneTreeItem GameObjectGetTree(InstanceReference<GameObject> reference)
{
    // ...
}

Two input modes:

  • Parameter-based β€” each method parameter becomes an input field
  • Class-based β€” a single UtcpInput-derived class for complex inputs

At the moment tool output always should have class type or void, may be also UniTask or UniTask<T> for async operations.

Instance References

Objects are passed around as lightweight handles:

{ id: "29880", type: "Camera" }

Returned by tree queries, component lookups, and creation tools. They are resolved to Unity objects when passed back, usually with InstanceReference.Instance getter or with EditorUtility.InstanceIDToObject(id).

Custom AI Agent Editors

For components where the raw SerializedProperty layout doesn't map cleanly to what an AI agent should see (RectTransform, Camera, AnimatorController, etc.), Code Mode provides the AiAgentEditor system.

Each editor declares:

  • OnEnable β€” bind serialized properties and register handlers
  • OnDumpRequested β€” emit a clean JSON snapshot of current values
  • OnDefinitionRequested β€” emit a TypeScript class definition

Editors support inheritance. For example, ColliderAgentEditor (base) handles common collider properties like isTrigger or physic material; BoxColliderAgentEditor extend it with type-specific properties:

[CustomAiAgentEditor(typeof(BoxCollider))]
public class BoxColliderAgentEditor : ColliderAgentEditor
{
    private SerializedProperty m_Center;
    private SerializedProperty m_Size;

    protected override void OnEnable()
    {
        base.OnEnable();
        m_Center = serializedObject.FindProperty("m_Center");
        m_Size = serializedObject.FindProperty("m_Size");

        AddSettingPropertyHandler("center",
            () => m_Center.vector3Value.SerializeToJObject(),
            v => m_Center.vector3Value = v.DeserializeToVector3());

        AddSettingPropertyHandler("size",
            () => m_Size.vector3Value.SerializeToJObject(),
            v => m_Size.vector3Value = v.DeserializeToVector3());
    }

    protected override void OnDumpRequested()
    {
        base.OnDumpRequested();
        DumpProperty("center", m_Center.vector3Value.SerializeToJObject());
        DumpProperty("size", m_Size.vector3Value.SerializeToJObject());
    }

    protected override void OnDefinitionRequested()
    {
        base.OnDefinitionRequested();
        EmitClassDefinition("BoxCollider", new List<TsPropertyDef>
        {
            TsPropertyDef.Field("center", "Vector3"),
            TsPropertyDef.Field("size", "Vector3"),
        }, "Collider");
    }
}

Components without a custom editor fall back to automatic serialization from SerializedObject.

Installation

  1. Open Package Manager β†’ + β†’ Add package from git URL
  2. Enter: https://github.com/romarogov/unity-code-mode.git?path=Packages/com.roro.codemode

Adding Custom Tools

using CodeMode.Editor.Tools.Attributes;

public static class MyTools
{
    [UtcpTool("Describe what this tool does", httpMethod: "POST")]
    public static MyResult DoSomething(string input, int count = 10)
    {
        // Implementation β€” runs on main thread
    }
}

Tools are discovered automatically at startup. No registration needed.

UTCP Call Templates Configuration

This extension also have a special configuration utility for UTCP call templates, which can be used to connect different UTCP tools (including MCP servers!) into one Code Mode execution context. It is accessible from Code Mode β†’ UTCP Templates menu.

You can find Call Template structures in UTCP documentation:

Integration

Code Mode works with any UTCP-compatible client, including the Code Mode MCP server for AI assistants.

MCP Server Config

This extension provides example of integration config for UTCP Code Mode MCP server with prefilled path to config in Preferences β†’ Code Mode page:

{
  "mcpServers": {
    "code-mode": {
      "command": "npx",
      "args": ["@utcp/code-mode-mcp"],
      "env": {
        "UTCP_CONFIG_FILE": "/path/to/.utcp_config.json"
      }
    }
  }
}

Claude Code Configuration

To setup a Claude Code agent to use Code Mode, open your project and run following command:

Linux/MacOS:

claude mcp add --transport stdio --env UTCP_CONFIG_FILE="/path/to/.utcp_config.json" -- code-mode npx @utcp/code-mode-mcp

Windows:

claude mcp add --transport stdio --env UTCP_CONFIG_FILE="/path/to/.utcp_config.json" -- code-mode cmd /c npx @utcp/code-mode-mcp

About

AI Code Mode extension for Unity featuring UTCP Server with MCP wrapper

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages