Skip to content

Conversation

dsarno
Copy link
Owner

@dsarno dsarno commented Apr 10, 2025

Testing the PR

Summary by CodeRabbit

  • New Features
    • Introduced a parameter to control the inclusion of non-public serialized fields during game object management.
    • Added a new serialization helper to improve the handling of Unity objects and their components.
    • Implemented JSON converters for various Unity types to facilitate serialization and deserialization.
  • Bug Fixes
    • Enhanced command processing with improved error handling for scenarios where command data fails to convert correctly.

Copy link

coderabbitai bot commented Apr 10, 2025

Walkthrough

This pull request updates the serialization and command processing logic across several modules. In the UnityMcpBridge C# files, an optional parameter (includeNonPublicSerialized) is introduced to control the inclusion of non-public serialized fields during component data extraction, with caching and refined error logging added to improve the process. Additionally, a null check is added after JSON deserialization in the command processor to handle error cases. A corresponding update is made in the Python tool to mirror the new parameter functionality.

Changes

Files Change Summary
UnityMcpBridge/Editor/.../ManageGameObject.cs
UnityMcpServer/.../manage_gameobject.py
Added the includeNonPublicSerialized parameter to control serialization of non-public fields. Updated methods to pass the new flag, introduced caching of reflection metadata, refined serialization logic (including a new helper function), and updated docstrings/parameter dictionaries.
UnityMcpBridge/Editor/UnityMcpBridge.cs Inserted a null check after JSON deserialization in the ProcessCommands method to detect and handle commands that deserialize to null, producing an explicit error response.
UnityMcpBridge/Editor/Helpers/GameObjectSerializer.cs
UnityMcpBridge/Editor/Helpers/GameObjectSerializer.cs.meta
Introduced a new static class for serialization, providing methods to serialize GameObject and Component instances, including error handling and caching mechanisms. A metadata file was created to define the file's versioning and identification.
UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef
UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef.meta
Created a new assembly definition for the UnityMcpBridge.Editor namespace, specifying references and configurations.
UnityMcpBridge/Runtime/... Introduced new metadata files for various components and created a new assembly definition for UnityMcpBridge.Runtime, including serialization converters for Unity types.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant CmdHandler as ProcessCommands
    participant Serializer as JSON Serializer
    Client->>CmdHandler: Send JSON command
    CmdHandler->>Serializer: Deserialize command JSON
    CmdHandler->>CmdHandler: Check if command is null
    alt Command is null
        CmdHandler->>CmdHandler: Create error message
        CmdHandler->>Client: Return error response
    else Command is valid
        CmdHandler->>...: Process command normally
    end
Loading
sequenceDiagram
    participant UserCmd as Caller
    participant Handler as HandleCommand
    participant CompGetter as GetComponentsFromTarget
    participant CompData as GetComponentData
    participant Cache as Metadata Cache
    participant Serializer as AddSerializableValue
    UserCmd->>Handler: Invoke command with includeNonPublicSerialized flag
    Handler->>CompGetter: Request component data (passes flag)
    CompGetter->>CompData: Retrieve component data with flag
    alt Metadata available in cache?
        CompData->>Cache: Retrieve cached metadata
    else
        CompData->>Cache: Store new reflection metadata
    end
    CompData->>Serializer: Serialize properties/fields
    Serializer-->>CompData: Return serialized value
    CompData-->>CompGetter: Return complete component data
    CompGetter-->>Handler: Return data to caller
Loading

Poem

I hopped through lines of code today,
Tweaking fields in a whimsical way.
Non-public secrets now join the crew,
With caching magic shining through.
A null check here, a fix so neat—
This rabbit hops with joy so sweet! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@dsarno dsarno marked this pull request as ready for review April 10, 2025 15:14
Copy link

@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 (5)
UnityMcpBridge/Editor/Tools/ManageGameObject.cs (5)

25-28: Remove or gate commented-out debug logs.
These lines are currently commented out. Consider removing them or converting them into a conditional/log-level-based debug mechanism to reduce clutter.

- // --- DEBUG --- Log the raw parameter value ---
- // JToken rawIncludeFlag = @params["includeNonPublicSerialized"];
- // Debug.Log($"[HandleCommand Debug] Raw includeNonPublicSerialized parameter: Type={rawIncludeFlag?.Type.ToString() ?? "Null"}, Value={rawIncludeFlag?.ToString() ?? "N/A"}");
- // --- END DEBUG ---

46-50: Clean up commented-out parameter logic.
Several lines for toggling how includeNonPublicSerialized is handled remain commented out. If the logic is no longer needed, removing them will improve readability.

- // Reverting to original logic, assuming external system will be fixed...
- bool includeNonPublicSerialized = @params["includeNonPublicSerialized"]?.ToObject<bool>() ?? true; // Default
- // Revised: Explicitly check for null, default to false if null/missing. -- REMOVED
- // bool includeNonPublicSerialized = @params["includeNonPublicSerialized"] != null && ...

2210-2230: Introducing reflection metadata caching.
The new CachedMetadata class and _metadataCache dictionary greatly optimize repeated reflection. However, if any multi-threaded usage is foreseen, consider adding locking or concurrency safeguards around _metadataCache.


2230-2382: Hierarchical reflection in GetComponentData.
Traversing the inheritance chain to gather properties and fields is a robust approach. It neatly avoids repeated reflection logic at each level. Keep an eye on performance for large hierarchies, and consider a maximum depth or explicit skip logic if future expansions risk complexity.


2382-2475: Serialization approach in AddSerializableValue.
Rich handling of primitives, Unity structs, and UnityEngine.Object references ensures thorough coverage. Consider splitting overly complex conditions (e.g. for Materials) into helper methods to keep code maintainable and reduce branching complexity.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cbe9b3a and 15ba68f.

⛔ Files ignored due to path filters (1)
  • UnityMcpServer/src/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • UnityMcpBridge/Editor/Tools/ManageGameObject.cs (11 hunks)
  • UnityMcpBridge/Editor/UnityMcpBridge.cs (1 hunks)
  • UnityMcpServer/src/tools/manage_gameobject.py (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
UnityMcpBridge/Editor/Tools/ManageGameObject.cs (3)
UnityMcpBridge/Editor/Tools/ManageAsset.cs (1)
  • Type (1116-1151)
UnityMcpBridge/Editor/Helpers/Vector3Helper.cs (1)
  • Vector3 (17-22)
UnityMcpBridge/Editor/Windows/UnityMcpEditorWindow.cs (1)
  • Color (40-53)
🔇 Additional comments (8)
UnityMcpBridge/Editor/UnityMcpBridge.cs (1)

270-280: Good addition for null command handling.
This new block properly handles the scenario where a valid JSON string deserializes to a null command, providing a clear error response. This significantly improves robustness and debugging clarity.

UnityMcpServer/src/tools/manage_gameobject.py (3)

38-38: Parameter added for private serialized fields control.
Adding includeNonPublicSerialized as an optional boolean parameter is a solid improvement, enabling more flexible serialization of private [SerializeField] fields.


63-63: Docstring updated for new parameter.
The additional docstring clarifies behavior and usage of includeNonPublicSerialized, ensuring maintainability and discoverability.


96-97: Inclusion of new parameter in the command dictionary.
Correctly adding includeNonPublicSerialized to the parameters ensures the Python tool mirrors the Unity side, maintaining consistent behavior across systems.

UnityMcpBridge/Editor/Tools/ManageGameObject.cs (4)

5-5: New import aligns with usage of Json classes.
Importing Newtonsoft.Json is consistent with the rest of the file’s approach to JSON handling.


142-142: Parameter forwarding to GetComponentsFromTarget.
Forwarding includeNonPublicSerialized ensures that the serialization logic downstream is consistent with the user’s request.


882-882: Enhanced signature for component retrieval.
Introducing the bool includeNonPublicSerialized parameter in GetComponentsFromTarget is aligned with the broader goal of selectively including non-public serialized fields.


895-896: Passing the flag to GetComponentData.
This continues the pipeline for handling non-public serialized fields. The consistency between parameter reading and usage is well maintained.

…ializer helper

Moved serialization logic (GetGameObjectData, GetComponentData, metadata caching, JSON conversion helpers) from ManageGameObject tool to a dedicated GameObjectSerializer class in the Helpers namespace.

This improves separation of concerns and reduces the size/complexity of ManageGameObject.cs. Updated ManageGameObject to use the new helper class.
Copy link

@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 (3)
UnityMcpBridge/Editor/Tools/ManageGameObject.cs (3)

26-29: Optional removal of debug logs in production.

Debug statements for includeNonPublicSerialized are commented out, which is acceptable for now. Consider removing these stubs if they are no longer necessary to avoid clutter in future maintenance.


1424-1441: Custom input serializer for property assignment.

Defining a separate serializer (with relevant converters) specifically for reading incoming property values is a practical design choice. This approach provides a clearer distinction between read- vs. write-serialization logic and helps avoid confusion with your output-oriented serializer. Minor performance overhead from re-instantiating JsonSerializerSettings each time is acceptable, though you could store it statically if needed.


1605-1643: Flexible handling of material shader properties.

Your approach to interpret arrays for color or vector sets is creative. However, note that ambiguous array lengths (e.g., 2 vs. 3 vs. 4 elements) could lead to partial misinterpretations (e.g., a 4-element array might be incorrectly used). Consider logging more detail if multiple conversions fail, so users know which fallback was triggered.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15ba68f and dd0113d.

📒 Files selected for processing (2)
  • UnityMcpBridge/Editor/Helpers/GameObjectSerializer.cs (1 hunks)
  • UnityMcpBridge/Editor/Tools/ManageGameObject.cs (19 hunks)
🔇 Additional comments (9)
UnityMcpBridge/Editor/Helpers/GameObjectSerializer.cs (5)

21-99: Commendable thoroughness in GetGameObjectData.

This method offers a detailed snapshot of the GameObject state, carefully handling transform details to avoid reference loops. The explicit approach for serializing position, rotation, etc., is verbose but ensures clear, cycle-free data, suitable for external consumers. The optional component serialization is also well-structured and commented out to reduce overhead. No immediate corrections are needed.


101-115: Efficient reflection metadata caching strategy.

By storing computed properties/fields in _metadataCache keyed by (Type, bool), you reduce reflection overhead significantly. This is especially beneficial for large-scale and repeated serialization tasks. Implementation appears robust; no concerns here.


117-195: Solid reflection-based serialization in GetComponentData.

Your logic to traverse inheritance hierarchy up to MonoBehaviour is appropriate for most Unity components. Filtering out backing fields, skipping unwanted property names, and conditionally including non-public serialized fields help maintain a safe and consistent representation. One small caution: for extremely large or complex components, reflection might still be slow. However, your caching and property-skipping steps minimize this risk well.


252-335: Prudent JSON token handling and fallback conversions.

The AddSerializableValue pipeline ensures that problematic fields/properties are gracefully skipped. Converting JToken back to plain objects in ConvertJTokenToPlainObject is a neat approach for returning raw serializable data. The mix of logging warnings and ignoring reference loops helps minimize unexpected breaks. Great error resilience here.


337-375: Robust custom serializer configuration.

You have nicely consolidated Unity-specific converters (Vector3Converter, ColorConverter, etc.) into _outputSerializerSettings. The try/catch in CreateTokenFromValue handles serialization failures gracefully. Overall, this design is solid for Editor usage where reflection-based approaches are common.

UnityMcpBridge/Editor/Tools/ManageGameObject.cs (4)

47-49: Good addition of includeNonPublicSerialized parameter.

Defaulting to true maintains backward compatibility and ensures feature parity with prior reflection usage. Keep in mind that this allows external requests to read private fields (if [SerializeField] is present), so confirm that no sensitive data is exposed inadvertently.


139-140: Passing the new flag downstream is consistent.

Forwarding includeNonPublicSerialized to GetComponentsFromTarget ensures correct usage throughout the pipeline. The naming is self-explanatory, positively impacting maintainability. No issues spotted.


532-533: Neat usage of GameObjectSerializer.GetGameObjectData.

Returning serialized object data in success responses dramatically improves debugging and remote inspection. This centralizes serialization logic in the helper class and keeps this method clean.


1982-2025: Comprehensive type resolution logic.

The fallback approach scanning assemblies is thorough for a reflection-heavy editor utility. The incremental approach—checking known assemblies first, then searching the rest—should mitigate performance hits. Logging warnings on ambiguities is also appreciated. Well done.

Copy link

@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

♻️ Duplicate comments (5)
UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs (5)

36-56: Similar concern about missing properties in Vector2Converter.


58-84: Similar concern about missing properties in QuaternionConverter.


86-112: Similar concern about missing properties in ColorConverter.


114-140: Similar concern about missing properties in RectConverter.


142-161: Similar concern about missing properties in BoundsConverter.

🧹 Nitpick comments (1)
UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs (1)

11-34: Strengthen error handling for incomplete or malformed JSON.

In Vector3Converter.ReadJson, (float)jo["x"] may throw if the tokens are missing or of an unexpected type. Consider verifying the presence of these properties or falling back to default values when tokens are missing.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0433b88 and bd85072.

📒 Files selected for processing (8)
  • UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef (1 hunks)
  • UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef.meta (1 hunks)
  • UnityMcpBridge/Runtime.meta (1 hunks)
  • UnityMcpBridge/Runtime/Serialization.meta (1 hunks)
  • UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs (1 hunks)
  • UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs.meta (1 hunks)
  • UnityMcpBridge/Runtime/UnityMcpBridge.Runtime.asmdef (1 hunks)
  • UnityMcpBridge/Runtime/UnityMcpBridge.Runtime.asmdef.meta (1 hunks)
✅ Files skipped from review due to trivial changes (7)
  • UnityMcpBridge/Runtime/UnityMcpBridge.Runtime.asmdef.meta
  • UnityMcpBridge/Runtime/UnityMcpBridge.Runtime.asmdef
  • UnityMcpBridge/Runtime/Serialization.meta
  • UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs.meta
  • UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef
  • UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef.meta
  • UnityMcpBridge/Runtime.meta
🔇 Additional comments (2)
UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs (2)

1-10: No issues found in the initial setup.

The using statements and namespace declaration appear correct, and there are no obvious concerns here.


163-266: Assess potential security implications of loading assets via user-supplied paths.

If portions of the JSON come from untrusted sources, malicious paths could be supplied. Consider validating or sanitizing asset paths before calling LoadAssetAtPath to reduce any security risk.

Would you please confirm whether the JSON input is fully controlled? If external, do you need a safeguard to restrict possible paths?

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