mcpforunityserver 9.3.0b20260129104751__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cli/__init__.py +3 -0
- cli/commands/__init__.py +3 -0
- cli/commands/animation.py +84 -0
- cli/commands/asset.py +280 -0
- cli/commands/audio.py +125 -0
- cli/commands/batch.py +171 -0
- cli/commands/code.py +182 -0
- cli/commands/component.py +190 -0
- cli/commands/editor.py +447 -0
- cli/commands/gameobject.py +487 -0
- cli/commands/instance.py +93 -0
- cli/commands/lighting.py +123 -0
- cli/commands/material.py +239 -0
- cli/commands/prefab.py +248 -0
- cli/commands/scene.py +231 -0
- cli/commands/script.py +222 -0
- cli/commands/shader.py +226 -0
- cli/commands/texture.py +540 -0
- cli/commands/tool.py +58 -0
- cli/commands/ui.py +258 -0
- cli/commands/vfx.py +421 -0
- cli/main.py +281 -0
- cli/utils/__init__.py +31 -0
- cli/utils/config.py +58 -0
- cli/utils/confirmation.py +37 -0
- cli/utils/connection.py +258 -0
- cli/utils/constants.py +23 -0
- cli/utils/output.py +195 -0
- cli/utils/parsers.py +112 -0
- cli/utils/suggestions.py +34 -0
- core/__init__.py +0 -0
- core/config.py +52 -0
- core/logging_decorator.py +37 -0
- core/telemetry.py +551 -0
- core/telemetry_decorator.py +164 -0
- main.py +713 -0
- mcpforunityserver-9.3.0b20260129104751.dist-info/METADATA +216 -0
- mcpforunityserver-9.3.0b20260129104751.dist-info/RECORD +103 -0
- mcpforunityserver-9.3.0b20260129104751.dist-info/WHEEL +5 -0
- mcpforunityserver-9.3.0b20260129104751.dist-info/entry_points.txt +3 -0
- mcpforunityserver-9.3.0b20260129104751.dist-info/licenses/LICENSE +21 -0
- mcpforunityserver-9.3.0b20260129104751.dist-info/top_level.txt +7 -0
- models/__init__.py +4 -0
- models/models.py +56 -0
- models/unity_response.py +47 -0
- services/__init__.py +0 -0
- services/custom_tool_service.py +499 -0
- services/registry/__init__.py +22 -0
- services/registry/resource_registry.py +53 -0
- services/registry/tool_registry.py +51 -0
- services/resources/__init__.py +86 -0
- services/resources/active_tool.py +47 -0
- services/resources/custom_tools.py +57 -0
- services/resources/editor_state.py +304 -0
- services/resources/gameobject.py +243 -0
- services/resources/layers.py +29 -0
- services/resources/menu_items.py +34 -0
- services/resources/prefab.py +191 -0
- services/resources/prefab_stage.py +39 -0
- services/resources/project_info.py +39 -0
- services/resources/selection.py +55 -0
- services/resources/tags.py +30 -0
- services/resources/tests.py +87 -0
- services/resources/unity_instances.py +122 -0
- services/resources/windows.py +47 -0
- services/state/external_changes_scanner.py +245 -0
- services/tools/__init__.py +83 -0
- services/tools/batch_execute.py +93 -0
- services/tools/debug_request_context.py +86 -0
- services/tools/execute_custom_tool.py +43 -0
- services/tools/execute_menu_item.py +32 -0
- services/tools/find_gameobjects.py +110 -0
- services/tools/find_in_file.py +181 -0
- services/tools/manage_asset.py +119 -0
- services/tools/manage_components.py +131 -0
- services/tools/manage_editor.py +64 -0
- services/tools/manage_gameobject.py +260 -0
- services/tools/manage_material.py +111 -0
- services/tools/manage_prefabs.py +174 -0
- services/tools/manage_scene.py +111 -0
- services/tools/manage_script.py +645 -0
- services/tools/manage_scriptable_object.py +87 -0
- services/tools/manage_shader.py +71 -0
- services/tools/manage_texture.py +581 -0
- services/tools/manage_vfx.py +120 -0
- services/tools/preflight.py +110 -0
- services/tools/read_console.py +151 -0
- services/tools/refresh_unity.py +153 -0
- services/tools/run_tests.py +317 -0
- services/tools/script_apply_edits.py +1006 -0
- services/tools/set_active_instance.py +117 -0
- services/tools/utils.py +348 -0
- transport/__init__.py +0 -0
- transport/legacy/port_discovery.py +329 -0
- transport/legacy/stdio_port_registry.py +65 -0
- transport/legacy/unity_connection.py +888 -0
- transport/models.py +63 -0
- transport/plugin_hub.py +585 -0
- transport/plugin_registry.py +126 -0
- transport/unity_instance_middleware.py +232 -0
- transport/unity_transport.py +63 -0
- utils/focus_nudge.py +589 -0
- utils/module_discovery.py +55 -0
cli/commands/material.py
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"""Material CLI commands."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import json
|
|
5
|
+
import click
|
|
6
|
+
from typing import Optional, Any, Tuple
|
|
7
|
+
|
|
8
|
+
from cli.utils.config import get_config
|
|
9
|
+
from cli.utils.output import format_output, print_error, print_success
|
|
10
|
+
from cli.utils.connection import run_command, handle_unity_errors
|
|
11
|
+
from cli.utils.parsers import parse_value_safe, parse_json_dict_or_exit
|
|
12
|
+
from cli.utils.constants import SEARCH_METHOD_CHOICE_RENDERER
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@click.group()
|
|
16
|
+
def material():
|
|
17
|
+
"""Material operations - create, modify, assign materials."""
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@material.command("info")
|
|
22
|
+
@click.argument("path")
|
|
23
|
+
@handle_unity_errors
|
|
24
|
+
def info(path: str):
|
|
25
|
+
"""Get information about a material.
|
|
26
|
+
|
|
27
|
+
\b
|
|
28
|
+
Examples:
|
|
29
|
+
unity-mcp material info "Assets/Materials/Red.mat"
|
|
30
|
+
"""
|
|
31
|
+
config = get_config()
|
|
32
|
+
|
|
33
|
+
result = run_command("manage_material", {
|
|
34
|
+
"action": "get_material_info",
|
|
35
|
+
"materialPath": path,
|
|
36
|
+
}, config)
|
|
37
|
+
click.echo(format_output(result, config.format))
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@material.command("create")
|
|
41
|
+
@click.argument("path")
|
|
42
|
+
@click.option(
|
|
43
|
+
"--shader", "-s",
|
|
44
|
+
default="Standard",
|
|
45
|
+
help="Shader to use (default: Standard)."
|
|
46
|
+
)
|
|
47
|
+
@click.option(
|
|
48
|
+
"--properties", "-p",
|
|
49
|
+
default=None,
|
|
50
|
+
help='Initial properties as JSON.'
|
|
51
|
+
)
|
|
52
|
+
@handle_unity_errors
|
|
53
|
+
def create(path: str, shader: str, properties: Optional[str]):
|
|
54
|
+
"""Create a new material.
|
|
55
|
+
|
|
56
|
+
\b
|
|
57
|
+
Examples:
|
|
58
|
+
unity-mcp material create "Assets/Materials/NewMat.mat"
|
|
59
|
+
unity-mcp material create "Assets/Materials/Red.mat" --shader "Universal Render Pipeline/Lit"
|
|
60
|
+
unity-mcp material create "Assets/Materials/Blue.mat" --properties '{"_Color": [0,0,1,1]}'
|
|
61
|
+
"""
|
|
62
|
+
config = get_config()
|
|
63
|
+
|
|
64
|
+
params: dict[str, Any] = {
|
|
65
|
+
"action": "create",
|
|
66
|
+
"materialPath": path,
|
|
67
|
+
"shader": shader,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if properties:
|
|
71
|
+
params["properties"] = parse_json_dict_or_exit(properties, "properties")
|
|
72
|
+
|
|
73
|
+
result = run_command("manage_material", params, config)
|
|
74
|
+
click.echo(format_output(result, config.format))
|
|
75
|
+
if result.get("success"):
|
|
76
|
+
print_success(f"Created material: {path}")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@material.command("set-color")
|
|
80
|
+
@click.argument("path")
|
|
81
|
+
@click.argument("r", type=float)
|
|
82
|
+
@click.argument("g", type=float)
|
|
83
|
+
@click.argument("b", type=float)
|
|
84
|
+
@click.argument("a", type=float, default=1.0)
|
|
85
|
+
@click.option(
|
|
86
|
+
"--property", "-p",
|
|
87
|
+
default="_Color",
|
|
88
|
+
help="Color property name (default: _Color)."
|
|
89
|
+
)
|
|
90
|
+
@handle_unity_errors
|
|
91
|
+
def set_color(path: str, r: float, g: float, b: float, a: float, property: str):
|
|
92
|
+
"""Set a material's color.
|
|
93
|
+
|
|
94
|
+
\b
|
|
95
|
+
Examples:
|
|
96
|
+
unity-mcp material set-color "Assets/Materials/Red.mat" 1 0 0
|
|
97
|
+
unity-mcp material set-color "Assets/Materials/Blue.mat" 0 0 1 0.5
|
|
98
|
+
unity-mcp material set-color "Assets/Materials/Mat.mat" 1 1 0 --property "_BaseColor"
|
|
99
|
+
"""
|
|
100
|
+
config = get_config()
|
|
101
|
+
|
|
102
|
+
params: dict[str, Any] = {
|
|
103
|
+
"action": "set_material_color",
|
|
104
|
+
"materialPath": path,
|
|
105
|
+
"property": property,
|
|
106
|
+
"color": [r, g, b, a],
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
result = run_command("manage_material", params, config)
|
|
110
|
+
click.echo(format_output(result, config.format))
|
|
111
|
+
if result.get("success"):
|
|
112
|
+
print_success(f"Set color on: {path}")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@material.command("set-property")
|
|
116
|
+
@click.argument("path")
|
|
117
|
+
@click.argument("property_name")
|
|
118
|
+
@click.argument("value")
|
|
119
|
+
@handle_unity_errors
|
|
120
|
+
def set_property(path: str, property_name: str, value: str):
|
|
121
|
+
"""Set a shader property on a material.
|
|
122
|
+
|
|
123
|
+
\b
|
|
124
|
+
Examples:
|
|
125
|
+
unity-mcp material set-property "Assets/Materials/Mat.mat" _Metallic 0.5
|
|
126
|
+
unity-mcp material set-property "Assets/Materials/Mat.mat" _Smoothness 0.8
|
|
127
|
+
unity-mcp material set-property "Assets/Materials/Mat.mat" _MainTex "Assets/Textures/Tex.png"
|
|
128
|
+
"""
|
|
129
|
+
config = get_config()
|
|
130
|
+
|
|
131
|
+
# Try to parse value as JSON for complex types
|
|
132
|
+
parsed_value = parse_value_safe(value)
|
|
133
|
+
|
|
134
|
+
params: dict[str, Any] = {
|
|
135
|
+
"action": "set_material_shader_property",
|
|
136
|
+
"materialPath": path,
|
|
137
|
+
"property": property_name,
|
|
138
|
+
"value": parsed_value,
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
result = run_command("manage_material", params, config)
|
|
142
|
+
click.echo(format_output(result, config.format))
|
|
143
|
+
if result.get("success"):
|
|
144
|
+
print_success(f"Set {property_name} on: {path}")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@material.command("assign")
|
|
148
|
+
@click.argument("material_path")
|
|
149
|
+
@click.argument("target")
|
|
150
|
+
@click.option(
|
|
151
|
+
"--search-method",
|
|
152
|
+
type=SEARCH_METHOD_CHOICE_RENDERER,
|
|
153
|
+
default=None,
|
|
154
|
+
help="How to find the target GameObject."
|
|
155
|
+
)
|
|
156
|
+
@click.option(
|
|
157
|
+
"--slot", "-s",
|
|
158
|
+
default=0,
|
|
159
|
+
type=int,
|
|
160
|
+
help="Material slot index (default: 0)."
|
|
161
|
+
)
|
|
162
|
+
@click.option(
|
|
163
|
+
"--mode", "-m",
|
|
164
|
+
type=click.Choice(["shared", "instance", "property_block"]),
|
|
165
|
+
default="shared",
|
|
166
|
+
help="Assignment mode."
|
|
167
|
+
)
|
|
168
|
+
@handle_unity_errors
|
|
169
|
+
def assign(material_path: str, target: str, search_method: Optional[str], slot: int, mode: str):
|
|
170
|
+
"""Assign a material to a GameObject's renderer.
|
|
171
|
+
|
|
172
|
+
\b
|
|
173
|
+
Examples:
|
|
174
|
+
unity-mcp material assign "Assets/Materials/Red.mat" "Cube"
|
|
175
|
+
unity-mcp material assign "Assets/Materials/Blue.mat" "Player" --mode instance
|
|
176
|
+
unity-mcp material assign "Assets/Materials/Mat.mat" "-81840" --search-method by_id --slot 1
|
|
177
|
+
"""
|
|
178
|
+
config = get_config()
|
|
179
|
+
|
|
180
|
+
params: dict[str, Any] = {
|
|
181
|
+
"action": "assign_material_to_renderer",
|
|
182
|
+
"materialPath": material_path,
|
|
183
|
+
"target": target,
|
|
184
|
+
"slot": slot,
|
|
185
|
+
"mode": mode,
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if search_method:
|
|
189
|
+
params["searchMethod"] = search_method
|
|
190
|
+
|
|
191
|
+
result = run_command("manage_material", params, config)
|
|
192
|
+
click.echo(format_output(result, config.format))
|
|
193
|
+
if result.get("success"):
|
|
194
|
+
print_success(f"Assigned material to: {target}")
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
@material.command("set-renderer-color")
|
|
198
|
+
@click.argument("target")
|
|
199
|
+
@click.argument("r", type=float)
|
|
200
|
+
@click.argument("g", type=float)
|
|
201
|
+
@click.argument("b", type=float)
|
|
202
|
+
@click.argument("a", type=float, default=1.0)
|
|
203
|
+
@click.option(
|
|
204
|
+
"--search-method",
|
|
205
|
+
type=SEARCH_METHOD_CHOICE_RENDERER,
|
|
206
|
+
default=None,
|
|
207
|
+
help="How to find the target GameObject."
|
|
208
|
+
)
|
|
209
|
+
@click.option(
|
|
210
|
+
"--mode", "-m",
|
|
211
|
+
type=click.Choice(["shared", "instance", "property_block"]),
|
|
212
|
+
default="property_block",
|
|
213
|
+
help="Modification mode."
|
|
214
|
+
)
|
|
215
|
+
@handle_unity_errors
|
|
216
|
+
def set_renderer_color(target: str, r: float, g: float, b: float, a: float, search_method: Optional[str], mode: str):
|
|
217
|
+
"""Set a renderer's material color directly.
|
|
218
|
+
|
|
219
|
+
\b
|
|
220
|
+
Examples:
|
|
221
|
+
unity-mcp material set-renderer-color "Cube" 1 0 0
|
|
222
|
+
unity-mcp material set-renderer-color "Player" 0 1 0 --mode instance
|
|
223
|
+
"""
|
|
224
|
+
config = get_config()
|
|
225
|
+
|
|
226
|
+
params: dict[str, Any] = {
|
|
227
|
+
"action": "set_renderer_color",
|
|
228
|
+
"target": target,
|
|
229
|
+
"color": [r, g, b, a],
|
|
230
|
+
"mode": mode,
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if search_method:
|
|
234
|
+
params["searchMethod"] = search_method
|
|
235
|
+
|
|
236
|
+
result = run_command("manage_material", params, config)
|
|
237
|
+
click.echo(format_output(result, config.format))
|
|
238
|
+
if result.get("success"):
|
|
239
|
+
print_success(f"Set renderer color on: {target}")
|
cli/commands/prefab.py
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""Prefab CLI commands."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import click
|
|
5
|
+
from typing import Optional, Any
|
|
6
|
+
|
|
7
|
+
from cli.utils.config import get_config
|
|
8
|
+
from cli.utils.output import format_output, print_error, print_success
|
|
9
|
+
from cli.utils.connection import run_command, handle_unity_errors
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@click.group()
|
|
13
|
+
def prefab():
|
|
14
|
+
"""Prefab operations - info, hierarchy, open, save, close, create prefabs."""
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@prefab.command("open")
|
|
19
|
+
@click.argument("path")
|
|
20
|
+
@handle_unity_errors
|
|
21
|
+
def open_stage(path: str):
|
|
22
|
+
"""Open a prefab in the prefab stage for editing.
|
|
23
|
+
|
|
24
|
+
\b
|
|
25
|
+
Examples:
|
|
26
|
+
unity-mcp prefab open "Assets/Prefabs/Player.prefab"
|
|
27
|
+
"""
|
|
28
|
+
config = get_config()
|
|
29
|
+
|
|
30
|
+
params: dict[str, Any] = {
|
|
31
|
+
"action": "open_stage",
|
|
32
|
+
"prefabPath": path,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
result = run_command("manage_prefabs", params, config)
|
|
36
|
+
click.echo(format_output(result, config.format))
|
|
37
|
+
if result.get("success"):
|
|
38
|
+
print_success(f"Opened prefab: {path}")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@prefab.command("close")
|
|
42
|
+
@click.option(
|
|
43
|
+
"--save", "-s",
|
|
44
|
+
is_flag=True,
|
|
45
|
+
help="Save the prefab before closing."
|
|
46
|
+
)
|
|
47
|
+
@handle_unity_errors
|
|
48
|
+
def close_stage(save: bool):
|
|
49
|
+
"""Close the current prefab stage.
|
|
50
|
+
|
|
51
|
+
\b
|
|
52
|
+
Examples:
|
|
53
|
+
unity-mcp prefab close
|
|
54
|
+
unity-mcp prefab close --save
|
|
55
|
+
"""
|
|
56
|
+
config = get_config()
|
|
57
|
+
|
|
58
|
+
params: dict[str, Any] = {
|
|
59
|
+
"action": "close_stage",
|
|
60
|
+
}
|
|
61
|
+
if save:
|
|
62
|
+
params["saveBeforeClose"] = True
|
|
63
|
+
|
|
64
|
+
result = run_command("manage_prefabs", params, config)
|
|
65
|
+
click.echo(format_output(result, config.format))
|
|
66
|
+
if result.get("success"):
|
|
67
|
+
print_success("Closed prefab stage")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@prefab.command("save")
|
|
71
|
+
@click.option(
|
|
72
|
+
"--force", "-f",
|
|
73
|
+
is_flag=True,
|
|
74
|
+
help="Force save even if no changes detected. Useful for automated workflows."
|
|
75
|
+
)
|
|
76
|
+
@handle_unity_errors
|
|
77
|
+
def save_stage(force: bool):
|
|
78
|
+
"""Save the currently open prefab stage.
|
|
79
|
+
|
|
80
|
+
\b
|
|
81
|
+
Examples:
|
|
82
|
+
unity-mcp prefab save
|
|
83
|
+
unity-mcp prefab save --force
|
|
84
|
+
"""
|
|
85
|
+
config = get_config()
|
|
86
|
+
|
|
87
|
+
params: dict[str, Any] = {
|
|
88
|
+
"action": "save_open_stage",
|
|
89
|
+
}
|
|
90
|
+
if force:
|
|
91
|
+
params["force"] = True
|
|
92
|
+
|
|
93
|
+
result = run_command("manage_prefabs", params, config)
|
|
94
|
+
click.echo(format_output(result, config.format))
|
|
95
|
+
if result.get("success"):
|
|
96
|
+
print_success("Saved prefab")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@prefab.command("info")
|
|
100
|
+
@click.argument("path")
|
|
101
|
+
@click.option(
|
|
102
|
+
"--compact", "-c",
|
|
103
|
+
is_flag=True,
|
|
104
|
+
help="Show compact output (key values only)."
|
|
105
|
+
)
|
|
106
|
+
@handle_unity_errors
|
|
107
|
+
def info(path: str, compact: bool):
|
|
108
|
+
"""Get information about a prefab asset.
|
|
109
|
+
|
|
110
|
+
\b
|
|
111
|
+
Examples:
|
|
112
|
+
unity-mcp prefab info "Assets/Prefabs/Player.prefab"
|
|
113
|
+
unity-mcp prefab info "Assets/Prefabs/UI.prefab" --compact
|
|
114
|
+
"""
|
|
115
|
+
config = get_config()
|
|
116
|
+
|
|
117
|
+
params: dict[str, Any] = {
|
|
118
|
+
"action": "get_info",
|
|
119
|
+
"prefabPath": path,
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
result = run_command("manage_prefabs", params, config)
|
|
123
|
+
# Get the actual response data from the wrapped result structure
|
|
124
|
+
response_data = result.get("result", result)
|
|
125
|
+
if compact and response_data.get("success") and response_data.get("data"):
|
|
126
|
+
data = response_data["data"]
|
|
127
|
+
click.echo(f"Prefab: {data.get('assetPath', path)}")
|
|
128
|
+
click.echo(f" Type: {data.get('prefabType', 'Unknown')}")
|
|
129
|
+
click.echo(f" Root: {data.get('rootObjectName', 'N/A')}")
|
|
130
|
+
click.echo(f" GUID: {data.get('guid', 'N/A')}")
|
|
131
|
+
click.echo(
|
|
132
|
+
f" Components: {len(data.get('rootComponentTypes', []))}")
|
|
133
|
+
click.echo(f" Children: {data.get('childCount', 0)}")
|
|
134
|
+
if data.get('isVariant'):
|
|
135
|
+
click.echo(f" Variant of: {data.get('parentPrefab', 'N/A')}")
|
|
136
|
+
else:
|
|
137
|
+
click.echo(format_output(result, config.format))
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@prefab.command("hierarchy")
|
|
141
|
+
@click.argument("path")
|
|
142
|
+
@click.option(
|
|
143
|
+
"--compact", "-c",
|
|
144
|
+
is_flag=True,
|
|
145
|
+
help="Show compact output (names and paths only)."
|
|
146
|
+
)
|
|
147
|
+
@click.option(
|
|
148
|
+
"--show-prefab-info", "-p",
|
|
149
|
+
is_flag=True,
|
|
150
|
+
help="Show prefab nesting information."
|
|
151
|
+
)
|
|
152
|
+
@handle_unity_errors
|
|
153
|
+
def hierarchy(path: str, compact: bool, show_prefab_info: bool):
|
|
154
|
+
"""Get the hierarchical structure of a prefab.
|
|
155
|
+
|
|
156
|
+
\b
|
|
157
|
+
Examples:
|
|
158
|
+
unity-mcp prefab hierarchy "Assets/Prefabs/Player.prefab"
|
|
159
|
+
unity-mcp prefab hierarchy "Assets/Prefabs/UI.prefab" --compact
|
|
160
|
+
unity-mcp prefab hierarchy "Assets/Prefabs/Complex.prefab" --show-prefab-info
|
|
161
|
+
"""
|
|
162
|
+
config = get_config()
|
|
163
|
+
|
|
164
|
+
params: dict[str, Any] = {
|
|
165
|
+
"action": "get_hierarchy",
|
|
166
|
+
"prefabPath": path,
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
result = run_command("manage_prefabs", params, config)
|
|
170
|
+
# Get the actual response data from the wrapped result structure
|
|
171
|
+
response_data = result.get("result", result)
|
|
172
|
+
if compact and response_data.get("success") and response_data.get("data"):
|
|
173
|
+
data = response_data["data"]
|
|
174
|
+
items = data.get("items", [])
|
|
175
|
+
for item in items:
|
|
176
|
+
indent = " " * item.get("path", "").count("/")
|
|
177
|
+
prefab_info = ""
|
|
178
|
+
if show_prefab_info and item.get("prefab", {}).get("isNestedRoot"):
|
|
179
|
+
prefab_info = f" [nested: {item['prefab']['assetPath']}]"
|
|
180
|
+
click.echo(f"{indent}{item.get('name')}{prefab_info}")
|
|
181
|
+
click.echo(f"\nTotal: {data.get('total', 0)} objects")
|
|
182
|
+
elif show_prefab_info:
|
|
183
|
+
# Show prefab info in readable format
|
|
184
|
+
if response_data.get("success") and response_data.get("data"):
|
|
185
|
+
data = response_data["data"]
|
|
186
|
+
items = data.get("items", [])
|
|
187
|
+
for item in items:
|
|
188
|
+
prefab = item.get("prefab", {})
|
|
189
|
+
prefab_info = ""
|
|
190
|
+
if prefab.get("isRoot"):
|
|
191
|
+
prefab_info = " [root]"
|
|
192
|
+
elif prefab.get("isNestedRoot"):
|
|
193
|
+
prefab_info = f" [nested: {prefab.get('nestingDepth', 0)}]"
|
|
194
|
+
click.echo(f"{item.get('path')}{prefab_info}")
|
|
195
|
+
click.echo(f"\nTotal: {data.get('total', 0)} objects")
|
|
196
|
+
else:
|
|
197
|
+
click.echo(format_output(result, config.format))
|
|
198
|
+
else:
|
|
199
|
+
click.echo(format_output(result, config.format))
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@prefab.command("create")
|
|
203
|
+
@click.argument("target")
|
|
204
|
+
@click.argument("path")
|
|
205
|
+
@click.option(
|
|
206
|
+
"--overwrite",
|
|
207
|
+
is_flag=True,
|
|
208
|
+
help="Overwrite existing prefab at path."
|
|
209
|
+
)
|
|
210
|
+
@click.option(
|
|
211
|
+
"--include-inactive",
|
|
212
|
+
is_flag=True,
|
|
213
|
+
help="Include inactive objects when finding target."
|
|
214
|
+
)
|
|
215
|
+
@click.option(
|
|
216
|
+
"--unlink-if-instance",
|
|
217
|
+
is_flag=True,
|
|
218
|
+
help="Unlink from existing prefab before creating new one."
|
|
219
|
+
)
|
|
220
|
+
@handle_unity_errors
|
|
221
|
+
def create(target: str, path: str, overwrite: bool, include_inactive: bool, unlink_if_instance: bool):
|
|
222
|
+
"""Create a prefab from a scene GameObject.
|
|
223
|
+
|
|
224
|
+
\b
|
|
225
|
+
Examples:
|
|
226
|
+
unity-mcp prefab create "Player" "Assets/Prefabs/Player.prefab"
|
|
227
|
+
unity-mcp prefab create "Enemy" "Assets/Prefabs/Enemy.prefab" --overwrite
|
|
228
|
+
unity-mcp prefab create "EnemyInstance" "Assets/Prefabs/BossEnemy.prefab" --unlink-if-instance
|
|
229
|
+
"""
|
|
230
|
+
config = get_config()
|
|
231
|
+
|
|
232
|
+
params: dict[str, Any] = {
|
|
233
|
+
"action": "create_from_gameobject",
|
|
234
|
+
"target": target,
|
|
235
|
+
"prefabPath": path,
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if overwrite:
|
|
239
|
+
params["allowOverwrite"] = True
|
|
240
|
+
if include_inactive:
|
|
241
|
+
params["searchInactive"] = True
|
|
242
|
+
if unlink_if_instance:
|
|
243
|
+
params["unlinkIfInstance"] = True
|
|
244
|
+
|
|
245
|
+
result = run_command("manage_prefabs", params, config)
|
|
246
|
+
click.echo(format_output(result, config.format))
|
|
247
|
+
if result.get("success"):
|
|
248
|
+
print_success(f"Created prefab: {path}")
|