Skip to content

Prefab Management Improvements: Pagination, Batch Operations, and Property Setting#666

Open
waqasrana wants to merge 10 commits intoCoplayDev:betafrom
waqasrana:feature/prefab-management-improvements
Open

Prefab Management Improvements: Pagination, Batch Operations, and Property Setting#666
waqasrana wants to merge 10 commits intoCoplayDev:betafrom
waqasrana:feature/prefab-management-improvements

Conversation

@waqasrana
Copy link

@waqasrana waqasrana commented Feb 2, 2026

Summary

This PR enhances manage_prefabs with several new capabilities to improve AI-driven prefab workflows:

  • Pagination for get_hierarchy - Prevents excessive payloads (100k+ chars) on large prefabs with page_size, cursor, max_depth, and filter parameters. Opt-in to
    maintain backward compatibility.
  • set_property support - Set component property values directly on prefab assets (like manage_components set_property but for prefabs)
  • set_component_reference - Wire serialized field references to other objects within prefabs
  • batch_modify action - Apply multiple operations to different targets in a single prefab load/save cycle for efficiency
  • createdChildren response - Detailed feedback on created children including name, path, instanceId, isPrefabInstance, sourcePrefabPath, etc.
  • Bug fix - Fixed create_child with prefab_path creating empty GameObjects instead of nested prefab instances

Backward Compatibility

  • get_hierarchy returns all items by default (original behavior); pagination only activates when page_size or cursor is explicitly provided
  • All new parameters are optional and additive
  • Internal method signatures preserved via overloads with out parameters

Test Plan

  • Added 15 new Unity C# tests covering all new features
  • All 563 Python tests pass
  • All 37 ManagePrefabs tests pass
  • Tested batch_modify with multiple operations including components_to_add, create_child, set_property
  • Verified pagination returns correct subsets and next_cursor values
  • Verified backward compatibility: existing calls work unchanged

Commits

Commit Description
Fix manage_prefabs create_child with prefab_path Fixed nested prefab instantiation
Add set_component_reference parameter Wire serialized fields to objects
Add pagination support to get_hierarchy page_size, cursor, max_depth, filter
Add set_property support Component property values on prefabs
Add detailed feedback for create_child createdChildren response array
Clarify target parameter docs Path-based targeting documentation
Add batch_modify action Multi-operation single save cycle
Fix batch_modify snake_case fallbacks Python parameter compatibility
Make pagination opt-in Backward compatibility for get_hierarchy
Add tests for new features 15 new tests

🤖 Generated with Claude Code

Summary by Sourcery

Enhance Unity prefab management tooling with pagination and filtering for hierarchy queries, richer child creation metadata, batch modification support, and new component reference/property-setting capabilities, while updating the Python wrapper and adding extensive tests.

New Features:

  • Add optional pagination, depth limiting, and name filtering to the get_hierarchy prefab action while preserving legacy behavior when pagination is not requested.
  • Introduce a batch_modify action to apply multiple targeted prefab modifications within a single load/save cycle and return per-operation results.
  • Expose createdChildren metadata from modify_contents and batch_modify to describe newly created child objects, including hierarchy path, instance IDs, prefab instance details, and components.
  • Support creating nested prefab instances in create_child via a prefab_path parameter with corresponding source prefab metadata in responses.
  • Add set_component_reference and set_property operations to manage serialized component references and property values directly on prefab assets from the prefab management API.

Bug Fixes:

  • Fix create_child with prefab_path so it instantiates nested prefab instances instead of empty GameObjects.

Enhancements:

  • Extend prefab hierarchy items with depth and component metadata while supporting optional max_depth and filter parameters for hierarchy construction.
  • Improve modify_contents parameter handling to accept both camelCase and snake_case names for activation and component add/remove operations.
  • Document expanded manage_prefabs behavior and parameters in the Python tool wrapper, including target semantics and advanced modify/get_hierarchy options.

Tests:

  • Add comprehensive Unity edit-mode tests for pagination, depth limiting, filtering, child creation metadata, nested prefab instantiation, batch_modify behavior, and property/reference setting.

Summary by CodeRabbit

  • New Features
    • Added batch modification for prefabs—modify multiple elements in a single operation.
    • Introduced pagination and filtering for prefab hierarchies with depth-limiting controls.
    • Added support for nested prefab instantiation during child creation.
    • Enabled component reference and property setting capabilities.
    • Improved parameter flexibility with camelCase and snake_case support.

Dee-III and others added 10 commits February 2, 2026 23:24
…bject

When using manage_prefabs with create_child containing a prefab_path,
the code was ignoring the prefab_path and creating an empty GameObject
instead of a proper nested prefab instance.

Now uses PrefabUtility.InstantiatePrefab() to create nested prefab
instances that maintain their link to the source prefab.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allows wiring serialized field references on components within prefabs.
Supports referencing GameObjects or specific Components using path syntax
(e.g., 'Canvas/Button:Button'). Uses reflection to set public fields,
[SerializeField] private fields, and writable properties.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds page_size, cursor, max_depth, and filter parameters to prevent
excessive payload sizes on large prefabs. Response now includes
pagination metadata (cursor, next_cursor, truncated). Preserves
backward compatibility by keeping original BuildHierarchyItems method
as a wrapper.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… assets

Enables setting component property values on objects within prefab assets,
which was previously only possible on scene GameObjects via manage_components.
Supports single property (property+value) and multiple properties (properties
object) modes. Uses ComponentOps.SetProperty for consistent value conversion.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Response now includes createdChildren array with details about each created
object: name, path, instanceId, transformInstanceId, isPrefabInstance,
sourcePrefabGuid, sourcePrefabPath, and component info.

Uses backward-compatible overloads with out parameters to preserve existing
method signatures while adding new functionality.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated docstring to explicitly document that target accepts:
- Object name ('MyObject')
- Relative path ('Child/GrandChild')
- Full path with root ('RootName/Child/GrandChild')

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…on workflows

Adds batch_modify action that loads a prefab once, applies multiple operations
to different targets, then saves once. Each operation can specify its own target
(defaults to prefab root) and modification parameters (position, rotation, scale,
name, tag, layer, set_active, parent, components, create_child, set_property).

Returns detailed operationResults array with per-operation success/failure info.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…lbacks

ApplyModificationsToPrefabObject now accepts both camelCase and snake_case
for setActive, componentsToAdd, and componentsToRemove parameters. This
fixes batch_modify operations where Python passes snake_case keys directly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When no page_size or cursor is provided, returns all items with the
original response format. Pagination only applies when explicitly
requested. Updated parameter description to reflect this behavior.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests added for:
- batch_modify action (5 tests)
- get_hierarchy pagination with page_size, cursor, max_depth, filter (4 tests)
- set_property parameter for component property values (2 tests)
- set_component_reference parameter (1 test)
- create_child with prefab_path for nested prefab instantiation (1 test)
- createdChildren response info (1 test)
- snake_case parameter handling in batch_modify (1 test)

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

sourcery-ai bot commented Feb 2, 2026

Reviewer's Guide

Extends manage_prefabs with opt‑in, filterable pagination for get_hierarchy, adds batch_modify to apply multiple prefab edits per load/save, introduces set_property and set_component_reference operations, returns detailed metadata for created children (including nested prefab instances), fixes create_child with prefab_path, and wires all new capabilities through the Python manage_prefabs tool with snake_case/camelCase compatibility and comprehensive tests.

Sequence diagram for batch_modify prefab operations

sequenceDiagram
    actor Client
    participant PythonTool as manage_prefabs_py
    participant Unity as ManagePrefabs_cs
    participant PrefabUtil as PrefabUtility
    participant AssetDb as AssetDatabase

    Client->>PythonTool: manage_prefabs(action=batch_modify, prefab_path, operations[])
    PythonTool->>PythonTool: Build params (prefabPath, operations)
    PythonTool->>Unity: HandleCommand(params)

    Unity->>Unity: Parse action=batch_modify
    Unity->>Unity: BatchModifyContents(params)

    Unity->>PrefabUtil: LoadPrefabContents(sanitizedPath)
    PrefabUtil-->>Unity: prefabContents GameObject

    loop For each operation in operations
        Unity->>Unity: FindInPrefabContents(prefabContents, operation.target)
        alt Target found
            Unity->>Unity: ApplyModificationsToPrefabObject(targetGo, operation, prefabContents, out createdChildren)
            alt create_child present
                Unity->>Unity: CreateSingleChildInPrefab(..., out childInfo)
                Unity->>Unity: Collect childInfo into createdChildren
            end
            alt set_component_reference present
                Unity->>Unity: SetSingleComponentReference(...)
            end
            alt set_property present
                Unity->>Unity: SetSingleComponentProperty(...)
            end
            Unity->>Unity: Accumulate modified flag and allCreatedChildren
        else Target missing
            Unity->>Unity: Record per-operation error
        end
    end

    alt anyModified == true
        Unity->>PrefabUtil: SaveAsPrefabAsset(prefabContents, sanitizedPath, out success)
        PrefabUtil-->>Unity: success
        Unity->>AssetDb: Refresh()
        Unity->>Unity: McpLog.Info(batch summary)
        Unity-->>PythonTool: SuccessResponse(modified=true, operationResults, createdChildren)
    else
        Unity-->>PythonTool: SuccessResponse(modified=false, operationResults, createdChildren)
    end

    Unity->>PrefabUtil: UnloadPrefabContents(prefabContents)

    PythonTool-->>Client: JSON result with per-operation results and createdChildren
Loading

Sequence diagram for get_hierarchy with opt-in pagination

sequenceDiagram
    actor Client
    participant PythonTool as manage_prefabs_py
    participant Unity as ManagePrefabs_cs
    participant PrefabUtil as PrefabUtility

    Client->>PythonTool: manage_prefabs(action=get_hierarchy, prefab_path, page_size?, cursor?, max_depth?, filter?)

    PythonTool->>PythonTool: Map args to params
    PythonTool->>Unity: HandleCommand(params)

    Unity->>Unity: Parse action=get_hierarchy
    Unity->>Unity: GetHierarchy(params)
    Unity->>Unity: Sanitize prefabPath

    Unity->>PrefabUtil: LoadPrefabContents(sanitizedPath)
    PrefabUtil-->>Unity: prefabContents GameObject

    Unity->>Unity: Read pageSize, cursor, maxDepth, filter
    Unity->>Unity: paginationRequested = pageSize or cursor provided

    Unity->>Unity: BuildHierarchyItemsWithDepth(prefabContents.transform, sanitizedPath, maxDepth, filter)
    Unity->>Unity: total = allItems.Count

    alt paginationRequested == false
        Unity-->>PythonTool: SuccessResponse(prefabPath, total, items = allItems)
    else
        Unity->>Unity: Clamp cursor and pageSize
        Unity->>Unity: Compute end = min(total, cursor + pageSize)
        Unity->>Unity: pagedItems = allItems[cursor:end]
        Unity->>Unity: truncated = end < total
        Unity->>Unity: next_cursor = truncated ? end.ToString() : null
        Unity-->>PythonTool: SuccessResponse(prefabPath, total, cursor, pageSize, next_cursor, truncated, maxDepth, filter, items = pagedItems)
    end

    Unity->>PrefabUtil: UnloadPrefabContents(prefabContents)

    PythonTool-->>Client: JSON hierarchy page (with or without pagination fields)
Loading

Class diagram for updated ManagePrefabs prefab management flow

classDiagram
    class ManagePrefabs {
        <<static>>
        -ACTION_CREATE_FROM_GAMEOBJECT : string
        -ACTION_GET_INFO : string
        -ACTION_GET_HIERARCHY : string
        -ACTION_MODIFY_CONTENTS : string
        -ACTION_BATCH_MODIFY : string
        -SupportedActions : string
        +HandleCommand(params : JObject) object
        -GetInfo(params : JObject) object
        -GetHierarchy(params : JObject) object
        -ModifyContents(params : JObject) object
        -BatchModifyContents(params : JObject) object
        -FindInPrefabContents(prefabContents : GameObject, target : string) GameObject
        -ApplyModificationsToPrefabObject(targetGo : GameObject, params : JObject, prefabRoot : GameObject) (bool modified, ErrorResponse error)
        -ApplyModificationsToPrefabObject(targetGo : GameObject, params : JObject, prefabRoot : GameObject, createdChildren : out List~object~) (bool modified, ErrorResponse error)
        -CreateSingleChildInPrefab(createChildToken : JToken, defaultParent : GameObject, prefabRoot : GameObject) (bool created, ErrorResponse error)
        -CreateSingleChildInPrefab(createChildToken : JToken, defaultParent : GameObject, prefabRoot : GameObject, createdInfo : out object) (bool created, ErrorResponse error)
        -GetGameObjectPath(go : GameObject, root : GameObject) string
        -GetComponentInfoList(go : GameObject) List~object~
        -SetSingleComponentReference(refToken : JToken, targetGo : GameObject, prefabRoot : GameObject) (bool set, ErrorResponse error)
        -SetSingleComponentProperty(propToken : JToken, targetGo : GameObject) (bool set, ErrorResponse error)
        -BuildHierarchyItems(root : Transform, mainPrefabPath : string) List~object~
        -BuildHierarchyItemsWithDepth(root : Transform, mainPrefabPath : string, maxDepth : int?, filter : string) List~object~
        -BuildHierarchyItemsRecursiveWithDepth(transform : Transform, mainPrefabRoot : Transform, mainPrefabPath : string, parentPath : string, items : List~object~, currentDepth : int, maxDepth : int?, filterLower : string) void
    }

    class ComponentResolver {
        +TryResolve(typeName : string, componentType : out Type, resolveError : out string) bool
        +GetAllComponentProperties(componentType : Type) List~string~
    }

    class ComponentOps {
        +SetProperty(targetComponent : Component, propertyName : string, valueToken : JToken, error : out string) bool
    }

    class PrefabUtilityHelper {
        +GetComponentTypeNames(go : GameObject) List~string~
        +GetPrefabNestingDepth(go : GameObject, mainPrefabRoot : Transform) int
        +GetParentPrefabPath(go : GameObject, mainPrefabRoot : Transform) string
        +GetNestedPrefabPath(go : GameObject) string
    }

    class AssetPathUtility {
        +SanitizeAssetPath(path : string) string
    }

    class ErrorResponse {
        +Error : string
    }

    class SuccessResponse {
        +Message : string
        +Data : object
    }

    class McpLog {
        +Info(message : string) void
        +Warn(message : string) void
    }

    class PrefabUtility {
        +LoadPrefabContents(path : string) GameObject
        +SaveAsPrefabAsset(prefabRoot : GameObject, path : string, success : out bool) void
        +UnloadPrefabContents(prefabRoot : GameObject) void
        +InstantiatePrefab(prefabAsset : Object, parent : Transform) Object
        +IsAnyPrefabInstanceRoot(go : GameObject) bool
    }

    class AssetDatabase {
        +LoadAssetAtPath~GameObject~(path : string) GameObject
        +AssetPathToGUID(path : string) string
        +Refresh() void
    }

    ManagePrefabs --> ComponentResolver : uses for type resolution
    ManagePrefabs --> ComponentOps : uses for property setting
    ManagePrefabs --> PrefabUtilityHelper : uses for hierarchy metadata
    ManagePrefabs --> AssetPathUtility : uses for path sanitization
    ManagePrefabs --> ErrorResponse : returns on failure
    ManagePrefabs --> SuccessResponse : returns on success
    ManagePrefabs --> McpLog : logs operations
    ManagePrefabs --> PrefabUtility : loads/saves prefabs
    ManagePrefabs --> AssetDatabase : loads source prefabs and GUIDs
Loading

File-Level Changes

Change Details Files
Add opt-in pagination, depth limiting, and name filtering to get_hierarchy while preserving backward-compatible behavior.
  • Parse page_size/pageSize, cursor, maxDepth/max_depth, and filter from params and detect whether pagination was explicitly requested.
  • Refactor hierarchy building into BuildHierarchyItemsWithDepth/BuildHierarchyItemsRecursiveWithDepth to support maxDepth, depth field on items, and optional name filter.
  • Return full list when pagination is not requested; otherwise slice items into pages with cursor, pageSize, next_cursor, truncated, and total metadata in the SuccessResponse.
MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManagePrefabsCrudTests.cs
Introduce batch_modify action to apply multiple modifications in a single prefab load/save cycle with per-operation results and snake_case support.
  • Add ACTION_BATCH_MODIFY dispatch path and BatchModifyContents method that loads prefab once, iterates operations, applies ApplyModificationsToPrefabObject for each target, and saves once if anything changed.
  • Aggregate created children across operations and return operationCount, operationResults (success/error per index), and createdChildren in the response.
  • Extend ApplyModificationsToPrefabObject to accept an out createdChildren list and support both camelCase and snake_case for setActive/set_active, componentsToAdd/components_to_add, and componentsToRemove/components_to_remove for both single and batched operations.
MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManagePrefabsCrudTests.cs
Add set_property and set_component_reference operations for prefab objects using reflection-backed helpers.
  • Extend ApplyModificationsToPrefabObject to process setComponentReference/set_component_reference (single or array) via new SetSingleComponentReference helper that resolves components, parses reference_target (optionally with :ComponentType), and assigns serialized fields/properties with type checking and detailed errors.
  • Extend ApplyModificationsToPrefabObject to process setProperty/set_property (single or array) via new SetSingleComponentProperty helper that calls ComponentOps.SetProperty for single property or properties object and aggregates partial failures.
  • Use System.Reflection (FieldInfo/PropertyInfo) and ComponentResolver helpers to discover fields/properties, enforce SerializeField for private fields, and provide helpful diagnostics on type mismatches or missing members.
MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManagePrefabsCrudTests.cs
Enhance create_child to properly instantiate nested prefab instances and return rich metadata for created children.
  • Refactor CreateSingleChildInPrefab into an overload with an out createdInfo object and support prefabPath/prefab_path for instantiating nested prefabs via PrefabUtility.InstantiatePrefab, tracking isPrefabInstance, sourcePrefabPath, and sourcePrefabGuid.
  • Track added components on newly created children and expose both components (created) and allComponents (current) along with name, prefab-relative path, instance IDs, and transform IDs via GetGameObjectPath and GetComponentInfoList.
  • Plumb createdChildren from ApplyModificationsToPrefabObject/CreateSingleChildInPrefab through ModifyContents and BatchModifyContents so responses include per-call and aggregated createdChildren arrays, and add tests for both primitive and nested-prefab child creation flows.
MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManagePrefabsCrudTests.cs
Wire new capabilities through the Python manage_prefabs tool API, including pagination, batch_modify, and new modification parameters, with updated docs.
  • Register batch_modify in REQUIRED_PARAMS and action enum, and add operations argument plus plumbing to forward it as operations to Unity.
  • Expose get_hierarchy pagination arguments (page_size, cursor, max_depth, filter) in the Python signature, map them to pageSize, cursor, maxDepth, and filter, and update description to document pagination and depth/filter support.
  • Extend modify_contents arguments and docstrings to include prefab_path support for create_child, set_component_reference, and set_property, normalizing create_child via normalize_child_params and forwarding setComponentReference/setProperty to Unity.
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 Feb 2, 2026

📝 Walkthrough

Walkthrough

This pull request introduces batch modification capabilities, pagination, filtering, and depth controls for prefab hierarchies. New features include a batch_modify action for performing multiple operations in one cycle, enhanced GetHierarchy with page-size and cursor parameters, component reference/property setting via reflection, and richer metadata tracking for created children. Changes span the C# editor tool, Python server API layer, and comprehensive test coverage.

Changes

Cohort / File(s) Summary
ManagePrefabs Core Implementation
MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
Adds BatchModifyContents action handler; extends GetHierarchy with pagination (pageSize, cursor), depth (maxDepth), and filtering parameters; returns paginated results with metadata (total, nextCursor, truncated). Enhances ApplyModificationsToPrefabObject to track created children via out parameter. Introduces SetSingleComponentReference and SetSingleComponentProperty for reflection-based field/property updates. Expands CreateSingleChildInPrefab to return richer metadata and support nested prefab instantiation. Adds helper methods (GetGameObjectPath, GetComponentInfoList, BuildHierarchyItemsWithDepth) and supports camelCase/snake_case parameter names.
Server API Layer
Server/src/services/tools/manage_prefabs.py
Adds batch_modify action to supported actions and required params (prefab_path, operations). Introduces new public parameters: page_size, cursor, max_depth, filter for pagination/filtering; set_component_reference, set_property for advanced component modifications; operations for batch processing. Updates parameter propagation to wire these new inputs to Unity; extends documentation for prefab-specific path formats and nested prefab creation via prefab_path.
Test Coverage Expansion
TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManagePrefabsCrudTests.cs
Adds 604 lines of new unit tests covering: batch modify workflows with multi-operation application and per-operation results; pagination, maxDepth, and filter behavior; property and component reference setting with error handling; nested prefab instantiation; snake_case parameter support; created child info validation including paths and instance IDs.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Server
    participant ManagePrefabs as Unity<br/>ManagePrefabs
    participant PrefabSystem as Prefab<br/>System

    Client->>Server: batch_modify(prefab_path, operations[])
    Server->>ManagePrefabs: BatchModifyContents(operations)
    ManagePrefabs->>PrefabSystem: LoadPrefabContents(prefab_path)
    
    loop For each operation
        ManagePrefabs->>ManagePrefabs: ApplyModificationsToPrefabObject()
        alt Operation type
            ManagePrefabs->>ManagePrefabs: SetSingleComponentReference()
            ManagePrefabs->>ManagePrefabs: SetSingleComponentProperty()
        else Create Child
            ManagePrefabs->>PrefabSystem: CreateSingleChildInPrefab()
            PrefabSystem-->>ManagePrefabs: createdInfo (path, IDs, components)
        end
        ManagePrefabs->>ManagePrefabs: Collect per-operation result
    end
    
    ManagePrefabs->>PrefabSystem: SavePrefabAsset()
    ManagePrefabs->>PrefabSystem: UnloadPrefabContents()
    ManagePrefabs-->>Server: {results[], summary}
    Server-->>Client: {success, created_children, per_op_results}
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~60 minutes

The review requires careful analysis of interrelated logic across multiple layers: batch operation sequencing and state tracking in ManagePrefabs.cs, parameter propagation and validation in the server API, and comprehensive test scenarios validating both success and error paths. The addition of reflection-based property/reference setting and pagination logic increases complexity, though the changes follow consistent patterns.

Possibly Related PRs

  • PR #646: Directly modifies CreateSingleChildInPrefab and ApplyModificationsToPrefabObject signatures, establishing foundation for enhanced child creation with metadata tracking.
  • PR #627: Expands prefab hierarchy and info retrieval workflows that this PR further enhances with pagination and filtering capabilities.
  • PR #405: Modifies manage_prefabs server handler and supported actions/parameters, foundational to the batch_modify action integration.

Poem

🐰 Bouncing through prefabs with batches so bright,
Pagination and depth making hierarchies right,
Component references dancing with filters alight,
Nested children birthed in one eager flight,
A warren of modifications now perfectly tight!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main changes: pagination, batch operations, and property setting capabilities added to prefab management.
Description check ✅ Passed The pull request description is comprehensive and well-structured, covering summary, backward compatibility, test plan, commits, and additional context; all key template sections are addressed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs:1346-1355` </location>
<code_context>
+            UnityEngine.Object objectToAssign;
</code_context>

<issue_to_address>
**suggestion:** Handle GameObject fields when the reference_target explicitly specifies a Component type.

When `reference_target` includes a component suffix (e.g., `"Canvas/Button:Button"`), `objectToAssign` will always be a `Component`. For `GameObject`-typed fields/properties this fails the `IsAssignableFrom` check and returns a type mismatch, even though `component.gameObject` would be valid.

You already handle the reverse (field expects a `Component` but `objectToAssign` is a `GameObject`). Please mirror that for `GameObject` targets, e.g.:

```csharp
typeof(GameObject).IsAssignableFrom(fieldType) && objectToAssign is Component c
    ? c.gameObject
    : objectToAssign;
```

and apply the same logic for properties, so `reference_target` behaves consistently regardless of whether the target member is a `Component` or `GameObject`.

Suggested implementation:

```csharp
            // Determine what object to assign (GameObject or Component)
            UnityEngine.Object objectToAssign;

```

```csharp
                Component refComponent = referencedGo.GetComponent(refCompType);
                if (refComponent == null)
                {

```

```csharp
            // Now assign the reference to the field
            var fieldType = fieldInfo.FieldType;
            UnityEngine.Object fieldObjectToAssign =
                typeof(GameObject).IsAssignableFrom(fieldType) && objectToAssign is Component cForGo
                    ? cForGo.gameObject
                    : objectToAssign;

            if (!fieldType.IsAssignableFrom(fieldObjectToAssign.GetType()))
            {
                return (false, new ErrorResponse(
                    $"Type mismatch when assigning reference to field '{fieldInfo.Name}'. " +
                    $"Field type: {fieldType.FullName}, " +
                    $"Assigned object type: {fieldObjectToAssign.GetType().FullName}."));
            }

            fieldInfo.SetValue(targetComponent, fieldObjectToAssign);

```

```csharp
            // Now assign the reference to the property
            var propertyType = propertyInfo.PropertyType;
            UnityEngine.Object propertyObjectToAssign =
                typeof(GameObject).IsAssignableFrom(propertyType) && objectToAssign is Component cForGoProp
                    ? cForGoProp.gameObject
                    : objectToAssign;

            if (!propertyType.IsAssignableFrom(propertyObjectToAssign.GetType()))
            {
                return (false, new ErrorResponse(
                    $"Type mismatch when assigning reference to property '{propertyInfo.Name}'. " +
                    $"Property type: {propertyType.FullName}, " +
                    $"Assigned object type: {propertyObjectToAssign.GetType().FullName}."));
            }

            propertyInfo.SetValue(targetComponent, propertyObjectToAssign);

```

I assumed the existing assignment logic for fields and properties looks like the `IsAssignableFrom` checks in the SEARCH blocks above. If your actual code differs (e.g., variable names, structure, or error messages), adjust the SEARCH patterns accordingly and apply the same wrapping pattern:

1. Introduce a local `fieldObjectToAssign` (for fields) / `propertyObjectToAssign` (for properties).
2. Set it via:
   `typeof(GameObject).IsAssignableFrom(expectedType) && objectToAssign is Component c ? c.gameObject : objectToAssign;`
3. Use that local both in the `IsAssignableFrom` check and in the `SetValue` call.

Make sure to keep any existing special handling you already have for `Component`-typed fields where `objectToAssign` is a `GameObject`; this new logic is additive and should mirror that behavior in the opposite direction.
</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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs (1)

755-1024: ⚠️ Potential issue | 🔴 Critical

Add required using static import for ComponentResolver access.

The code at lines 883, 902, 1177, 1317, 1350, 1394, and 1482 calls ComponentResolver.TryResolve() and ComponentResolver.GetAllComponentProperties() directly, but the file lacks the required import statement. Since ComponentResolver is a nested static class within ManageGameObject, add this to the top of ManagePrefabs.cs:

using static MCPForUnity.Editor.Tools.ManageGameObject;

Without this import, all ComponentResolver calls will fail to compile.

@waqasrana
Copy link
Author

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)

MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs (1)> 755-1024: ⚠️ Potential issue | 🔴 Critical

Add required using static import for ComponentResolver access.
The code at lines 883, 902, 1177, 1317, 1350, 1394, and 1482 calls ComponentResolver.TryResolve() and ComponentResolver.GetAllComponentProperties() directly, but the file lacks the required import statement. Since ComponentResolver is a nested static class within ManageGameObject, add this to the top of ManagePrefabs.cs:

using static MCPForUnity.Editor.Tools.ManageGameObject;

Without this import, all ComponentResolver calls will fail to compile.

code compiles fine.


  Compilation succeeded:
  ExitCode: 0 Duration: 0s69ms
  *** Tundra build success (0.05 seconds), 0 items updated, 389 evaluated
  AssetDatabase: script compilation time: 0.237031s

  Plugin loaded correctly:
  MCP-FOR-UNITY: Auto-discovered 19 tools and 13 resources (32 total handlers)

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.

2 participants