diff --git a/HOW_TO_ADD_A_TOOL.md b/HOW_TO_ADD_A_TOOL.md deleted file mode 100644 index 84267307..00000000 --- a/HOW_TO_ADD_A_TOOL.md +++ /dev/null @@ -1,250 +0,0 @@ -# Unity MCP Server - -This directory contains the Unity MCP Server implementation, which provides a bridge between Python and Unity Editor functionality. - -## Adding New Tools - -To add a new tool to the MCP Server, follow these steps: - -### 1. Create the C# Command Handler - -First, create or modify a command handler in the `Editor/Commands` directory: - -```csharp -// Example: NewCommandHandler.cs -public static class NewCommandHandler -{ - public static object HandleNewCommand(JObject @params) - { - // Extract parameters - string param1 = (string)@params["param1"]; - int param2 = (int)@params["param2"]; - - // Implement the Unity-side functionality - // ... - - // Return results - return new { - message = "Operation successful", - result = someResult - }; - } -} -``` - -### 2. Register the Command Handler - -Add your command handler to the `CommandRegistry.cs` in the `Editor/Commands` directory: - -```csharp -public static class CommandRegistry -{ - private static readonly Dictionary> _handlers = new() - { - // ... existing handlers ... - { "NEW_COMMAND", NewCommandHandler.HandleNewCommand } - }; -} -``` - -### 3. Create the Python Tool - -Add your tool to the appropriate Python module in the `Python/tools` directory: - -```python -@mcp.tool() -def new_tool( - ctx: Context, - param1: str, - param2: int -) -> str: - """Description of what the tool does. - - Args: - ctx: The MCP context - param1: Description of param1 - param2: Description of param2 - - Returns: - str: Success message or error details - """ - try: - response = get_unity_connection().send_command("NEW_COMMAND", { - "param1": param1, - "param2": param2 - }) - return response.get("message", "Operation successful") - except Exception as e: - return f"Error executing operation: {str(e)}" -``` - -### 4. Register the Tool - -Ensure your tool is registered in the appropriate registration function: - -```python -# In Python/tools/__init__.py -def register_all_tools(mcp): - register_scene_tools(mcp) - register_script_tools(mcp) - register_material_tools(mcp) - # Add your new tool registration if needed -``` - -### 5. Update the Prompt - -If your tool should be exposed to users, update the prompt in `Python/server.py`: - -```python -@mcp.prompt() -def asset_creation_strategy() -> str: - return ( - "Follow these Unity best practices:\n\n" - "1. **Your Category**:\n" - " - Use `new_tool(param1, param2)` to do something\n" - # ... rest of the prompt ... - ) -``` - -## Best Practices - -1. **Existence Checking**: - - - ALWAYS check if objects, scripts, assets, or materials exist before creating or updating them - - Use appropriate search tools (`find_objects_by_name`, `list_scripts`, `get_asset_list`) to verify existence - - Handle both cases: creation when it doesn't exist and updating when it does - - Implement proper error handling when an expected resource is not found - -2. **Error Handling**: - - - Always include try-catch blocks in Python tools - - Validate parameters in C# handlers - - Return meaningful error messages - -3. **Documentation**: - - - Add XML documentation to C# handlers - - Include detailed docstrings in Python tools - - Update the prompt with clear usage instructions - -4. **Parameter Validation**: - - - Validate parameters on both Python and C# sides - - Use appropriate types (str, int, float, List, etc.) - - Provide default values when appropriate - -5. **Testing**: - - - Test the tool in both Unity Editor and Python environments - - Verify error handling works as expected - - Check that the tool integrates well with existing functionality - -6. **Code Organization**: - - Group related tools in appropriate handler classes - - Keep tools focused and single-purpose - - Follow existing naming conventions - -## Example Implementation - -Here's a complete example of adding a new tool: - -1. **C# Handler** (`Editor/Commands/ExampleHandler.cs`): - -```csharp -public static class ExampleHandler -{ - public static object CreatePrefab(JObject @params) - { - string prefabName = (string)@params["prefab_name"]; - string template = (string)@params["template"]; - bool overwrite = @params["overwrite"] != null ? (bool)@params["overwrite"] : false; - - // Check if the prefab already exists - string prefabPath = $"Assets/Prefabs/{prefabName}.prefab"; - bool prefabExists = System.IO.File.Exists(prefabPath); - - if (prefabExists && !overwrite) - { - return new { - message = $"Prefab already exists: {prefabName}. Use overwrite=true to replace it.", - exists = true, - path = prefabPath - }; - } - - // Implementation - GameObject prefab = new GameObject(prefabName); - // ... setup prefab ... - - return new { - message = prefabExists ? $"Updated prefab: {prefabName}" : $"Created prefab: {prefabName}", - exists = prefabExists, - path = prefabPath - }; - } -} -``` - -2. **Python Tool** (`Python/tools/example_tools.py`): - -```python -@mcp.tool() -def create_prefab( - ctx: Context, - prefab_name: str, - template: str = "default", - overwrite: bool = False -) -> str: - """Create a new prefab in the project or update if it exists. - - Args: - ctx: The MCP context - prefab_name: Name for the new prefab - template: Template to use (default: "default") - overwrite: Whether to overwrite an existing prefab (default: False) - - Returns: - str: Success message or error details - """ - try: - # First check if the prefab already exists - assets = get_unity_connection().send_command("GET_ASSET_LIST", { - "type": "Prefab", - "search_pattern": prefab_name, - "folder": "Assets/Prefabs" - }).get("assets", []) - - prefab_exists = any(asset.get("name") == prefab_name for asset in assets) - - if prefab_exists and not overwrite: - return f"Prefab '{prefab_name}' already exists. Use overwrite=True to replace it." - - # Create or update the prefab - response = get_unity_connection().send_command("CREATE_PREFAB", { - "prefab_name": prefab_name, - "template": template, - "overwrite": overwrite - }) - - return response.get("message", "Prefab operation completed successfully") - except Exception as e: - return f"Error with prefab operation: {str(e)}" -``` - -3. **Update Prompt**: - -```python -"1. **Prefab Management**:\n" -" - ALWAYS check if a prefab exists before creating it\n" -" - Create or update prefabs with `create_prefab(prefab_name, template, overwrite=False)`\n" -``` - -## Troubleshooting - -If you encounter issues: - -1. Check the Unity Console for C# errors -2. Verify the command name matches between Python and C# -3. Ensure all parameters are properly serialized -4. Check the Python logs for connection issues -5. Verify the tool is properly registered in both environments diff --git a/HOW_TO_ADD_A_TOOL.md.meta b/HOW_TO_ADD_A_TOOL.md.meta deleted file mode 100644 index 5d24a51d..00000000 --- a/HOW_TO_ADD_A_TOOL.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: b58016417cf90784ab7d4a74d1ed827a -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/climber-prompt.md b/climber-prompt.md deleted file mode 100644 index da07f840..00000000 --- a/climber-prompt.md +++ /dev/null @@ -1,66 +0,0 @@ -Follow this detailed step-by-step guide to build this **"Crystal Climber"** game. - ---- - -### Step 1: Set Up the Basic Scene -1. Create a new 3D project named "Crystal Climber." -2. Add a large flat plane as the starting ground (this can act as the base of the climb). -3. Add a simple 3D cube or capsule as the player character. -4. Position the player on the ground plane, slightly above it (to account for gravity). -5. Add a directional light to illuminate the scene evenly. - ---- - -### Step 2: Player Movement Basics -6. Implement basic WASD movement for the player (forward, backward, left, right). -7. Add a jump ability triggered by the spacebar. -8. Attach a third-person camera to follow the player (positioned slightly behind and above). - ---- - -### Step 3: Build the Platform Structure -9. Create a flat, square platform (e.g., a thin cube or plane) as a prefab. -10. Place 5 platforms manually in the scene, staggered vertically and slightly offset horizontally (forming a climbable path upward). -11. Add collision to the platforms so the player can land on them. -12. Test the player jumping from the ground plane to the first platform and up the sequence. - ---- - -### Step 4: Core Objective -13. Place a glowing cube or sphere at the topmost platform as the "crystal." -14. Make the crystal detectable so the game recognizes when the player reaches it. -15. Add a win condition (e.g., display "You Win!" text on screen when the player touches the crystal). - ---- - -### Step 5: Visual Polish -16. Apply a semi-transparent material to the platforms (e.g., light blue with a faint glow). -17. Add a pulsing effect to the platforms (e.g., slight scale increase/decrease or opacity shift). -18. Change the scene background to a starry skybox. -19. Add a particle effect (e.g., sparkles or glowing dots) around the crystal. - ---- - -### Step 6: Refine the Platforms -20. Adjust the spacing between platforms to ensure jumps are challenging but possible. -21. Add 5 more platforms (total 10) to extend the climb vertically. -22. Place a small floating orb or decorative object on one platform as a visual detail. - ---- - -### Step 7: Audio Enhancement -23. Add a looping ambient background sound (e.g., soft wind or ethereal hum). -24. Attach a jump sound to the player (e.g., a light tap or whoosh). -25. Add a short victory sound (e.g., a chime or jingle) when the player reaches the crystal. - ---- - -### Step 8: Final Touches for Devlog Appeal -26. Add a subtle camera zoom-in effect when the player touches the crystal. -27. Sprinkle a few particle effects (e.g., faint stars or mist) across the scene for atmosphere. - ---- - -### Extras -29. Add a double-jump ability (e.g., press space twice) to make platforming easier. -30. Place a slow-rotating spike ball on one platform as a hazard to jump over. \ No newline at end of file diff --git a/climber-prompt.md.meta b/climber-prompt.md.meta deleted file mode 100644 index 2a771625..00000000 --- a/climber-prompt.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 59f0a16c19ac31d48a5b294600c96873 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/example-prompt-v2.md b/example-prompt-v2.md deleted file mode 100644 index 33698d5e..00000000 --- a/example-prompt-v2.md +++ /dev/null @@ -1,20 +0,0 @@ -# Create a "Collect the Cubes" game - Objective: The player controls a simple 3D character (like a sphere or capsule) that moves around a flat 3D environment to collect floating cubes before a timer runs out. - Win Condition: Collect all the cubes (e.g., 5–10) to win. - Lose Condition: Timer runs out before all cubes are collected. - -## Steps - Create a 3D plane in the scene and position it as the ground. - Add a 3D sphere to the scene as the player object. - Attach a Rigidbody component to the sphere. - Create a new script called "PlayerMovement" and attach it to the sphere. - Add five 3D cubes to the scene, positioning them at different spots above the ground. - Add a Collider component to each cube and set it as a trigger. - Create a new script called "Collectible" and attach it to each cube. - Create an empty GameObject called "GameManager" in the scene. - Create a new script called "GameController" and attach it to the GameManager. - Add a UI Text element to the scene for displaying the score. - Add a second UI Text element to the scene for displaying the timer. - Create a UI Text element for a win message and set it to be invisible by default. - Create a UI Text element for a lose message and set it to be invisible by default. - Save the scene. \ No newline at end of file diff --git a/example-prompt-v2.md.meta b/example-prompt-v2.md.meta deleted file mode 100644 index 19c75d96..00000000 --- a/example-prompt-v2.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 870319fa77a9f444ea4b604112bc761e -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/example-prompt.md b/example-prompt.md deleted file mode 100644 index 83103628..00000000 --- a/example-prompt.md +++ /dev/null @@ -1,83 +0,0 @@ -Create an endless runner game based on the Google Dinosaur game concept. - - Scene Setup: - - Create a new 2D scene named "EndlessRunner". - - Configure the Main Camera for 2D orthographic view. - - Player Character: - - Create a GameObject for the Player (e.g., a simple sprite or 2D shape like a square). - - Position the Player towards the left side of the screen, slightly above the ground level. - - Add appropriate 2D physics components (Rigidbody2D, Collider2D) to the Player. Configure gravity. - - Create a PlayerController script and attach it to the Player. - - Implement jump functionality triggered by player input (e.g., Spacebar, mouse click, or screen tap). This should apply an upward force. - - Prevent double-jumping unless intended (check if grounded). - - Detect collisions, specifically with objects tagged as "Obstacle". - - Ground: - - Create at least two Ground GameObjects (e.g., long thin sprites or shapes) that can be placed end-to-end. - - Add Collider2D components to the Ground GameObjects so the player can stand on them. - - Create a script (e.g., GroundScroller) to manage ground movement. - - Implement continuous scrolling movement from right to left for the ground segments. - - Implement logic to reposition ground segments that move off-screen to the left back to the right side, creating an infinite loop. - - Obstacles: - - Create at least one Obstacle prefab (e.g., a different sprite or shape representing a cactus). - - Add a Collider2D component to the Obstacle prefab. - - Assign a specific tag (e.g., "Obstacle") to the Obstacle prefab. - - Create an empty GameObject named ObstacleSpawner. - - Create an ObstacleSpawner script and attach it. - - Implement logic to periodically spawn Obstacle prefabs at a set position off-screen to the right. - - Introduce random variation in the time between spawns. - - (Optional) Implement logic to choose randomly between different obstacle types if more than one prefab is created. - - Create an ObstacleMover script and attach it to the Obstacle prefab(s). - - Implement movement for spawned obstacles from right to left at the game's current speed. - - Implement logic to destroy obstacles once they move off-screen to the left. - - Game Management: - - Create an empty GameObject named GameManager. - - Create a GameManager script and attach it. - - Manage the overall game state (e.g., Initializing, Playing, GameOver). - - Track the player's score, increasing it over time while the game state is "Playing". - - Control the game's speed, gradually increasing the scrolling speed of the ground and obstacles over time. - - Implement Game Over logic: triggered when the Player collides with an "Obstacle". This should stop all movement (player, ground, obstacles) and change the game state. - - Implement Restart logic: allow the player to restart the game (e.g., by pressing a key or button) after a Game Over, resetting the score, speed, and scene elements. - - User Interface (UI): - - Create a UI Canvas. - - Add a UI Text element to display the current score, updated by the GameManager. - - Add UI elements for the Game Over screen (e.g., "Game Over" text, final score display, restart instructions). These should be hidden initially and shown when the game state changes to "GameOver". \ No newline at end of file diff --git a/example-prompt.md.meta b/example-prompt.md.meta deleted file mode 100644 index fdc4b599..00000000 --- a/example-prompt.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 22513ccfdc5b6134f8d582d3d8869c5c -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/tool-refactor-plan.md b/tool-refactor-plan.md deleted file mode 100644 index 09365c71..00000000 --- a/tool-refactor-plan.md +++ /dev/null @@ -1,98 +0,0 @@ -# Tool Refactor Plan -The purpose of this refactor is to minimize the amount of tools in use. Right now we have around 35 tool available to the LLM. Most research I've seen says the ideal amount of tools is 10-30 total. This includes when using multiple MCP servers. So to help the LLM make the best tool choice for the job, we're going to narrow down the number of tools we are using from 35 to 8-ish. - -## Project Structure -We are building a Unity plugin under the folder and name UnityMCP. Within this folder are two projects. One is the MCP server under Python/ and the other is the Unity bridge and tool implementations under Editor/ - -## Steps - -1. Remove all existing tools except for execute_command under editor_tools.py and for HandleExecuteCommand in EditorControlHandler.cs. This will be the only tool reused. All other files should be deleted. Rename editor_tools.py to execute_command.py. Rename EditorControllerHandler.cs to ExecuteCommand.cs. - -2. Create Python/tools/manage_script.py and Editor/Tools/ManageScript.cs - - Implement all CRUD operations. Specify the action with an 'action' parameter. - - Add required parameter 'name' - - Add optional parameters 'path', 'contents', and 'script_type' (MonoBehaviour, ScriptableObject, Editor, etc.) - - Include validation for script syntax - - Add optional 'namespace' parameter for organizing scripts - -3. Create Python/tools/manage_scene.py and Editor/Tools/ManageScene.cs - - Implement scene operations like loading, saving, creating new scenes. - - Add required parameter 'action' to specify operation (load, save, create, get_hierarchy, etc.) - - Add optional parameters 'name', 'path', and 'build_index' - - Handle scene hierarchy queries with 'get_hierarchy' action - -4. Create Python/tools/manage_editor.py and Editor/Tools/ManageEditor.cs - - Control editor state (play mode, pause, stop). Query editor state - - Add required parameter 'action' to specify the operation ('play', 'pause', 'stop', 'get_state', etc.) - - Add optional parameters for specific settings ('resolution', 'quality', 'target_framerate') - - Include operations for managing editor windows and layouts - - Add optional 'wait_for_completion' boolean parameter for operations that take time - - Support querying current active tool and selection - -5. Create Python/tools/manage_gameobject.py and Editor/Tools/ManageGameObject.cs - - Handle GameObject creation, modification, deletion - - Add required parameters 'action' ('create', 'modify', 'delete', 'find', 'get_components', etc.) - - Add required parameter 'target' for operations on existing objects (path, name, or ID) - - Add optional parameters 'parent', 'position', 'rotation', 'scale', 'components' - - Support component-specific operations with 'component_name' and 'component_properties' - - Add 'search_method' parameter ('by_name', 'by_tag', 'by_layer', 'by_component') - - Return standardized GameObject data structure with transforms and components - -6. Create Python/tools/manage_asset.py and Editor/Tools/ManageAsset.cs - - Implement asset operations ('import', 'create', 'modify', 'delete', 'duplicate', 'search') - - Add required parameters 'action' and 'path' - - Add optional parameters 'asset_type', 'properties', 'destination' (for duplicate/move) - - Support asset-specific parameters based on asset_type - - Include preview generation with optional 'generate_preview' parameter - - Add pagination support with 'page_size' and 'page_number' for search results - - Support filtering assets by type, name pattern, or creation date - -7. Create Python/tools/read_console.py and Editor/Tools/ReadConsole.cs - - Retrieve Unity console output (errors, warnings, logs) - - Add optional parameters 'type' (array of 'error', 'warning', 'log', 'all') - - Add optional 'count', 'filter_text', 'since_timestamp' parameters - - Support 'clear' action to clear console - - Add 'format' parameter ('plain', 'detailed', 'json') for different output formats - - Include stack trace toggle with 'include_stacktrace' boolean - -8. Create Python/tools/execute_menu_item.py and Editor/Tools/ExecuteMenuItem.cs - - Execute Unity editor menu commands through script - - Add required parameter 'menu_path' for the menu item to execute - - Add optional 'parameters' object for menu items that accept parameters - - Support common menu operations with 'alias' parameter for simplified access - - Include validation to prevent execution of dangerous operations - - Add 'get_available_menus' action to list accessible menu items - - Support context-specific menu items with optional 'context' parameter - -## Implementation Guidelines - -1. Ensure consistent parameter naming and structure across all tools: - - Use 'action' parameter consistently for all operation-based tools - - Return standardized response format with 'success', 'data', and 'error' fields - - Use consistent error codes and messages - -2. Implement proper error handling and validation: - - Validate parameters before execution - - Provide detailed error messages with suggestions for resolution - - Add timeout handling for long-running operations - - Include parameter type checking in both Python and C# - -3. Use JSON for structured data exchange: - - Define clear schema for each tool's input and output - - Handle serialization edge cases (e.g., circular references) - - Optimize for large data transfers when necessary - -4. Minimize dependencies between tools: - - Design each tool to function independently - - Use common utility functions for shared functionality - - Document any required dependencies clearly - -5. Add performance considerations: - - Implement batching for multiple related operations - - Add optional asynchronous execution for long-running tasks - - Include optional progress reporting for time-consuming operations - -6. Improve documentation: - - Add detailed XML/JSDoc comments for all public methods - - Include example usage for common scenarios - - Document potential side effects of operations \ No newline at end of file diff --git a/tool-refactor-plan.md.meta b/tool-refactor-plan.md.meta deleted file mode 100644 index 842e7b98..00000000 --- a/tool-refactor-plan.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: c3ccc86868276bd4bba01c840f14e5bb -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: