Skip to content

Commit 866dcec

Browse files
committed
fix(cli): send an [x,y,z] --view-target to Unity as a position
manage_camera reads viewTarget as a GameObject reference, or as a position when it is a JSON array. The CLI sent the option as text, so "[0, 1, 2]" reached Unity as a GameObject name, although the help offered [x,y,z]. A value that starts with "[" is now parsed as a JSON array, for both screenshot and screenshot-multiview, and the guide no longer says a position needs `raw`.
1 parent 6b454b5 commit 866dcec

3 files changed

Lines changed: 17 additions & 6 deletions

File tree

‎Server/src/cli/commands/camera.py‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from cli.utils.config import get_config
77
from cli.utils.output import format_output, print_error, print_success
88
from cli.utils.connection import run_command, handle_unity_errors
9-
from cli.utils.parsers import parse_json_dict_or_exit
9+
from cli.utils.parsers import parse_json_dict_or_exit, parse_json_list_or_exit
1010
from cli.utils.constants import SEARCH_METHOD_CHOICE_BASIC
1111

1212

@@ -519,8 +519,11 @@ def screenshot(camera_ref, file_name, super_size, include_image, max_resolution,
519519
params["captureSource"] = capture_source
520520
if batch:
521521
params["batch"] = batch
522+
# Unity reads a JSON array as a position and any other value as a GameObject; the
523+
# option arrives as text, so "[x,y,z]" is parsed to reach Unity as an array.
522524
if view_target:
523-
params["viewTarget"] = view_target
525+
params["viewTarget"] = (parse_json_list_or_exit(view_target, "view-target")
526+
if view_target.lstrip().startswith("[") else view_target)
524527
if output_folder:
525528
params["outputFolder"] = output_folder
526529
result = run_command("manage_camera", params, config)
@@ -529,7 +532,7 @@ def screenshot(camera_ref, file_name, super_size, include_image, max_resolution,
529532

530533
@camera.command("screenshot-multiview")
531534
@click.option("--max-resolution", type=int, default=None, help="Max resolution per tile.")
532-
@click.option("--view-target", default=None, help="Center target for the multiview capture.")
535+
@click.option("--view-target", default=None, help="Center target: GameObject name/path/ID or [x,y,z].")
533536
@click.option("--output-folder", default=None,
534537
help="Output folder, project-relative or absolute inside the project. "
535538
"Overrides Editor preference; falls back to Assets/Screenshots when unset.")
@@ -547,7 +550,8 @@ def screenshot_multiview(max_resolution, view_target, output_folder):
547550
if max_resolution is not None:
548551
params["maxResolution"] = max_resolution
549552
if view_target:
550-
params["viewTarget"] = view_target
553+
params["viewTarget"] = (parse_json_list_or_exit(view_target, "view-target")
554+
if view_target.lstrip().startswith("[") else view_target)
551555
if output_folder:
552556
params["outputFolder"] = output_folder
553557
result = run_command("manage_camera", params, config)

‎Server/tests/test_cli.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,13 @@ def test_camera_screenshot_scene_view(self, runner, mock_unity_response):
476476
assert params["viewTarget"] == "Canvas"
477477
assert params["includeImage"] is True
478478

479+
def test_camera_screenshot_position_view_target_reaches_unity_as_an_array(self, runner, mock_unity_response):
480+
# Unity reads a JSON array as a position; the text "[0, 1, 2]" would be looked up as a GameObject name.
481+
with patch("cli.commands.camera.run_command", return_value=mock_unity_response) as mock_run:
482+
result = runner.invoke(cli, ["camera", "screenshot", "--view-target", "[0, 1, 2]"])
483+
assert result.exit_code == 0, result.output
484+
assert mock_run.call_args[0][1]["viewTarget"] == [0, 1, 2]
485+
479486
def test_camera_ping_prints_output(self, runner, mock_unity_response):
480487
"""The camera group must actually emit its result.
481488

‎website/docs/guides/cli.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,10 +392,10 @@ unity-mcp camera screenshot-multiview --view-target "Player" --max-resolution 48
392392
| `--max-resolution` | int | Longest edge of the inline image in pixels (default 640; 480 per tile with `--batch`) |
393393
| `--capture-source` | string | `game_view` (default) or `scene_view` (editor viewport) |
394394
| `--batch` | string | `surround` (6 angles) or `orbit` (grid around the target) |
395-
| `--view-target` | string | GameObject name/path/ID. Aims the camera (game_view) or frames the Scene View (scene_view) |
395+
| `--view-target` | string | GameObject name/path/ID, or a `[x,y,z]` position. Aims the camera (game_view) or frames the Scene View (scene_view) |
396396
| `--output-folder` | string | Save folder, project-relative or absolute inside the project (default: Editor preference, then `Assets/Screenshots`) |
397397

398-
`camera screenshot-multiview` takes `--max-resolution`, `--view-target` and `--output-folder`. `--view-target` is sent as a string, so it cannot carry a `[x,y,z]` position; that, and the MCP tool's `view_position`, `view_rotation` and `orbit_*` settings, need `unity-mcp raw manage_camera '{"action": "screenshot", ...}'`.
398+
`camera screenshot-multiview` takes `--max-resolution`, `--view-target` and `--output-folder`. The MCP tool's `view_position`, `view_rotation` and `orbit_*` settings need `unity-mcp raw manage_camera '{"action": "screenshot", ...}'`.
399399

400400
### Graphics Operations
401401

0 commit comments

Comments
 (0)