chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,282 @@
|
||||
---
|
||||
name: unity-mcp-orchestrator
|
||||
description: Orchestrate Unity Editor via MCP (Model Context Protocol) tools and resources. Use when working with Unity projects through MCP for Unity - creating/modifying GameObjects, editing scripts, managing scenes, running tests, or any Unity Editor automation. Provides best practices, tool schemas, and workflow patterns for effective Unity-MCP integration.
|
||||
---
|
||||
|
||||
# Unity-MCP Operator Guide
|
||||
|
||||
This skill helps you effectively use the Unity Editor with MCP tools and resources.
|
||||
|
||||
## Template Notice
|
||||
|
||||
Examples in `references/workflows.md` and `references/tools-reference.md` are reusable templates. They may be inaccurate across Unity versions, package setups (UGUI/TMP/Input System), and project-specific conventions. Please check console, compilation errors, or use screenshot after implementation.
|
||||
|
||||
Before applying a template:
|
||||
- Validate targets/components first via resources and `find_gameobjects`.
|
||||
- Treat names, enum values, and property payloads as placeholders to adapt.
|
||||
|
||||
## Quick Start: Resource-First Workflow
|
||||
|
||||
**Always read relevant resources before using tools.** This prevents errors and provides the necessary context.
|
||||
|
||||
```
|
||||
1. Check editor state → mcpforunity://editor/state
|
||||
2. Understand the scene → mcpforunity://scene/gameobject-api
|
||||
3. Find what you need → find_gameobjects or resources
|
||||
4. Take action → tools (manage_gameobject, create_script, script_apply_edits, apply_text_edits, validate_script, delete_script, get_sha, etc.)
|
||||
5. Verify results → read_console, manage_camera(action="screenshot"), resources
|
||||
```
|
||||
|
||||
## Critical Best Practices
|
||||
|
||||
### 1. After Writing/Editing Scripts: Wait for Compilation and Check Console
|
||||
|
||||
```python
|
||||
# After create_script or script_apply_edits:
|
||||
# Both tools already trigger AssetDatabase.ImportAsset + RequestScriptCompilation automatically.
|
||||
# No need to call refresh_unity — just wait for compilation to finish, then check console.
|
||||
|
||||
# 1. Poll editor state until compilation completes
|
||||
# Read mcpforunity://editor/state → wait until is_compiling == false
|
||||
|
||||
# 2. Check for compilation errors
|
||||
read_console(types=["error"], count=10, include_stacktrace=True)
|
||||
```
|
||||
|
||||
**Why:** Unity must compile scripts before they're usable. `create_script` and `script_apply_edits` already trigger import and compilation automatically — calling `refresh_unity` afterward is redundant.
|
||||
|
||||
### 2. Use `batch_execute` for Multiple Operations
|
||||
|
||||
```python
|
||||
# 10-100x faster than sequential calls
|
||||
batch_execute(
|
||||
commands=[
|
||||
{"tool": "manage_gameobject", "params": {"action": "create", "name": "Cube1", "primitive_type": "Cube"}},
|
||||
{"tool": "manage_gameobject", "params": {"action": "create", "name": "Cube2", "primitive_type": "Cube"}},
|
||||
{"tool": "manage_gameobject", "params": {"action": "create", "name": "Cube3", "primitive_type": "Cube"}}
|
||||
],
|
||||
parallel=True # Hint only: Unity may still execute sequentially
|
||||
)
|
||||
```
|
||||
|
||||
**Max 25 commands per batch by default (configurable in Unity MCP Tools window, max 100).** Use `fail_fast=True` for dependent operations.
|
||||
|
||||
**Tip:** Also use `batch_execute` for discovery — batch multiple `find_gameobjects` calls instead of calling them one at a time:
|
||||
```python
|
||||
batch_execute(commands=[
|
||||
{"tool": "find_gameobjects", "params": {"search_term": "Camera", "search_method": "by_component"}},
|
||||
{"tool": "find_gameobjects", "params": {"search_term": "Player", "search_method": "by_tag"}},
|
||||
{"tool": "find_gameobjects", "params": {"search_term": "GameManager", "search_method": "by_name"}}
|
||||
])
|
||||
```
|
||||
|
||||
### 3. Use Screenshots to Verify Visual Results
|
||||
|
||||
```python
|
||||
# Basic screenshot (saves to Assets/, returns file path only)
|
||||
manage_camera(action="screenshot")
|
||||
|
||||
# Inline screenshot (returns base64 PNG directly to the AI)
|
||||
manage_camera(action="screenshot", include_image=True)
|
||||
|
||||
# Use a specific camera and cap resolution for smaller payloads
|
||||
manage_camera(action="screenshot", camera="MainCamera", include_image=True, max_resolution=512)
|
||||
|
||||
# Batch surround: captures front/back/left/right/top/bird_eye around the scene
|
||||
manage_camera(action="screenshot", batch="surround", max_resolution=256)
|
||||
|
||||
# Batch surround centered on a specific object
|
||||
manage_camera(action="screenshot", batch="surround", view_target="Player", max_resolution=256)
|
||||
|
||||
# Positioned screenshot: place a temp camera and capture in one call
|
||||
manage_camera(action="screenshot", view_target="Player", view_position=[0, 10, -10], max_resolution=512)
|
||||
|
||||
# Scene View screenshot: capture what the developer sees in the editor
|
||||
manage_camera(action="screenshot", capture_source="scene_view", include_image=True)
|
||||
|
||||
# Scene View framed on a specific object
|
||||
manage_camera(action="screenshot", capture_source="scene_view", view_target="Canvas", include_image=True)
|
||||
```
|
||||
|
||||
**Best practices for AI scene understanding:**
|
||||
- Use `include_image=True` when you need to *see* the scene, not just save a file.
|
||||
- Use `batch="surround"` for a comprehensive overview (6 angles, one command).
|
||||
- Use `view_target`/`view_position` to capture from a specific viewpoint without needing a scene camera.
|
||||
- Use `capture_source="scene_view"` to see the editor viewport (gizmos, wireframes, grid).
|
||||
- Keep `max_resolution` at 256–512 to balance quality vs. token cost.
|
||||
|
||||
```python
|
||||
# Agentic camera loop: point, shoot, analyze
|
||||
manage_gameobject(action="look_at", target="MainCamera", look_at_target="Player")
|
||||
manage_camera(action="screenshot", camera="MainCamera", include_image=True, max_resolution=512)
|
||||
# → Analyze image, decide next action
|
||||
|
||||
# Multi-view screenshot (6-angle contact sheet)
|
||||
manage_camera(action="screenshot_multiview", max_resolution=480)
|
||||
|
||||
# Scene View for editor-level inspection (shows gizmos, debug overlays, etc.)
|
||||
manage_camera(action="screenshot", capture_source="scene_view", view_target="Player", include_image=True)
|
||||
```
|
||||
|
||||
### 4. Check Console After Major Changes
|
||||
|
||||
```python
|
||||
read_console(
|
||||
action="get",
|
||||
types=["error", "warning"], # Focus on problems
|
||||
count=10,
|
||||
format="detailed"
|
||||
)
|
||||
```
|
||||
|
||||
### 5. Always Check `editor_state` Before Complex Operations
|
||||
|
||||
```python
|
||||
# Read mcpforunity://editor/state to check:
|
||||
# - is_compiling: Wait if true
|
||||
# - is_domain_reload_pending: Wait if true
|
||||
# - ready_for_tools: Only proceed if true
|
||||
# - blocking_reasons: Why tools might fail
|
||||
```
|
||||
|
||||
## Parameter Type Conventions
|
||||
|
||||
These are common patterns, not strict guarantees. `manage_components.set_property` payload shapes can vary by component/property; if a template fails, inspect the component resource payload and adjust.
|
||||
|
||||
### Vectors (position, rotation, scale, color)
|
||||
```python
|
||||
# Both forms accepted:
|
||||
position=[1.0, 2.0, 3.0] # List
|
||||
position="[1.0, 2.0, 3.0]" # JSON string
|
||||
```
|
||||
|
||||
### Booleans
|
||||
```python
|
||||
# Both forms accepted:
|
||||
include_inactive=True # Boolean
|
||||
include_inactive="true" # String
|
||||
```
|
||||
|
||||
### Colors
|
||||
```python
|
||||
# Auto-detected format:
|
||||
color=[255, 0, 0, 255] # 0-255 range
|
||||
color=[1.0, 0.0, 0.0, 1.0] # 0.0-1.0 normalized (auto-converted)
|
||||
```
|
||||
|
||||
### Paths
|
||||
```python
|
||||
# Assets-relative (default):
|
||||
path="Assets/Scripts/MyScript.cs"
|
||||
|
||||
# URI forms:
|
||||
uri="mcpforunity://path/Assets/Scripts/MyScript.cs"
|
||||
uri="file:///full/path/to/file.cs"
|
||||
```
|
||||
|
||||
## Core Tool Categories
|
||||
|
||||
| Category | Key Tools | Use For |
|
||||
|----------|-----------|---------|
|
||||
| **Scene** | `manage_scene`, `find_gameobjects` | Scene operations, finding objects |
|
||||
| **Objects** | `manage_gameobject`, `manage_components` | Creating/modifying GameObjects |
|
||||
| **Scripts** | `create_script`, `script_apply_edits`, `validate_script` | C# code management (auto-refreshes on create/edit) |
|
||||
| **Assets** | `manage_asset`, `manage_prefabs` | Asset operations. **Prefab instantiation** is done via `manage_gameobject(action="create", prefab_path="...")`, not `manage_prefabs`. |
|
||||
| **Editor** | `manage_editor`, `execute_menu_item`, `read_console` | Editor control, package deployment (`deploy_package`/`restore_package` actions) |
|
||||
| **Testing** | `run_tests`, `get_test_job` | Unity Test Framework |
|
||||
| **Batch** | `batch_execute` | Parallel/bulk operations |
|
||||
| **Camera** | `manage_camera` | Camera management (Unity Camera + Cinemachine). **Tier 1** (always available): create, target, lens, priority, list, screenshot. **Tier 2** (requires `com.unity.cinemachine`): brain, body/aim/noise pipeline, extensions, blending, force/release. 7 presets: follow, third_person, freelook, dolly, static, top_down, side_scroller. Resource: `mcpforunity://scene/cameras`. Use `ping` to check Cinemachine availability. See [tools-reference.md](references/tools-reference.md#camera-tools). |
|
||||
| **Graphics** | `manage_graphics` | Rendering and post-processing management. 33 actions across 5 groups: **Volume** (create/configure volumes and effects, URP/HDRP), **Bake** (lightmaps, light probes, reflection probes, Edit mode only), **Stats** (draw calls, batches, memory), **Pipeline** (quality levels, pipeline settings), **Features** (URP renderer features: add, remove, toggle, reorder). Resources: `mcpforunity://scene/volumes`, `mcpforunity://rendering/stats`, `mcpforunity://pipeline/renderer-features`. Use `ping` to check pipeline status. See [tools-reference.md](references/tools-reference.md#graphics-tools). |
|
||||
| **Packages** | `manage_packages` | Install, remove, search, and manage Unity packages and scoped registries. Query actions: list installed, search registry, get info, ping, poll status. Mutating actions: add/remove packages, embed for editing, add/remove scoped registries, force resolve. Validates identifiers, warns on git URLs, checks dependents before removal (`force=true` to override). See [tools-reference.md](references/tools-reference.md#package-tools). |
|
||||
| **Physics** | `manage_physics` | Manage 3D and 2D physics (21 actions). Settings, collision matrix, materials, joints (14 types). Queries: `raycast`, `raycast_all`, `linecast`, `shapecast` (sphere/box/capsule sweep), `overlap`. Forces: `apply_force` (AddForce/AddTorque/AddExplosionForce with ForceMode). Rigidbody: `get_rigidbody`, `configure_rigidbody` (mass, drag, gravity, constraints, collision detection). Validation: scene-wide checks. Simulation: `simulate_step` in edit mode. See [tools-reference.md](references/tools-reference.md#physics-tools). |
|
||||
| **ProBuilder** | `manage_probuilder` | 3D modeling, mesh editing, complex geometry. **When `com.unity.probuilder` is installed, prefer ProBuilder shapes over primitive GameObjects** for editable geometry, multi-material faces, or complex shapes. Supports 12 shape types, face/edge/vertex editing, smoothing, and per-face materials. See [ProBuilder Guide](references/probuilder-guide.md). |
|
||||
| **UI** | `manage_ui`, `batch_execute` with `manage_gameobject` + `manage_components` | **UI Toolkit**: Use `manage_ui` to create UXML/USS files, attach UIDocument, inspect visual trees. **uGUI (Canvas)**: Use `batch_execute` for Canvas, Panel, Button, Text, Slider, Toggle, Input Field. **Read `mcpforunity://project/info` first** to detect uGUI/TMP/Input System/UI Toolkit availability. (see [UI workflows](references/workflows.md#ui-creation-workflows)) |
|
||||
| **Docs** | `unity_reflect`, `unity_docs` | API verification and documentation lookup. **`unity_reflect`** inspects live C# APIs via reflection (requires Unity connection): `search` types across assemblies, `get_type` for member summary, `get_member` for full signatures. **`unity_docs`** fetches official docs from docs.unity3d.com (no Unity connection needed): `get_doc` (ScriptReference), `get_manual` (Manual pages), `get_package_doc` (package docs), `lookup` (parallel search all sources + project assets). **Trust hierarchy: reflection > project assets > docs.** Workflow: `unity_reflect` search -> get_type -> get_member -> `unity_docs` lookup. See [tools-reference.md](references/tools-reference.md#docs-tools). |
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Creating a New Script and Using It
|
||||
|
||||
```python
|
||||
# 1. Create the script (automatically triggers import + compilation)
|
||||
create_script(
|
||||
path="Assets/Scripts/PlayerController.cs",
|
||||
contents="using UnityEngine;\n\npublic class PlayerController : MonoBehaviour\n{\n void Update() { }\n}"
|
||||
)
|
||||
|
||||
# 2. Wait for compilation to finish
|
||||
# Read mcpforunity://editor/state → wait until is_compiling == false
|
||||
|
||||
# 3. Check for compilation errors
|
||||
read_console(types=["error"], count=10)
|
||||
|
||||
# 4. Only then attach to GameObject
|
||||
manage_gameobject(action="modify", target="Player", components_to_add=["PlayerController"])
|
||||
```
|
||||
|
||||
### Finding and Modifying GameObjects
|
||||
|
||||
```python
|
||||
# 1. Find by name/tag/component (returns IDs only)
|
||||
result = find_gameobjects(search_term="Enemy", search_method="by_tag", page_size=50)
|
||||
|
||||
# 2. Get full data via resource
|
||||
# mcpforunity://scene/gameobject/{instance_id}
|
||||
|
||||
# 3. Modify using the ID
|
||||
manage_gameobject(action="modify", target=instance_id, position=[10, 0, 0])
|
||||
```
|
||||
|
||||
### Running and Monitoring Tests
|
||||
|
||||
```python
|
||||
# 1. Start test run (async)
|
||||
result = run_tests(mode="EditMode", test_names=["MyTests.TestSomething"])
|
||||
job_id = result["job_id"]
|
||||
|
||||
# 2. Poll for completion
|
||||
result = get_test_job(job_id=job_id, wait_timeout=60, include_failed_tests=True)
|
||||
```
|
||||
|
||||
## Pagination Pattern
|
||||
|
||||
Large queries return paginated results. Always follow `next_cursor`:
|
||||
|
||||
```python
|
||||
cursor = 0
|
||||
all_items = []
|
||||
while True:
|
||||
result = manage_scene(action="get_hierarchy", page_size=50, cursor=cursor)
|
||||
all_items.extend(result["data"]["items"])
|
||||
if not result["data"].get("next_cursor"):
|
||||
break
|
||||
cursor = result["data"]["next_cursor"]
|
||||
```
|
||||
|
||||
## Multi-Instance Workflow
|
||||
|
||||
When multiple Unity Editors are running:
|
||||
|
||||
```python
|
||||
# 1. List instances via resource: mcpforunity://instances
|
||||
# 2. Set active instance
|
||||
set_active_instance(instance="MyProject@abc123")
|
||||
# 3. All subsequent calls route to that instance
|
||||
```
|
||||
|
||||
## Error Recovery
|
||||
|
||||
| Symptom | Cause | Solution |
|
||||
|---------|-------|----------|
|
||||
| Tools return "busy" | Compilation in progress | Wait, check `editor_state` |
|
||||
| "stale_file" error | File changed since SHA | Re-fetch SHA with `get_sha`, retry |
|
||||
| Connection lost | Domain reload | Wait ~5s, reconnect |
|
||||
| Commands fail silently | Wrong instance | Check `set_active_instance` |
|
||||
|
||||
## Reference Files
|
||||
|
||||
For detailed schemas and examples:
|
||||
|
||||
- **[tools-reference.md](references/tools-reference.md)**: Complete tool documentation with all parameters
|
||||
- **[resources-reference.md](references/resources-reference.md)**: All available resources and their data
|
||||
- **[workflows.md](references/workflows.md)**: Extended workflow examples and patterns
|
||||
@@ -0,0 +1,444 @@
|
||||
# ProBuilder Workflow Guide
|
||||
|
||||
Patterns and best practices for AI-driven ProBuilder mesh editing through MCP for Unity.
|
||||
|
||||
## Availability
|
||||
|
||||
ProBuilder is an **optional** Unity package (`com.unity.probuilder`). Check `mcpforunity://project/info` or call `manage_probuilder(action="ping")` to verify it's installed before using any ProBuilder tools. If available, **prefer ProBuilder over primitive GameObjects** for any geometry that needs editing, multi-material faces, or non-trivial shapes.
|
||||
|
||||
## Core Workflow: Always Get Info First
|
||||
|
||||
Before any mesh edit, call `get_mesh_info` with `include='faces'` to understand the geometry:
|
||||
|
||||
```python
|
||||
# Step 1: Get face info with directions
|
||||
result = manage_probuilder(action="get_mesh_info", target="MyCube",
|
||||
properties={"include": "faces"})
|
||||
|
||||
# Response includes per-face:
|
||||
# index: 0, normal: [0, 1, 0], center: [0, 0.5, 0], direction: "top"
|
||||
# index: 1, normal: [0, -1, 0], center: [0, -0.5, 0], direction: "bottom"
|
||||
# index: 2, normal: [0, 0, 1], center: [0, 0, 0.5], direction: "front"
|
||||
# ...
|
||||
|
||||
# Step 2: Use the direction labels to pick faces
|
||||
# Want to extrude the top? Find the face with direction="top"
|
||||
manage_probuilder(action="extrude_faces", target="MyCube",
|
||||
properties={"faceIndices": [0], "distance": 1.5})
|
||||
```
|
||||
|
||||
### Include Parameter
|
||||
|
||||
| Value | Returns | Use When |
|
||||
|-------|---------|----------|
|
||||
| `"summary"` | Counts, bounds, materials | Quick check / validation |
|
||||
| `"faces"` | + normals, centers, directions | Selecting faces for editing |
|
||||
| `"edges"` | + edge vertex pairs with world positions (max 200) | Edge-based operations |
|
||||
| `"all"` | Everything | Full mesh analysis |
|
||||
|
||||
## Shape Creation
|
||||
|
||||
### All 12 Shape Types
|
||||
|
||||
```python
|
||||
# Basic shapes
|
||||
manage_probuilder(action="create_shape", properties={"shape_type": "Cube", "name": "MyCube"})
|
||||
manage_probuilder(action="create_shape", properties={"shape_type": "Sphere", "name": "MySphere"})
|
||||
manage_probuilder(action="create_shape", properties={"shape_type": "Cylinder", "name": "MyCyl"})
|
||||
manage_probuilder(action="create_shape", properties={"shape_type": "Plane", "name": "MyPlane"})
|
||||
manage_probuilder(action="create_shape", properties={"shape_type": "Cone", "name": "MyCone"})
|
||||
manage_probuilder(action="create_shape", properties={"shape_type": "Prism", "name": "MyPrism"})
|
||||
|
||||
# Parametric shapes
|
||||
manage_probuilder(action="create_shape", properties={
|
||||
"shape_type": "Torus", "name": "MyTorus",
|
||||
"rows": 16, "columns": 24, "innerRadius": 0.5, "outerRadius": 1.0
|
||||
})
|
||||
manage_probuilder(action="create_shape", properties={
|
||||
"shape_type": "Pipe", "name": "MyPipe",
|
||||
"radius": 1.0, "height": 2.0, "thickness": 0.2
|
||||
})
|
||||
manage_probuilder(action="create_shape", properties={
|
||||
"shape_type": "Arch", "name": "MyArch",
|
||||
"radius": 2.0, "angle": 180, "segments": 12
|
||||
})
|
||||
|
||||
# Architectural shapes
|
||||
manage_probuilder(action="create_shape", properties={
|
||||
"shape_type": "Stair", "name": "MyStairs", "steps": 10
|
||||
})
|
||||
manage_probuilder(action="create_shape", properties={
|
||||
"shape_type": "CurvedStair", "name": "Spiral", "steps": 12
|
||||
})
|
||||
manage_probuilder(action="create_shape", properties={
|
||||
"shape_type": "Door", "name": "MyDoor"
|
||||
})
|
||||
|
||||
# Custom polygon
|
||||
manage_probuilder(action="create_poly_shape", properties={
|
||||
"points": [[0,0,0], [5,0,0], [5,0,5], [2.5,0,7], [0,0,5]],
|
||||
"extrudeHeight": 3.0, "name": "Pentagon"
|
||||
})
|
||||
```
|
||||
|
||||
## Common Editing Operations
|
||||
|
||||
### Extrude a Roof
|
||||
|
||||
```python
|
||||
# 1. Create a building base
|
||||
manage_probuilder(action="create_shape", properties={
|
||||
"shape_type": "Cube", "name": "Building", "size": [4, 3, 6]
|
||||
})
|
||||
|
||||
# 2. Find the top face
|
||||
info = manage_probuilder(action="get_mesh_info", target="Building",
|
||||
properties={"include": "faces"})
|
||||
# Find face with direction="top" -> e.g. index 2
|
||||
|
||||
# 3. Extrude upward for a flat roof extension
|
||||
manage_probuilder(action="extrude_faces", target="Building",
|
||||
properties={"faceIndices": [2], "distance": 0.5})
|
||||
```
|
||||
|
||||
### Cut a Hole (Delete Faces)
|
||||
|
||||
```python
|
||||
# 1. Get face info
|
||||
info = manage_probuilder(action="get_mesh_info", target="Wall",
|
||||
properties={"include": "faces"})
|
||||
# Find the face with direction="front" -> e.g. index 4
|
||||
|
||||
# 2. Subdivide to create more faces
|
||||
manage_probuilder(action="subdivide", target="Wall",
|
||||
properties={"faceIndices": [4]})
|
||||
|
||||
# 3. Get updated face info (indices changed after subdivide!)
|
||||
info = manage_probuilder(action="get_mesh_info", target="Wall",
|
||||
properties={"include": "faces"})
|
||||
|
||||
# 4. Delete the center face(s) for the hole
|
||||
manage_probuilder(action="delete_faces", target="Wall",
|
||||
properties={"faceIndices": [6]})
|
||||
```
|
||||
|
||||
### Bevel Edges
|
||||
|
||||
```python
|
||||
# Get edge info
|
||||
info = manage_probuilder(action="get_mesh_info", target="MyCube",
|
||||
properties={"include": "edges"})
|
||||
|
||||
# Bevel specific edges
|
||||
manage_probuilder(action="bevel_edges", target="MyCube",
|
||||
properties={"edgeIndices": [0, 1, 2, 3], "amount": 0.1})
|
||||
```
|
||||
|
||||
### Detach Faces to New Object
|
||||
|
||||
```python
|
||||
# Detach and keep original (default)
|
||||
manage_probuilder(action="detach_faces", target="MyCube",
|
||||
properties={"faceIndices": [0, 1], "deleteSourceFaces": False})
|
||||
|
||||
# Detach and remove from source
|
||||
manage_probuilder(action="detach_faces", target="MyCube",
|
||||
properties={"faceIndices": [0, 1], "deleteSourceFaces": True})
|
||||
```
|
||||
|
||||
### Select Faces by Direction
|
||||
|
||||
```python
|
||||
# Select all upward-facing faces
|
||||
manage_probuilder(action="select_faces", target="MyMesh",
|
||||
properties={"direction": "up", "tolerance": 0.7})
|
||||
|
||||
# Grow selection from a seed face
|
||||
manage_probuilder(action="select_faces", target="MyMesh",
|
||||
properties={"growFrom": [0], "growAngle": 45})
|
||||
```
|
||||
|
||||
### Double-Sided Geometry
|
||||
|
||||
```python
|
||||
# Create inside faces for a room (duplicate and flip normals)
|
||||
manage_probuilder(action="duplicate_and_flip", target="Room",
|
||||
properties={"faceIndices": [0, 1, 2, 3, 4, 5]})
|
||||
```
|
||||
|
||||
### Create Polygon from Existing Vertices
|
||||
|
||||
```python
|
||||
# Connect existing vertices into a new face (auto-finds winding order)
|
||||
manage_probuilder(action="create_polygon", target="MyMesh",
|
||||
properties={"vertexIndices": [0, 3, 7, 4]})
|
||||
```
|
||||
|
||||
## Vertex Operations
|
||||
|
||||
```python
|
||||
# Move vertices by offset
|
||||
manage_probuilder(action="move_vertices", target="MyCube",
|
||||
properties={"vertexIndices": [0, 1, 2, 3], "offset": [0, 1, 0]})
|
||||
|
||||
# Weld nearby vertices (proximity-based merge)
|
||||
manage_probuilder(action="weld_vertices", target="MyCube",
|
||||
properties={"vertexIndices": [0, 1, 2, 3], "radius": 0.1})
|
||||
|
||||
# Insert vertex on an edge
|
||||
manage_probuilder(action="insert_vertex", target="MyCube",
|
||||
properties={"edge": {"a": 0, "b": 1}, "point": [0.5, 0, 0]})
|
||||
|
||||
# Add evenly-spaced points along edges
|
||||
manage_probuilder(action="append_vertices_to_edge", target="MyCube",
|
||||
properties={"edgeIndices": [0, 1], "count": 3})
|
||||
```
|
||||
|
||||
## Smoothing Workflow
|
||||
|
||||
### Auto-Smooth (Recommended Default)
|
||||
|
||||
```python
|
||||
# Apply auto-smoothing with default 30 degree threshold
|
||||
manage_probuilder(action="auto_smooth", target="MyMesh",
|
||||
properties={"angleThreshold": 30})
|
||||
```
|
||||
|
||||
- **Low angle (15-25)**: More hard edges, faceted look
|
||||
- **Medium angle (30-45)**: Good default, smooth curves + sharp corners
|
||||
- **High angle (60-80)**: Very smooth, only sharpest edges remain hard
|
||||
|
||||
### Manual Smoothing Groups
|
||||
|
||||
```python
|
||||
# Set specific faces to smooth group 1
|
||||
manage_probuilder(action="set_smoothing", target="MyMesh",
|
||||
properties={"faceIndices": [0, 1, 2], "smoothingGroup": 1})
|
||||
|
||||
# Set other faces to hard edges (group 0)
|
||||
manage_probuilder(action="set_smoothing", target="MyMesh",
|
||||
properties={"faceIndices": [3, 4, 5], "smoothingGroup": 0})
|
||||
```
|
||||
|
||||
## Mesh Cleanup Pattern
|
||||
|
||||
After editing, always clean up:
|
||||
|
||||
```python
|
||||
# 1. Center the pivot (important after extrusions that shift geometry)
|
||||
manage_probuilder(action="center_pivot", target="MyMesh")
|
||||
|
||||
# 2. Optionally freeze transform if you moved/rotated the object
|
||||
manage_probuilder(action="freeze_transform", target="MyMesh")
|
||||
|
||||
# 3. Validate mesh health
|
||||
result = manage_probuilder(action="validate_mesh", target="MyMesh")
|
||||
# Check result.data.healthy -- if false, repair
|
||||
|
||||
# 4. Auto-repair if needed
|
||||
manage_probuilder(action="repair_mesh", target="MyMesh")
|
||||
```
|
||||
|
||||
## Building Complex Objects with ProBuilder
|
||||
|
||||
When ProBuilder is available, prefer it over primitive GameObjects for complex geometry. ProBuilder lets you create, edit, and combine shapes into detailed objects without external 3D tools.
|
||||
|
||||
### Example: Simple House
|
||||
|
||||
```python
|
||||
# 1. Create base building
|
||||
manage_probuilder(action="create_shape", properties={
|
||||
"shape_type": "Cube", "name": "House", "width": 6, "height": 3, "depth": 8
|
||||
})
|
||||
|
||||
# 2. Get face info to find the top face
|
||||
info = manage_probuilder(action="get_mesh_info", target="House",
|
||||
properties={"include": "faces"})
|
||||
# Find direction="top" -> e.g. index 2
|
||||
|
||||
# 3. Extrude the top face to create a flat raised section
|
||||
manage_probuilder(action="extrude_faces", target="House",
|
||||
properties={"faceIndices": [2], "distance": 0.3})
|
||||
|
||||
# 4. Re-query faces, then move top vertices inward to form a ridge
|
||||
info = manage_probuilder(action="get_mesh_info", target="House",
|
||||
properties={"include": "faces"})
|
||||
# Find the new top face after extrude, get its vertex indices
|
||||
# Move them to form a peaked roof shape
|
||||
manage_probuilder(action="move_vertices", target="House",
|
||||
properties={"vertexIndices": [0, 1, 2, 3], "offset": [0, 2, 0]})
|
||||
|
||||
# 5. Cut a doorway: subdivide front face, delete center sub-face
|
||||
info = manage_probuilder(action="get_mesh_info", target="House",
|
||||
properties={"include": "faces"})
|
||||
# Find direction="front", subdivide it
|
||||
manage_probuilder(action="subdivide", target="House",
|
||||
properties={"faceIndices": [4]})
|
||||
|
||||
# Re-query, find bottom-center face, delete it
|
||||
info = manage_probuilder(action="get_mesh_info", target="House",
|
||||
properties={"include": "faces"})
|
||||
manage_probuilder(action="delete_faces", target="House",
|
||||
properties={"faceIndices": [12]})
|
||||
|
||||
# 6. Add a door frame with arch
|
||||
manage_probuilder(action="create_shape", properties={
|
||||
"shape_type": "Door", "name": "Doorway",
|
||||
"position": [0, 0, 4], "width": 1.5, "height": 2.5
|
||||
})
|
||||
|
||||
# 7. Add stairs to the door
|
||||
manage_probuilder(action="create_shape", properties={
|
||||
"shape_type": "Stair", "name": "FrontSteps",
|
||||
"position": [0, 0, 5], "steps": 3, "width": 2
|
||||
})
|
||||
|
||||
# 8. Smooth organic parts, keep architectural edges sharp
|
||||
manage_probuilder(action="auto_smooth", target="House",
|
||||
properties={"angleThreshold": 30})
|
||||
|
||||
# 9. Assign materials per face
|
||||
manage_probuilder(action="set_face_material", target="House",
|
||||
properties={"faceIndices": [0, 1, 2, 3], "materialPath": "Assets/Materials/Brick.mat"})
|
||||
manage_probuilder(action="set_face_material", target="House",
|
||||
properties={"faceIndices": [4, 5], "materialPath": "Assets/Materials/Roof.mat"})
|
||||
|
||||
# 10. Cleanup
|
||||
manage_probuilder(action="center_pivot", target="House")
|
||||
manage_probuilder(action="validate_mesh", target="House")
|
||||
```
|
||||
|
||||
### Example: Pillared Corridor (Batch)
|
||||
|
||||
```python
|
||||
# Create multiple columns efficiently
|
||||
batch_execute(commands=[
|
||||
{"tool": "manage_probuilder", "params": {
|
||||
"action": "create_shape",
|
||||
"properties": {"shape_type": "Cylinder", "name": f"Pillar_{i}",
|
||||
"radius": 0.3, "height": 4, "segments": 12,
|
||||
"position": [i * 3, 0, 0]}
|
||||
}} for i in range(6)
|
||||
] + [
|
||||
# Floor
|
||||
{"tool": "manage_probuilder", "params": {
|
||||
"action": "create_shape",
|
||||
"properties": {"shape_type": "Plane", "name": "Floor",
|
||||
"width": 18, "height": 6, "position": [7.5, 0, 0]}
|
||||
}},
|
||||
# Ceiling
|
||||
{"tool": "manage_probuilder", "params": {
|
||||
"action": "create_shape",
|
||||
"properties": {"shape_type": "Plane", "name": "Ceiling",
|
||||
"width": 18, "height": 6, "position": [7.5, 4, 0]}
|
||||
}},
|
||||
])
|
||||
|
||||
# Bevel all pillar tops for decoration
|
||||
for i in range(6):
|
||||
info = manage_probuilder(action="get_mesh_info", target=f"Pillar_{i}",
|
||||
properties={"include": "edges"})
|
||||
# Find top ring edges, bevel them
|
||||
manage_probuilder(action="bevel_edges", target=f"Pillar_{i}",
|
||||
properties={"edgeIndices": [0, 1, 2, 3], "amount": 0.05})
|
||||
|
||||
# Smooth the pillars
|
||||
for i in range(6):
|
||||
manage_probuilder(action="auto_smooth", target=f"Pillar_{i}",
|
||||
properties={"angleThreshold": 45})
|
||||
```
|
||||
|
||||
### Example: Custom L-Shaped Room
|
||||
|
||||
```python
|
||||
# Use polygon shape for non-rectangular footprint
|
||||
manage_probuilder(action="create_poly_shape", properties={
|
||||
"points": [
|
||||
[0, 0, 0], [10, 0, 0], [10, 0, 6],
|
||||
[4, 0, 6], [4, 0, 10], [0, 0, 10]
|
||||
],
|
||||
"extrudeHeight": 3.0,
|
||||
"name": "LRoom"
|
||||
})
|
||||
|
||||
# Create inside faces for the room interior
|
||||
info = manage_probuilder(action="get_mesh_info", target="LRoom",
|
||||
properties={"include": "faces"})
|
||||
# Duplicate and flip all faces to make interior visible
|
||||
all_faces = list(range(info["data"]["faceCount"]))
|
||||
manage_probuilder(action="duplicate_and_flip", target="LRoom",
|
||||
properties={"faceIndices": all_faces})
|
||||
|
||||
# Cut a window: subdivide a wall face, delete center
|
||||
# (follow the get_mesh_info -> subdivide -> get_mesh_info -> delete pattern)
|
||||
```
|
||||
|
||||
### Example: Torus Knot / Decorative Ring
|
||||
|
||||
```python
|
||||
# Create a torus
|
||||
manage_probuilder(action="create_shape", properties={
|
||||
"shape_type": "Torus", "name": "Ring",
|
||||
"innerRadius": 0.3, "outerRadius": 2.0,
|
||||
"rows": 24, "columns": 32
|
||||
})
|
||||
|
||||
# Smooth it for organic look
|
||||
manage_probuilder(action="auto_smooth", target="Ring",
|
||||
properties={"angleThreshold": 60})
|
||||
|
||||
# Assign metallic material
|
||||
manage_probuilder(action="set_face_material", target="Ring",
|
||||
properties={"faceIndices": [], "materialPath": "Assets/Materials/Gold.mat"})
|
||||
# Note: empty faceIndices = all faces
|
||||
```
|
||||
|
||||
## Batch Patterns
|
||||
|
||||
Use `batch_execute` for multi-step workflows to reduce round-trips:
|
||||
|
||||
```python
|
||||
batch_execute(commands=[
|
||||
{"tool": "manage_probuilder", "params": {
|
||||
"action": "create_shape",
|
||||
"properties": {"shape_type": "Cube", "name": "Column1", "position": [0, 0, 0]}
|
||||
}},
|
||||
{"tool": "manage_probuilder", "params": {
|
||||
"action": "create_shape",
|
||||
"properties": {"shape_type": "Cube", "name": "Column2", "position": [5, 0, 0]}
|
||||
}},
|
||||
{"tool": "manage_probuilder", "params": {
|
||||
"action": "create_shape",
|
||||
"properties": {"shape_type": "Cube", "name": "Column3", "position": [10, 0, 0]}
|
||||
}},
|
||||
])
|
||||
```
|
||||
|
||||
## Known Limitations
|
||||
|
||||
### Not Yet Working
|
||||
|
||||
These actions exist in the API but have known bugs that prevent them from working correctly:
|
||||
|
||||
| Action | Issue | Workaround |
|
||||
|--------|-------|------------|
|
||||
| `set_pivot` | Vertex positions don't persist through `ToMesh()`/`RefreshMesh()`. The `positions` property setter is overwritten when ProBuilder rebuilds the mesh. Needs `SetVertices(IList<Vertex>)` or direct `m_Positions` field access. | Use `center_pivot` instead, or position objects via Transform. |
|
||||
| `convert_to_probuilder` | `MeshImporter` constructor throws internally. May need ProBuilder's editor-only `ProBuilderize` API instead of runtime `MeshImporter`. | Create shapes natively with `create_shape` or `create_poly_shape` instead of converting existing meshes. |
|
||||
|
||||
### General Limitations
|
||||
|
||||
- Face indices are **not stable** across edits -- always re-query `get_mesh_info` after any modification
|
||||
- Edge data is capped at **200 edges** in `get_mesh_info` results
|
||||
- Face data is capped at **100 faces** in `get_mesh_info` results
|
||||
- `subdivide` uses `ConnectElements.Connect` internally (ProBuilder has no public `Subdivide` API), which connects face midpoints rather than traditional quad subdivision
|
||||
|
||||
## Key Rules
|
||||
|
||||
1. **Always get_mesh_info before editing** -- face indices are not stable across edits
|
||||
2. **Re-query after modifications** -- subdivide, extrude, delete all change face indices
|
||||
3. **Use direction labels** -- don't guess face indices, use the direction field
|
||||
4. **Cleanup after editing** -- center_pivot + validate is good practice
|
||||
5. **Auto-smooth for organic shapes** -- 30 degrees is a good default
|
||||
6. **Prefer ProBuilder over primitives** -- when the package is available and you need editable geometry
|
||||
7. **Use batch_execute** -- for creating multiple shapes or repetitive operations
|
||||
8. **Screenshot to verify** -- use `manage_camera(action="screenshot", include_image=True)` to check visual results after complex edits
|
||||
@@ -0,0 +1,645 @@
|
||||
# Unity-MCP Resources Reference
|
||||
|
||||
Resources provide read-only access to Unity state. Use resources to inspect before using tools to modify.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Editor State Resources](#editor-state-resources)
|
||||
- [Camera Resources](#camera-resources)
|
||||
- [Graphics Resources](#graphics-resources)
|
||||
- [Scene & GameObject Resources](#scene--gameobject-resources)
|
||||
- [Prefab Resources](#prefab-resources)
|
||||
- [Project Resources](#project-resources)
|
||||
- [Instance Resources](#instance-resources)
|
||||
- [Test Resources](#test-resources)
|
||||
|
||||
---
|
||||
|
||||
## URI Scheme
|
||||
|
||||
All resources use `mcpforunity://` scheme:
|
||||
|
||||
```
|
||||
mcpforunity://{category}/{resource_path}[?query_params]
|
||||
```
|
||||
|
||||
**Categories:** `editor`, `scene`, `prefab`, `project`, `pipeline`, `rendering`, `menu-items`, `custom-tools`, `tests`, `instances`
|
||||
|
||||
---
|
||||
|
||||
## Editor State Resources
|
||||
|
||||
### mcpforunity://editor/state
|
||||
|
||||
**Purpose:** Editor readiness snapshot - check before tool operations.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"unity_version": "2022.3.10f1",
|
||||
"is_compiling": false,
|
||||
"is_domain_reload_pending": false,
|
||||
"play_mode": {
|
||||
"is_playing": false,
|
||||
"is_paused": false
|
||||
},
|
||||
"active_scene": {
|
||||
"path": "Assets/Scenes/Main.unity",
|
||||
"name": "Main"
|
||||
},
|
||||
"ready_for_tools": true,
|
||||
"blocking_reasons": [],
|
||||
"recommended_retry_after_ms": null,
|
||||
"staleness": {
|
||||
"age_ms": 150,
|
||||
"is_stale": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Key Fields:**
|
||||
- `ready_for_tools`: Only proceed if `true`
|
||||
- `is_compiling`: Wait if `true`
|
||||
- `blocking_reasons`: Array explaining why tools might fail
|
||||
- `recommended_retry_after_ms`: Suggested wait time
|
||||
|
||||
### mcpforunity://editor/selection
|
||||
|
||||
**Purpose:** Currently selected objects.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"activeObject": "Player",
|
||||
"activeGameObject": "Player",
|
||||
"activeInstanceID": 12345,
|
||||
"count": 3,
|
||||
"gameObjects": ["Player", "Enemy", "Wall"],
|
||||
"assetGUIDs": []
|
||||
}
|
||||
```
|
||||
|
||||
### mcpforunity://editor/active-tool
|
||||
|
||||
**Purpose:** Current editor tool state.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"activeTool": "Move",
|
||||
"isCustom": false,
|
||||
"pivotMode": "Center",
|
||||
"pivotRotation": "Global"
|
||||
}
|
||||
```
|
||||
|
||||
### mcpforunity://editor/windows
|
||||
|
||||
**Purpose:** All open editor windows.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"windows": [
|
||||
{
|
||||
"title": "Scene",
|
||||
"typeName": "UnityEditor.SceneView",
|
||||
"isFocused": true,
|
||||
"position": {"x": 0, "y": 0, "width": 800, "height": 600}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### mcpforunity://editor/prefab-stage
|
||||
|
||||
**Purpose:** Current prefab editing context.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"isOpen": true,
|
||||
"assetPath": "Assets/Prefabs/Player.prefab",
|
||||
"prefabRootName": "Player",
|
||||
"isDirty": false
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Camera Resources
|
||||
|
||||
### mcpforunity://scene/cameras
|
||||
|
||||
**Purpose:** List all cameras in the scene (Unity Camera + CinemachineCamera) with full status. Read this before using `manage_camera` to understand the current camera setup.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"brain": {
|
||||
"exists": true,
|
||||
"gameObject": "Main Camera",
|
||||
"instanceID": 55504,
|
||||
"activeCameraName": "Cam_Cinematic",
|
||||
"activeCameraID": -39420,
|
||||
"isBlending": false
|
||||
},
|
||||
"cinemachineCameras": [
|
||||
{
|
||||
"instanceID": -39420,
|
||||
"name": "Cam_Cinematic",
|
||||
"isLive": true,
|
||||
"priority": 50,
|
||||
"follow": {"name": "CameraTarget", "instanceID": -26766},
|
||||
"lookAt": {"name": "CameraTarget", "instanceID": -26766},
|
||||
"body": "CinemachineThirdPersonFollow",
|
||||
"aim": "CinemachineRotationComposer",
|
||||
"noise": "CinemachineBasicMultiChannelPerlin",
|
||||
"extensions": []
|
||||
}
|
||||
],
|
||||
"unityCameras": [
|
||||
{
|
||||
"instanceID": 55504,
|
||||
"name": "Main Camera",
|
||||
"depth": 0.0,
|
||||
"fieldOfView": 50.0,
|
||||
"hasBrain": true
|
||||
}
|
||||
],
|
||||
"cinemachineInstalled": true
|
||||
}
|
||||
```
|
||||
|
||||
**Key Fields:**
|
||||
- `brain`: CinemachineBrain status — which camera is active, blend state
|
||||
- `cinemachineCameras`: All CinemachineCamera components with pipeline info (body, aim, noise, extensions)
|
||||
- `unityCameras`: All Unity Camera components with depth and FOV
|
||||
- `cinemachineInstalled`: Whether Cinemachine package is available
|
||||
|
||||
**Use with:** `manage_camera` tool for creating/configuring cameras
|
||||
|
||||
---
|
||||
|
||||
## Graphics Resources
|
||||
|
||||
### mcpforunity://scene/volumes
|
||||
|
||||
**Purpose:** List all Volume components in the scene with effects and parameters. Read this before using `manage_graphics` volume actions.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"pipeline": "Universal (URP)",
|
||||
"volumes": [
|
||||
{
|
||||
"name": "PostProcessVolume",
|
||||
"instance_id": -24600,
|
||||
"is_global": true,
|
||||
"weight": 1.0,
|
||||
"priority": 0,
|
||||
"blend_distance": 0,
|
||||
"profile": "MyProfile",
|
||||
"profile_path": "Assets/Settings/MyProfile.asset",
|
||||
"effects": [
|
||||
{
|
||||
"type": "Bloom",
|
||||
"active": true,
|
||||
"overridden_params": ["intensity", "threshold", "scatter"]
|
||||
},
|
||||
{
|
||||
"type": "Vignette",
|
||||
"active": true,
|
||||
"overridden_params": ["intensity", "smoothness"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Key Fields:**
|
||||
- `is_global`: Whether the volume applies everywhere or only within its collider bounds
|
||||
- `effects[].overridden_params`: Which parameters are actively overridden (not using defaults)
|
||||
- `profile_path`: Empty string for embedded profiles, asset path for shared profiles
|
||||
|
||||
**Use with:** `manage_graphics` volume actions (volume_create, volume_add_effect, volume_set_effect, etc.)
|
||||
|
||||
### mcpforunity://rendering/stats
|
||||
|
||||
**Purpose:** Current rendering performance counters (draw calls, batches, triangles, memory).
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"draw_calls": 42,
|
||||
"batches": 35,
|
||||
"set_pass_calls": 12,
|
||||
"triangles": 15234,
|
||||
"vertices": 8456,
|
||||
"dynamic_batches": 5,
|
||||
"static_batches": 20,
|
||||
"shadow_casters": 3,
|
||||
"render_textures": 8,
|
||||
"render_textures_bytes": 16777216,
|
||||
"visible_skinned_meshes": 2
|
||||
}
|
||||
```
|
||||
|
||||
**Use with:** `manage_graphics` stats actions (stats_get, stats_list_counters, stats_get_memory)
|
||||
|
||||
### mcpforunity://pipeline/renderer-features
|
||||
|
||||
**Purpose:** URP renderer features on the active renderer (SSAO, Decals, etc.).
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"rendererDataName": "PC_Renderer",
|
||||
"features": [
|
||||
{
|
||||
"index": 0,
|
||||
"name": "ScreenSpaceAmbientOcclusion",
|
||||
"type": "ScreenSpaceAmbientOcclusion",
|
||||
"isActive": true,
|
||||
"properties": { "m_Settings": "Generic" }
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Key Fields:**
|
||||
- `index`: Position in the feature list (use for feature_toggle, feature_remove, feature_configure)
|
||||
- `isActive`: Whether the feature is enabled
|
||||
- `rendererDataName`: Which URP renderer data asset is active
|
||||
|
||||
**Use with:** `manage_graphics` feature actions (feature_list, feature_add, feature_remove, feature_toggle, etc.)
|
||||
|
||||
---
|
||||
|
||||
## Scene & GameObject Resources
|
||||
|
||||
### mcpforunity://scene/gameobject-api
|
||||
|
||||
**Purpose:** Documentation for GameObject resources (read this first).
|
||||
|
||||
### mcpforunity://scene/gameobject/{instance_id}
|
||||
|
||||
**Purpose:** Basic GameObject data (metadata, no component properties).
|
||||
|
||||
**Parameters:**
|
||||
- `instance_id` (int): GameObject instance ID from `find_gameobjects`
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"instanceID": 12345,
|
||||
"name": "Player",
|
||||
"tag": "Player",
|
||||
"layer": 8,
|
||||
"layerName": "Player",
|
||||
"active": true,
|
||||
"activeInHierarchy": true,
|
||||
"isStatic": false,
|
||||
"transform": {
|
||||
"position": [0, 1, 0],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
},
|
||||
"parent": {"instanceID": 0},
|
||||
"children": [{"instanceID": 67890}],
|
||||
"componentTypes": ["Transform", "Rigidbody", "PlayerController"],
|
||||
"path": "/Player"
|
||||
}
|
||||
```
|
||||
|
||||
### mcpforunity://scene/gameobject/{instance_id}/components
|
||||
|
||||
**Purpose:** All components with full property serialization (paginated).
|
||||
|
||||
**Parameters:**
|
||||
- `instance_id` (int): GameObject instance ID
|
||||
- `page_size` (int): Default 25, max 100
|
||||
- `cursor` (int): Pagination cursor
|
||||
- `include_properties` (bool): Default true, set false for just types
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"gameObjectID": 12345,
|
||||
"gameObjectName": "Player",
|
||||
"components": [
|
||||
{
|
||||
"type": "Transform",
|
||||
"properties": {
|
||||
"position": {"x": 0, "y": 1, "z": 0},
|
||||
"rotation": {"x": 0, "y": 0, "z": 0, "w": 1}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Rigidbody",
|
||||
"properties": {
|
||||
"mass": 1.0,
|
||||
"useGravity": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"cursor": 0,
|
||||
"pageSize": 25,
|
||||
"nextCursor": null,
|
||||
"hasMore": false
|
||||
}
|
||||
```
|
||||
|
||||
### mcpforunity://scene/gameobject/{instance_id}/component/{component_name}
|
||||
|
||||
**Purpose:** Single component with full properties.
|
||||
|
||||
**Parameters:**
|
||||
- `instance_id` (int): GameObject instance ID
|
||||
- `component_name` (string): e.g., "Rigidbody", "Camera", "Transform"
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"gameObjectID": 12345,
|
||||
"gameObjectName": "Player",
|
||||
"component": {
|
||||
"type": "Rigidbody",
|
||||
"properties": {
|
||||
"mass": 1.0,
|
||||
"drag": 0,
|
||||
"angularDrag": 0.05,
|
||||
"useGravity": true,
|
||||
"isKinematic": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Prefab Resources
|
||||
|
||||
### mcpforunity://prefab-api
|
||||
|
||||
**Purpose:** Documentation for prefab resources.
|
||||
|
||||
### mcpforunity://prefab/{encoded_path}
|
||||
|
||||
**Purpose:** Prefab asset information.
|
||||
|
||||
**Parameters:**
|
||||
- `encoded_path` (string): URL-encoded path, e.g., `Assets%2FPrefabs%2FPlayer.prefab`
|
||||
|
||||
**Path Encoding:**
|
||||
```
|
||||
Assets/Prefabs/Player.prefab → Assets%2FPrefabs%2FPlayer.prefab
|
||||
```
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"assetPath": "Assets/Prefabs/Player.prefab",
|
||||
"guid": "abc123...",
|
||||
"prefabType": "Regular",
|
||||
"rootObjectName": "Player",
|
||||
"rootComponentTypes": ["Transform", "PlayerController"],
|
||||
"childCount": 5,
|
||||
"isVariant": false,
|
||||
"parentPrefab": null
|
||||
}
|
||||
```
|
||||
|
||||
### mcpforunity://prefab/{encoded_path}/hierarchy
|
||||
|
||||
**Purpose:** Full prefab hierarchy with nested prefab info.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"prefabPath": "Assets/Prefabs/Player.prefab",
|
||||
"total": 6,
|
||||
"items": [
|
||||
{
|
||||
"name": "Player",
|
||||
"instanceId": 12345,
|
||||
"path": "/Player",
|
||||
"activeSelf": true,
|
||||
"childCount": 2,
|
||||
"componentTypes": ["Transform", "PlayerController"]
|
||||
},
|
||||
{
|
||||
"name": "Model",
|
||||
"path": "/Player/Model",
|
||||
"isNestedPrefab": true,
|
||||
"nestedPrefabPath": "Assets/Prefabs/PlayerModel.prefab"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Project Resources
|
||||
|
||||
### mcpforunity://project/info
|
||||
|
||||
**Purpose:** Static project configuration.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"projectRoot": "/Users/dev/MyProject",
|
||||
"projectName": "MyProject",
|
||||
"unityVersion": "2022.3.10f1",
|
||||
"platform": "StandaloneWindows64",
|
||||
"assetsPath": "/Users/dev/MyProject/Assets"
|
||||
}
|
||||
```
|
||||
|
||||
### mcpforunity://project/tags
|
||||
|
||||
**Purpose:** All tags defined in TagManager.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
["Untagged", "Respawn", "Finish", "EditorOnly", "MainCamera", "Player", "GameController", "Enemy"]
|
||||
```
|
||||
|
||||
### mcpforunity://project/layers
|
||||
|
||||
**Purpose:** All layers with indices (0-31).
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"0": "Default",
|
||||
"1": "TransparentFX",
|
||||
"2": "Ignore Raycast",
|
||||
"4": "Water",
|
||||
"5": "UI",
|
||||
"8": "Player",
|
||||
"9": "Enemy"
|
||||
}
|
||||
```
|
||||
|
||||
### mcpforunity://menu-items
|
||||
|
||||
**Purpose:** All available Unity menu items.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
[
|
||||
"File/New Scene",
|
||||
"File/Open Scene",
|
||||
"File/Save",
|
||||
"Edit/Undo",
|
||||
"Edit/Redo",
|
||||
"GameObject/Create Empty",
|
||||
"GameObject/3D Object/Cube",
|
||||
"Window/General/Console"
|
||||
]
|
||||
```
|
||||
|
||||
### mcpforunity://custom-tools
|
||||
|
||||
**Purpose:** Custom tools available in the active Unity project.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"project_id": "MyProject",
|
||||
"tool_count": 3,
|
||||
"tools": [
|
||||
{
|
||||
"name": "capture_screenshot",
|
||||
"description": "Capture screenshots in Unity",
|
||||
"parameters": [
|
||||
{"name": "filename", "type": "string", "required": true},
|
||||
{"name": "width", "type": "int", "required": false},
|
||||
{"name": "height", "type": "int", "required": false}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Instance Resources
|
||||
|
||||
### mcpforunity://instances
|
||||
|
||||
**Purpose:** All running Unity Editor instances (for multi-instance workflows).
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"transport": "http",
|
||||
"instance_count": 2,
|
||||
"instances": [
|
||||
{
|
||||
"id": "MyProject@abc123",
|
||||
"name": "MyProject",
|
||||
"hash": "abc123",
|
||||
"unity_version": "2022.3.10f1",
|
||||
"connected_at": "2024-01-15T10:30:00Z"
|
||||
},
|
||||
{
|
||||
"id": "TestProject@def456",
|
||||
"name": "TestProject",
|
||||
"hash": "def456",
|
||||
"unity_version": "2022.3.10f1",
|
||||
"connected_at": "2024-01-15T11:00:00Z"
|
||||
}
|
||||
],
|
||||
"warnings": []
|
||||
}
|
||||
```
|
||||
|
||||
**Use with:** `set_active_instance(instance="MyProject@abc123")`
|
||||
|
||||
---
|
||||
|
||||
## Test Resources
|
||||
|
||||
### mcpforunity://tests
|
||||
|
||||
**Purpose:** All tests in the project.
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "TestSomething",
|
||||
"full_name": "MyTests.TestSomething",
|
||||
"mode": "EditMode"
|
||||
},
|
||||
{
|
||||
"name": "TestOther",
|
||||
"full_name": "MyTests.TestOther",
|
||||
"mode": "PlayMode"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### mcpforunity://tests/{mode}
|
||||
|
||||
**Purpose:** Tests filtered by mode.
|
||||
|
||||
**Parameters:**
|
||||
- `mode` (string): "EditMode" or "PlayMode"
|
||||
|
||||
**Example:** `mcpforunity://tests/EditMode`
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Check Editor State First
|
||||
|
||||
```python
|
||||
# Before any complex operation:
|
||||
# Read mcpforunity://editor/state
|
||||
# Check ready_for_tools == true
|
||||
```
|
||||
|
||||
### 2. Use Find Then Read Pattern
|
||||
|
||||
```python
|
||||
# 1. find_gameobjects to get IDs
|
||||
result = find_gameobjects(search_term="Player")
|
||||
|
||||
# 2. Read resource for full data
|
||||
# mcpforunity://scene/gameobject/{id}
|
||||
```
|
||||
|
||||
### 3. Paginate Large Queries
|
||||
|
||||
```python
|
||||
# Start with include_properties=false for component lists
|
||||
# mcpforunity://scene/gameobject/{id}/components?include_properties=false&page_size=25
|
||||
|
||||
# Then read specific components as needed
|
||||
# mcpforunity://scene/gameobject/{id}/component/Rigidbody
|
||||
```
|
||||
|
||||
### 4. URL-Encode Prefab Paths
|
||||
|
||||
```python
|
||||
# Wrong:
|
||||
# mcpforunity://prefab/Assets/Prefabs/Player.prefab
|
||||
|
||||
# Correct:
|
||||
# mcpforunity://prefab/Assets%2FPrefabs%2FPlayer.prefab
|
||||
```
|
||||
|
||||
### 5. Multi-Instance Awareness
|
||||
|
||||
```python
|
||||
# Always check mcpforunity://instances when:
|
||||
# - First connecting
|
||||
# - Commands fail unexpectedly
|
||||
# - Working with multiple projects
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user