Skip to content

Conversation

@Scriptwonder
Copy link
Collaborator

@Scriptwonder Scriptwonder commented Dec 4, 2025

Tackle the requests in Issue#267, tested and no bugs found.

(1) LLM can duplicate an gameobject based on request
(2) LLM can move a gameobject relative to another gameobject

Summary by CodeRabbit

  • New Features
    • Added support for duplicating objects with custom names, position offsets, and parent assignment options.
    • Added support for moving objects relative to reference objects using directional movement or offset vectors.
    • Movement operations support both world space and local space reference frames.

✏️ Tip: You can customize this high-level summary in your review settings.

Tackle the requests in Issue#267, tested and no bugs found.

(1)LLM can duplicate an gameobject based on request
(2)LLM can move a gameobject relative to another gameobject
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 4, 2025

Walkthrough

This PR extends GameObject manipulation capabilities by introducing two new actions: duplicate (for creating copies with custom properties) and move_relative (for repositioning objects relative to references). Both the C# Unity editor tool and Python server are updated to support these workflows with enhanced parameter handling.

Changes

Cohort / File(s) Summary
C# Unity Editor Tool
MCPForUnity/Editor/Tools/ManageGameObject.cs
Added two new action handlers: DuplicateGameObject (instantiates source with optional new_name, position, offset, parent) and MoveRelativeToObject (repositions target relative to a reference object with direction/distance support). Introduced GetDirectionVector helper to convert direction strings to Vector3. Enhanced parameter handling with includeNonPublicSerialized flag and JSON parsing for componentProperties. Added prefab redirection logic for modify and set_component_property actions.
Python Server Tool
Server/src/services/tools/manage_gameobject.py
Extended action literals to include "duplicate" and "move_relative". Added public parameters: new_name, offset (for duplicate); reference_object, direction, distance, world_space (for move_relative). Enhanced input coercion for offset and world_space. Updated method signature with new annotated parameters and propagated them through command payload.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant PyServer as Python Server
    participant UnityEditor as Unity Editor
    participant Scene as Scene/GameObject

    rect rgba(100, 200, 150, 0.2)
    Note over Client,Scene: Duplicate Action Flow
    Client->>PyServer: manage_gameobject(action="duplicate", source, new_name, offset, parent)
    PyServer->>PyServer: Validate & coerce parameters
    PyServer->>UnityEditor: SendCommand(duplicate, source, new_name, offset, parent)
    UnityEditor->>UnityEditor: Instantiate source GameObject
    UnityEditor->>UnityEditor: Apply naming (new_name or default)
    UnityEditor->>UnityEditor: Apply position + offset
    UnityEditor->>UnityEditor: Set parent (null or specified)
    UnityEditor->>Scene: Mark scene dirty
    UnityEditor->>UnityEditor: Register Undo
    UnityEditor->>PyServer: Return {original, duplicated, position, parent}
    PyServer->>Client: Return duplicated object info
    end

    rect rgba(100, 150, 200, 0.2)
    Note over Client,Scene: Move Relative Action Flow
    Client->>PyServer: manage_gameobject(action="move_relative", target, reference_object, direction, distance, world_space)
    PyServer->>PyServer: Validate & coerce direction, distance, world_space
    PyServer->>UnityEditor: SendCommand(move_relative, target, reference_object, direction, distance, world_space)
    UnityEditor->>UnityEditor: GetDirectionVector(direction, world_space, reference)
    UnityEditor->>UnityEditor: Calculate new position from offset/direction
    UnityEditor->>Scene: Update target position
    UnityEditor->>Scene: Mark scene dirty
    UnityEditor->>UnityEditor: Register Undo & select object
    UnityEditor->>PyServer: Return {moved_object, reference, new_position, direction, distance}
    PyServer->>Client: Return move result info
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring extra attention:

  • Direction vector conversion logic in GetDirectionVector to ensure correct world/local space transformations
  • Offset and parameter coercion in both Python and C# for robustness
  • Prefab redirection logic to confirm proper delegation to ManageAsset
  • Undo/scene marking consistency across both new actions

Poem

🐰 Hop, duplicate, and move with grace!
Objects now dance through Unity's space—
Copy them left, right, up, and around,
With offsets applied, new positions found.
The editor rejoices, the server's so keen,
Managing GameObjects like never before seen! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is partially related to the changeset but lacks specificity. It mentions 'two new features' without identifying what they are (duplicate and move_relative), making it vague for someone scanning the commit history. Consider revising to something more specific like '[FEATURE] Add duplicate and move_relative GameObject actions' to clearly convey the primary changes introduced.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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

@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

🧹 Nitpick comments (1)
Server/src/services/tools/manage_gameobject.py (1)

244-244: Static analysis hint: consider explicit conversion flag.

The Ruff linter suggests using an explicit conversion flag instead of str(e). While this is a valid suggestion, the current usage is clear and idiomatic. This can be addressed if the team has strict linting standards.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa47838 and c82e945.

📒 Files selected for processing (2)
  • MCPForUnity/Editor/Tools/ManageGameObject.cs (3 hunks)
  • Server/src/services/tools/manage_gameobject.py (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
Server/src/services/tools/manage_gameobject.py (1)
Server/src/services/tools/manage_editor.py (1)
  • _coerce_bool (30-41)
🪛 Ruff (0.14.7)
Server/src/services/tools/manage_gameobject.py

244-244: Use explicit conversion flag

Replace with conversion flag

(RUF010)

🔇 Additional comments (7)
Server/src/services/tools/manage_gameobject.py (3)

16-16: LGTM! Well-structured action and parameter expansion.

The new actions and parameters are properly typed and documented. The direction literal thoughtfully includes aliases ("front" for "forward", "backward"/"behind" for "back") which improves the developer experience.

Also applies to: 69-82


130-130: LGTM! Proper parameter coercion with sensible defaults.

The coercion follows established patterns. The world_space default of True is appropriate for most spatial operations and aligns with Unity's common conventions.

Also applies to: 137-137


200-209: Verify parameter naming convention consistency.

The new parameters are sent to Unity with snake_case names (new_name, reference_object, world_space), while existing parameters use camelCase (componentsToAdd, searchMethod, setActive). Confirm whether the Unity C# side correctly maps these snake_case parameter names, or if they should be converted to camelCase:

  • new_namenewName
  • reference_objectreferenceObject
  • world_spaceworldSpace
MCPForUnity/Editor/Tools/ManageGameObject.cs (4)

192-195: LGTM! Case handlers follow established patterns.

The new action handlers are properly integrated into the switch statement and follow the same signature pattern as existing handlers.


997-1077: Solid implementation with good flexibility.

The MoveRelativeToObject method properly handles:

  • Required reference_object validation (lines 1013-1016)
  • Two movement modes: custom offset vector OR directional movement with distance
  • Both world space and local space coordinates
  • Proper Unity integration (Undo, scene dirty marking, selection)

The positioning logic correctly uses referenceGo.transform.TransformPoint() for local-space offsets (line 1045), which applies the reference object's rotation and scale.


1079-1116: LGTM! Clear direction mapping with proper fallback.

The GetDirectionVector helper correctly:

  • Differentiates between world space (Vector3.right, etc.) and local space (referenceTransform.right, etc.)
  • Handles all direction aliases specified in the Python action literal
  • Provides a sensible fallback with a warning for unknown directions
  • Uses proper negation for opposite directions (left = -right, down = -up, back = -forward)

905-995: Well-implemented duplication with proper Unity integration.

The DuplicateGameObject method follows Unity best practices:

  • Proper Undo support (line 926)
  • Scene dirty marking (lines 981-982)
  • Selection update (line 984)
  • Structured data response using GameObjectSerializer

The positioning logic is clear: absolute position takes precedence, then offset from the original position, otherwise keeps the source position.

Verify the parameter name mapping: the C# code accesses @params["new_name"] (snake_case). Confirm this matches what the Python side sends.

@Scriptwonder
Copy link
Collaborator Author

Going to merge it, will close Issue#267 also.

@Scriptwonder Scriptwonder merged commit a69ce19 into CoplayDev:main Dec 4, 2025
1 check passed
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