Skip to content

Conversation

@dsarno
Copy link
Collaborator

@dsarno dsarno commented Jan 29, 2026

Summary

  • Adds create_child parameter to manage_prefabs modify_contents action
  • Enables adding child GameObjects to existing prefabs via headless editing
  • Supports single object or array for efficient batch creation (one load/save cycle)

Features

  • Create empty GameObjects (omit primitive_type) or primitives (Cube, Sphere, Capsule, Cylinder, Plane, Quad)
  • Set transform properties (position, rotation, scale) on new children
  • Add components to children via components_to_add
  • Specify parent within prefab hierarchy for nested children
  • Set tag, layer, and active state

Example Usage

# Empty GameObject (no primitive_type)
create_child={"name": "EmptyParent", "position": [0,0,0]}

# Single child with primitive
create_child={"name": "Child1", "primitive_type": "Sphere", "position": [1,0,0]}

# Batch creation (array)
create_child=[
    {"name": "Child1", "primitive_type": "Sphere", "position": [1,0,0]},
    {"name": "Child2", "primitive_type": "Cube", "parent": "Child1"}
]

Test plan

  • Python tests pass (502)
  • Unity EditMode tests pass (508 passed, 44 skipped)
  • Unity PlayMode tests pass (5 passed)
  • Added 5 new unit tests for create_child functionality:
    • Single child with primitive type
    • Empty GameObject creation
    • Multiple children from array (batch)
    • Nested parenting within prefab
    • Error handling for invalid inputs

🤖 Generated with Claude Code

Enables adding child GameObjects to existing prefabs via headless editing.
Supports single object or array for batch creation in one save operation.

Features:
- Create children with primitive types (Cube, Sphere, etc.)
- Set position, rotation, scale on new children
- Add components to children
- Specify parent within prefab hierarchy for nested children
- Set tag, layer, and active state

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jan 29, 2026

Reviewer's Guide

Adds a new create_child parameter to the manage_prefabs modify_contents flow, wiring Python-side request handling through to Unity editor code to create one or more child GameObjects in a prefab with configurable transform, components, and metadata.

Sequence diagram for manage_prefabs modify_contents with create_child

sequenceDiagram
    actor User
    participant PythonTool as manage_prefabs
    participant UnityBridge as send_with_unity_instance
    participant UnityEditor as ManagePrefabs_Editor
    participant PrefabRoot as prefabRoot

    User->>PythonTool: Call manage_prefabs(action=modify_contents, create_child)
    PythonTool->>PythonTool: Normalize create_child (position, rotation, scale)
    PythonTool->>UnityBridge: params including createChild
    UnityBridge->>UnityEditor: ApplyModificationsToPrefabObject(params, targetGo, prefabRoot)

    UnityEditor->>UnityEditor: Read createChild from params
    alt createChild is array
        loop For each childToken in createChild
            UnityEditor->>UnityEditor: CreateSingleChildInPrefab(childToken, targetGo, prefabRoot)
            alt ErrorResponse returned
                UnityEditor-->>UnityBridge: error (success false)
                UnityBridge-->>PythonTool: error
                PythonTool-->>User: Failure response
            else Child created
                UnityEditor->>PrefabRoot: Add new child GameObject
            end
        end
    else createChild is single object
        UnityEditor->>UnityEditor: CreateSingleChildInPrefab(createChild, targetGo, prefabRoot)
        alt ErrorResponse returned
            UnityEditor-->>UnityBridge: error (success false)
            UnityBridge-->>PythonTool: error
            PythonTool-->>User: Failure response
        else Child created
            UnityEditor->>PrefabRoot: Add new child GameObject
        end
    end

    UnityEditor-->>UnityBridge: modified true, no error
    UnityBridge-->>PythonTool: Success response
    PythonTool-->>User: Success (children created in prefab)
Loading

Class diagram for Unity ManagePrefabs create_child implementation

classDiagram
    class ManagePrefabs
    ManagePrefabs : +static ApplyModificationsToPrefabObject(JObject @params, GameObject targetGo, GameObject prefabRoot) bool ErrorResponse
    ManagePrefabs : -static CreateSingleChildInPrefab(JToken createChildToken, GameObject defaultParent, GameObject prefabRoot) bool ErrorResponse
    ManagePrefabs : -static FindInPrefabContents(GameObject prefabRoot, string name) GameObject

    class ErrorResponse
    ErrorResponse : +string message
    ErrorResponse : +ErrorResponse(string message)

    class GameObject
    GameObject : +string name
    GameObject : +Transform transform
    GameObject : +int layer
    GameObject : +string tag
    GameObject : +void SetActive(bool value)
    GameObject : +static GameObject CreatePrimitive(PrimitiveType type)

    class Transform
    Transform : +Vector3 localPosition
    Transform : +Vector3 localEulerAngles
    Transform : +Vector3 localScale
    Transform : +Transform parent
    Transform : +void SetParent(Transform parent, bool worldPositionStays)

    class VectorParsing
    VectorParsing : +static Vector3~nullable~ ParseVector3(JToken token)

    class ComponentResolver
    ComponentResolver : +static bool TryResolve(string typeName, Type componentType, string error)

    class McpLog
    McpLog : +static void Info(string message)
    McpLog : +static void Warn(string message)

    class LayerMask
    LayerMask : +static int NameToLayer(string layerName)

    class PrimitiveType

    ManagePrefabs --> ErrorResponse
    ManagePrefabs --> GameObject
    ManagePrefabs --> Transform
    ManagePrefabs --> VectorParsing
    ManagePrefabs --> ComponentResolver
    ManagePrefabs --> McpLog
    ManagePrefabs --> LayerMask
    GameObject --> Transform
    GameObject --> PrimitiveType
Loading

File-Level Changes

Change Details Files
Support create_child in Unity ManagePrefabs modify_contents to create child GameObjects inside prefab contents.
  • Read createChild/create_child from params and handle both single object and array forms within ApplyModificationsToPrefabObject.
  • For each requested child, delegate to a new helper that validates input, selects the parent transform (defaulting to target object or an explicitly named parent in the prefab), and creates either a primitive or empty GameObject.
  • Apply optional transform (position, rotation, scale), tag, layer, and active state to the new child GameObject.
  • Add optional component creation through ComponentResolver; on resolution failure, destroy the partially created child and return an error.
  • Log successes and warn on invalid tag/layer while keeping the prefab modification flow consistent with existing error reporting.
MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
Expose create_child parameter in Python manage_prefabs tool and translate it into Unity parameters including vector normalization.
  • Extend manage_prefabs documentation string to describe create_child usage and provide an inline example.
  • Add create_child parameter to the manage_prefabs function signature with a detailed annotation describing supported fields and usage for single or batch creation.
  • When action is modify_contents and create_child is provided, normalize position/rotation/scale for each child (handling single dict or list of dicts) using normalize_vector3 with contextual error prefixes.
  • On normalization error, short‑circuit and return a failure response; otherwise, emit a createChild payload matching the Unity side expectations.
Server/src/services/tools/manage_prefabs.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 29, 2026

📝 Walkthrough

Walkthrough

Adds headless prefab child-creation: the Python service accepts and normalizes a new create_child parameter and forwards it to Unity; the C# editor implements child GameObject creation, transform application, component attachment, tag/layer setting, and error handling during prefab modification.

Changes

Cohort / File(s) Summary
C# Editor Prefab Creation
MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
Introduces CreateSingleChildInPrefab helper and integrates a createChild workflow into ApplyModificationsToPrefabObject. Creates primitives or GameObjects, applies position/rotation/scale, attaches components with cleanup on failure, sets tag/layer with validation, and applies active state.
Python Server Parameter Handling
Server/src/services/tools/manage_prefabs.py
Adds create_child parameter to manage_prefabs, accepts a dict or list of dicts, validates/normalizes vector fields (position, rotation, scale), converts input to params.createChild, and returns errors on malformed vectors before sending command to Unity.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant PythonServer as Python Server
    participant UnityEditor as C# Editor
    participant Prefab as Prefab Asset

    Client->>PythonServer: manage_prefabs(create_child=[...])
    PythonServer->>PythonServer: Validate & normalize vectors
    PythonServer->>UnityEditor: Send command with params.createChild
    UnityEditor->>UnityEditor: ApplyModificationsToPrefabObject()
    loop For each child in params.createChild
        UnityEditor->>UnityEditor: Resolve parent GameObject
        UnityEditor->>UnityEditor: Create GameObject / primitive
        UnityEditor->>UnityEditor: Apply position/rotation/scale
        UnityEditor->>UnityEditor: Attach components (cleanup on failure)
        UnityEditor->>UnityEditor: Set tag & layer
        UnityEditor->>UnityEditor: Set active state
    end
    UnityEditor->>Prefab: Persist changes
    UnityEditor->>PythonServer: Return success response
    PythonServer->>Client: Return result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 In a prefab field I gently leap,

I plant small children, soft and neat.
Transforms set, components cling,
Tags and layers make them sing—
A tiny forest sprung complete. 🌱

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a create_child parameter to manage_prefabs modify_contents, which directly aligns with the primary objective of enabling child GameObject creation in prefabs.
Description check ✅ Passed The pull request description covers all required template sections with comprehensive details about the feature, examples, and test results.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • In normalize_child_params the return type is annotated as tuple[dict, str | None] but the function can return (None, err) on failure; consider either adjusting the type hint to allow dict | None or returning an empty dict to keep the annotation accurate.
  • In normalize_child_params, child_params = dict(child) assumes child is a mapping and will raise a generic error for bad input; it may be more robust to explicitly check that each child is a dict and return a clear error message if not.
  • When iterating componentsToAdd in CreateSingleChildInPrefab, non-string tokens that are not objects with a typeName field are silently ignored; consider either validating and erroring on unexpected shapes or logging a warning so mis-specified component entries are easier to detect.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `normalize_child_params` the return type is annotated as `tuple[dict, str | None]` but the function can return `(None, err)` on failure; consider either adjusting the type hint to allow `dict | None` or returning an empty dict to keep the annotation accurate.
- In `normalize_child_params`, `child_params = dict(child)` assumes `child` is a mapping and will raise a generic error for bad input; it may be more robust to explicitly check that each `child` is a dict and return a clear error message if not.
- When iterating `componentsToAdd` in `CreateSingleChildInPrefab`, non-string tokens that are not objects with a `typeName` field are silently ignored; consider either validating and erroring on unexpected shapes or logging a warning so mis-specified component entries are easier to detect.

## Individual Comments

### Comment 1
<location> `Server/src/services/tools/manage_prefabs.py:164-168` </location>
<code_context>
+                        child_params[vec_field] = vec_val
+                return child_params, None
+
+            if isinstance(create_child, list):
+                # Array of children
+                normalized_children = []
+                for i, child in enumerate(create_child):
+                    child_params, err = normalize_child_params(child, i)
+                    if err:
+                        return {"success": False, "message": err}
</code_context>

<issue_to_address>
**issue (bug_risk):** Add validation or clearer error handling when list elements in `create_child` are not dictionaries.

In the list branch, `normalize_child_params` assumes each `child` is dict-like and does `child_params = dict(child)`. If a non-dict is passed (e.g. string, list), this may raise or behave unexpectedly. Consider explicitly checking `isinstance(child, dict)` and returning a clear error (including the index and expected structure) when the input is invalid.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs`:
- Around line 864-891: The child tag/layer assignment in ManagePrefabs.cs
currently only logs warnings (references: childParams, childName, newChild.tag
assignment and LayerMask.NameToLayer), causing silent successes when invalid
values are provided; change this to match the main target behavior by returning
an ErrorResponse on invalid tag or invalid layer for children (instead of only
McpLog.Warn), i.e., validate the tag and layer the same way the main target does
and propagate an error response back to the caller when validation fails so the
overall operation fails consistently.

dsarno and others added 2 commits January 29, 2026 04:09
- Fix type hint to `tuple[dict | None, str | None]` to match actual returns
- Add explicit dict validation with clear error message including actual type
- Error on invalid component entries instead of silently ignoring them
- Return ErrorResponse for invalid tag/layer instead of just logging warnings

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests cover:
- Single child with primitive type
- Empty GameObject (no primitive_type)
- Multiple children from array (batch creation)
- Nested parenting within prefab
- Error handling for invalid inputs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dsarno dsarno merged commit 62c015d into CoplayDev:beta Jan 29, 2026
2 checks passed
@dsarno dsarno deleted the feature/prefab-create-child branch January 29, 2026 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant