/blender-to-unity
Hand off a model from Blender (via BlenderMCP) into Unity (via MCP for Unity) — export the current Blender model, import it through import_model_file, and place it in the open scene. Use when the user has BlenderMCP and MCP for Unity both connected and wants to bring a Blender
$ npx -y skills add CoplayDev/unity-mcp --skill blender-to-unity --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/blender-to-unity
Context preview
The summary Claude sees to decide when to auto-load this skill.
Hand off a model from Blender (via BlenderMCP) into Unity (via MCP for Unity) — export the current Blender model, import it through import_model_file, and place it in the open scene. Use when the user has BlenderMCP and MCP for Unity both connected and wants to bring a Blender
SKILL.md
blender-to-unity.SKILL.mdname: blender-to-unity
description: Hand off a model from Blender (via BlenderMCP) into Unity (via MCP for Unity) — export the current Blender model, import it through import_model_file, and place it in the open scene. Use when the user has BlenderMCP and MCP for Unity both connected and wants to bring a Blender model into Unity. Does NOT drive Blender's own generators; BlenderMCP owns how the model got into Blender.
Blender → Unity Model Handoff
Bring whatever model is currently in Blender into the open Unity scene. The seam is the local filesystem: Blender exports a file, Unity imports it. The two servers never talk directly.
Preconditions
- Both `mcp__blender__*` tools and MCP for Unity tools are connected.
- A model exists in the Blender scene (confirm with `mcp__blender__get_scene_info` /
`mcp__blender__get_object_info`). If empty, stop and tell the user — this skill does not generate models.
- **`import_model_file` is in the `asset_gen` tool group, which is off by default** (only `core`
loads). Enable it first with `manage_tools` (enable the `asset_gen` group), **or** call the C# handler straight through `batch_execute` — `{"tool":"import_model_file","params":{"sourcePath":...,"name":...,"outputFolder":...}}` (camelCase) — which dispatches by name regardless of group gating.
Steps
1. **Resolve the Unity project path.** Read `mcpforunity://editor/state` for the project root (the editor dataPath's parent). Decide the export format:
- **GLB (glTFast) when the model has a rig, animation, PBR (metallic/roughness), emission,
or transparency** — glTFast carries all of these automatically, no post-processing (see [references/bridge-fidelity.md](references/bridge-fidelity.md)). Multi-material zones survive either format, so they alone don't force GLB.
- **FBX otherwise** — when glTFast isn't installed, the model is plain geometry, or you
specifically need the built-in importer's humanoid-avatar pipeline. FBX drops emission/metallic (Step 5 restores emission) and surfaces animation only with `animation_type` set (Step 3). 2. **Export from Blender to a temp path** via `mcp__blender__execute_blender_code`:
import bpy, os, tempfile
out = os.path.join(tempfile.gettempdir(), "blender_to_unity.fbx")
# Export the selection if any, else the whole scene:
bpy.ops.export_scene.fbx(filepath=out, use_selection=bool(bpy.context.selected_objects),
apply_unit_scale=True, bake_space_transform=True)
print(out)(glTF branch: `out_glb = os.path.join(tempfile.gettempdir(), "blender_to_unity.glb")`, then `bpy.ops.export_scene.gltf(filepath=out_glb, export_format='GLB', use_active_scene=True)` — its default `use_active_scene=False` can silently export a *different* open scene.) 3. **Import into Unity** with `import_model_file`: `import_model_file(source_path=<temp path>, name=<asset name>, target_size=<final size in meters>)`. For a **rigged/animated FBX**, also pass `animation_type="generic"` (or `"humanoid"`; `"legacy"` targets the old Animation-component system) — the importer defaults to `"none"`, which deliberately imports the mesh with **zero animation clips**. GLB ignores this (glTFast imports animation itself), so it's an FBX-only knob. It returns `{ asset_path, asset_guid }`. Pass `target_size` as the intended final size, but treat it only as a hint: it rescales at import solely when the project's **Auto-normalize** pref is on, and even then is unreliable for Blender FBX (see the **Scale** note). Step 4 does the reliable normalization. 4. **Place it in the scene, normalized to size.** Ensure the scene has a camera + directional light (`manage_scene` / `manage_gameobject`). Instantiate the model at the chosen position via `manage_gameobject(action="create", prefab_path=<asset_path>, name=<asset name>, position=[x,y,z])`. Then normalize its size deterministically — Blender FBX commonly imports ~100× too large — by measuring the placed model's world bounds and scaling so its largest dimension equals your target size. Run via `execute_code` (substitute your object name and target meters):
var go = GameObject.Find("<asset name>");
var rs = go.GetComponentsInChildren<Renderer>();
var b = rs[0].bounds; for (int i = 1; i < rs.Length; i++) b.Encapsulate(rs[i].bounds);
float maxDim = Mathf.Max(b.size.x, Mathf.Max(b.size.y, b.size.z));
float target = 2f; // intended size in meters
if (maxDim > 0.0001f) go.transform.localScale *= target / maxDim;5. **Restore emission FBX dropped (FBX path).** Blender scenes commonly store their color/glow in *material emission* (and other Principled-node inputs). FBX carries base/diffuse color but **not emission**, so neon / "Tron" scenes import as dark bodies with black accents. If the import looks flat vs. Blender, restore it: a. Dump the emissive materials from Blender via `execute_blender_code`:
import bpy, json
out = {}
for m in bpy.data.materials:
if not (m.use_nodes and m.node_tree): continue
col, s = (0, 0, 0), 0.0
p = next((n for n in m.node_tree.nodes if n.type == 'BSDF_PRINCIPLED'), None)
es = next((k for k in ('Emission Color', 'Emission') if p and k in p.inputs), None) # 4.x / 3.x name
if es:
col = tuple(p.inputs[es].default_value)[:3]
s = float(p.inputs['Emission Strength'].default_value)
e = next((n for n in m.node_tree.nodes if n.type == 'EMISSION'), None)
if e and s == 0:
col = tuple(e.inputs['Color'].default_value)[:3]; s = float(e.inputs['Strength'].default_value)
if s > 0 and sum(col) > 0.01:
out[m.name] = [round(col[0], 3), round(col[1], 3), round(col[2], 3), round(s, 3)]
print(json.dumps(out))b. In Unity (`execute_code`): extract the FBX's materials
Read more
name: blender-to-unity description: Hand off a model from Blender (via BlenderMCP) into Unity (via MCP for Unity) — export the current Blender model, import it through import_model_file, and place it in the open scene. Use when the user has BlenderMCP and MCP for Unity both connected and wants to bring a Blender model into Unity. Does NOT drive Blender's own generators; BlenderMCP owns how the model got into Blender.
Blender → Unity Model Handoff
Bring whatever model is currently in Blender into the open Unity scene. The seam is the local filesystem: Blender exports a file, Unity imports it. The two servers never talk directly.
Preconditions
- Both `mcp__blender__*` tools and MCP for Unity tools are connected.
- A model exists in the Blender scene (confirm with `mcp__blender__get_scene_info` /
`mcp__blender__get_object_info`). If empty, stop and tell the user — this skill does not generate models.
- **`import_model_file` is in the `asset_gen` tool group, which is off by default** (only `core`
loads). Enable it first with `manage_tools` (enable the `asset_gen` group), **or** call the C# handler straight through `batch_execute` — `{"tool":"import_model_file","params":{"sourcePath":...,"name":...,"outputFolder":...}}` (camelCase) — which dispatches by name regardless of group gating.
Steps
1. **Resolve the Unity project path.** Read `mcpforunity://editor/state` for the project root (the editor dataPath's parent). Decide the export format:
- **GLB (glTFast) when the model has a rig, animation, PBR (metallic/roughness), emission,
or transparency** — glTFast carries all of these automatically, no post-processing (see [references/bridge-fidelity.md](references/bridge-fidelity.md)). Multi-material zones survive either format, so they alone don't force GLB.
- **FBX otherwise** — when glTFast isn't installed, the model is plain geometry, or you
specifically need the built-in importer's humanoid-avatar pipeline. FBX drops emission/metallic (Step 5 restores emission) and surfaces animation only with `animation_type` set (Step 3). 2. **Export from Blender to a temp path** via `mcp__blender__execute_blender_code`:
import bpy, os, tempfile
out = os.path.join(tempfile.gettempdir(), "blender_to_unity.fbx")
# Export the selection if any, else the whole scene:
bpy.ops.export_scene.fbx(filepath=out, use_selection=bool(bpy.context.selected_objects),
apply_unit_scale=True, bake_space_transform=True)
print(out)(glTF branch: `out_glb = os.path.join(tempfile.gettempdir(), "blender_to_unity.glb")`, then `bpy.ops.export_scene.gltf(filepath=out_glb, export_format='GLB', use_active_scene=True)` — its default `use_active_scene=False` can silently export a *different* open scene.) 3. **Import into Unity** with `import_model_file`: `import_model_file(source_path=<temp path>, name=<asset name>, target_size=<final size in meters>)`. For a **rigged/animated FBX**, also pass `animation_type="generic"` (or `"humanoid"`; `"legacy"` targets the old Animation-component system) — the importer defaults to `"none"`, which deliberately imports the mesh with **zero animation clips**. GLB ignores this (glTFast imports animation itself), so it's an FBX-only knob. It returns `{ asset_path, asset_guid }`. Pass `target_size` as the intended final size, but treat it only as a hint: it rescales at import solely when the project's **Auto-normalize** pref is on, and even then is unreliable for Blender FBX (see the **Scale** note). Step 4 does the reliable normalization. 4. **Place it in the scene, normalized to size.** Ensure the scene has a camera + directional light (`manage_scene` / `manage_gameobject`). Instantiate the model at the chosen position via `manage_gameobject(action="create", prefab_path=<asset_path>, name=<asset name>, position=[x,y,z])`. Then normalize its size deterministically — Blender FBX commonly imports ~100× too large — by measuring the placed model's world bounds and scaling so its largest dimension equals your target size. Run via `execute_code` (substitute your object name and target meters):
var go = GameObject.Find("<asset name>");
var rs = go.GetComponentsInChildren<Renderer>();
var b = rs[0].bounds; for (int i = 1; i < rs.Length; i++) b.Encapsulate(rs[i].bounds);
float maxDim = Mathf.Max(b.size.x, Mathf.Max(b.size.y, b.size.z));
float target = 2f; // intended size in meters
if (maxDim > 0.0001f) go.transform.localScale *= target / maxDim;5. **Restore emission FBX dropped (FBX path).** Blender scenes commonly store their color/glow in *material emission* (and other Principled-node inputs). FBX carries base/diffuse color but **not emission**, so neon / "Tron" scenes import as dark bodies with black accents. If the import looks flat vs. Blender, restore it: a. Dump the emissive materials from Blender via `execute_blender_code`:
import bpy, json
out = {}
for m in bpy.data.materials:
if not (m.use_nodes and m.node_tree): continue
col, s = (0, 0, 0), 0.0
p = next((n for n in m.node_tree.nodes if n.type == 'BSDF_PRINCIPLED'), None)
es = next((k for k in ('Emission Color', 'Emission') if p and k in p.inputs), None) # 4.x / 3.x name
if es:
col = tuple(p.inputs[es].default_value)[:3]
s = float(p.inputs['Emission Strength'].default_value)
e = next((n for n in m.node_tree.nodes if n.type == 'EMISSION'), None)
if e and s == 0:
col = tuple(e.inputs['Color'].default_value)[:3]; s = float(e.inputs['Strength'].default_value)
if s > 0 and sum(col) > 0.01:
out[m.name] = [round(col[0], 3), round(col[1], 3), round(col[2], 3), round(s, 3)]
print(json.dumps(out))b. In Unity (`execute_code`): extract the FBX's materials
Unity MCP acts as a bridge between AI assistants and your Unity Editor. Give your LLM tools to manage assets, control scenes, edit scripts, and automate tasks within Unity.
Other skills on coplaydev-unity-mcp.
- /mcp-source
Switch MCP for Unity package source in connected Unity projects. Use /mcp-source [main|beta|branch|local] to swap between upstream releases, your remote branch, or local dev checkout.
Open skill - /unity-mcp-skill
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,
Open skill

