-
Notifications
You must be signed in to change notification settings - Fork 526
Move Get commands to editor resources + Run Python tests every update #368
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 14 commits
3f37682
9b08dcb
c3186cd
932703d
2ea5cfa
fb9f7e4
4d88c4e
bec63f4
13274c9
5e20bcb
2a1e6ac
fd031b4
c7208ea
2d02c54
0c60d1a
6cb77d6
8681361
35637d3
d3fa3d9
1b40ce0
bfd806e
5bf3712
49d1fa9
730092d
d76e2b1
399d279
d78ea82
bbe1fb6
a734fe6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| name: Python Tests | ||
|
|
||
| on: | ||
| push: | ||
| branches: ["**"] | ||
| paths: | ||
| - MCPForUnity/UnityMcpServer~/src/** | ||
| - .github/workflows/python-tests.yml | ||
| pull_request: | ||
| paths: | ||
| - MCPForUnity/UnityMcpServer~/src/** | ||
| - .github/workflows/python-tests.yml | ||
| workflow_dispatch: {} | ||
|
|
||
| jobs: | ||
| test: | ||
| name: Run Python Tests | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Install uv | ||
| uses: astral-sh/setup-uv@v4 | ||
| with: | ||
| version: "latest" | ||
|
|
||
| - name: Set up Python | ||
| run: uv python install 3.10 | ||
|
|
||
| - name: Install dependencies | ||
| run: | | ||
| cd MCPForUnity/UnityMcpServer~/src | ||
| uv sync | ||
| uv pip install -e ".[dev]" | ||
|
|
||
| - name: Run tests | ||
| run: | | ||
| cd MCPForUnity/UnityMcpServer~/src | ||
| uv run pytest tests/ -v --tb=short | ||
|
|
||
| - name: Upload test results | ||
| uses: actions/upload-artifact@v4 | ||
| if: always() | ||
| with: | ||
| name: pytest-results | ||
| path: | | ||
| MCPForUnity/UnityMcpServer~/src/.pytest_cache/ | ||
| tests/ | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| using System; | ||
| using MCPForUnity.Editor.Helpers; | ||
| using Newtonsoft.Json.Linq; | ||
| using UnityEditor; | ||
|
|
||
| namespace MCPForUnity.Editor.Resources.Editor | ||
| { | ||
| /// <summary> | ||
| /// Provides information about the currently active editor tool. | ||
| /// </summary> | ||
| [McpForUnityResource("get_active_tool")] | ||
| public static class ActiveTool | ||
| { | ||
| public static object HandleCommand(JObject @params) | ||
| { | ||
| try | ||
| { | ||
| Tool currentTool = UnityEditor.Tools.current; | ||
| string toolName = currentTool.ToString(); | ||
| bool customToolActive = UnityEditor.Tools.current == Tool.Custom; | ||
| string activeToolName = customToolActive ? EditorTools.GetActiveToolName() : toolName; | ||
|
|
||
| var toolInfo = new | ||
| { | ||
| activeTool = activeToolName, | ||
| isCustom = customToolActive, | ||
| pivotMode = UnityEditor.Tools.pivotMode.ToString(), | ||
| pivotRotation = UnityEditor.Tools.pivotRotation.ToString(), | ||
| handleRotation = new | ||
| { | ||
| x = UnityEditor.Tools.handleRotation.eulerAngles.x, | ||
| y = UnityEditor.Tools.handleRotation.eulerAngles.y, | ||
| z = UnityEditor.Tools.handleRotation.eulerAngles.z | ||
| }, | ||
| handlePosition = new | ||
| { | ||
| x = UnityEditor.Tools.handlePosition.x, | ||
| y = UnityEditor.Tools.handlePosition.y, | ||
| z = UnityEditor.Tools.handlePosition.z | ||
| } | ||
| }; | ||
|
|
||
| return Response.Success("Retrieved active tool information.", toolInfo); | ||
| } | ||
| catch (Exception e) | ||
| { | ||
| return Response.Error($"Error getting active tool: {e.Message}"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Helper class for custom tool names | ||
| internal static class EditorTools | ||
| { | ||
| public static string GetActiveToolName() | ||
| { | ||
| if (UnityEditor.Tools.current == Tool.Custom) | ||
| { | ||
| return "Unknown Custom Tool"; | ||
| } | ||
| return UnityEditor.Tools.current.ToString(); | ||
| } | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| using System; | ||
| using MCPForUnity.Editor.Helpers; | ||
| using Newtonsoft.Json.Linq; | ||
| using UnityEditor; | ||
| using UnityEditor.SceneManagement; | ||
|
|
||
| namespace MCPForUnity.Editor.Resources.Editor | ||
| { | ||
| /// <summary> | ||
| /// Provides dynamic editor state information that changes frequently. | ||
| /// </summary> | ||
| [McpForUnityResource("get_editor_state")] | ||
| public static class EditorState | ||
| { | ||
| public static object HandleCommand(JObject @params) | ||
| { | ||
| try | ||
| { | ||
| var activeScene = EditorSceneManager.GetActiveScene(); | ||
| var state = new | ||
| { | ||
| isPlaying = EditorApplication.isPlaying, | ||
| isPaused = EditorApplication.isPaused, | ||
| isCompiling = EditorApplication.isCompiling, | ||
| isUpdating = EditorApplication.isUpdating, | ||
| timeSinceStartup = EditorApplication.timeSinceStartup, | ||
| activeSceneName = activeScene.name ?? "", | ||
| selectionCount = UnityEditor.Selection.count, | ||
| activeObjectName = UnityEditor.Selection.activeObject?.name | ||
| }; | ||
|
|
||
| return Response.Success("Retrieved editor state.", state); | ||
| } | ||
| catch (Exception e) | ||
| { | ||
| return Response.Error($"Error getting editor state: {e.Message}"); | ||
| } | ||
| } | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| using System; | ||
| using MCPForUnity.Editor.Helpers; | ||
| using Newtonsoft.Json.Linq; | ||
| using UnityEditor.SceneManagement; | ||
|
|
||
| namespace MCPForUnity.Editor.Resources.Editor | ||
| { | ||
| /// <summary> | ||
| /// Provides information about the current prefab editing context. | ||
| /// </summary> | ||
| [McpForUnityResource("get_prefab_stage")] | ||
| public static class PrefabStage | ||
| { | ||
| public static object HandleCommand(JObject @params) | ||
| { | ||
| try | ||
| { | ||
| PrefabStageUtility.GetCurrentPrefabStage(); | ||
| var stage = PrefabStageUtility.GetCurrentPrefabStage(); | ||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| if (stage == null) | ||
| { | ||
| return Response.Success("No prefab stage is currently open.", new { isOpen = false }); | ||
| } | ||
|
|
||
| var stageInfo = new | ||
| { | ||
| isOpen = true, | ||
| assetPath = stage.assetPath, | ||
| prefabRootName = stage.prefabContentsRoot?.name, | ||
| mode = stage.mode.ToString(), | ||
| isDirty = stage.scene.isDirty | ||
| }; | ||
|
|
||
| return Response.Success("Prefab stage info retrieved.", stageInfo); | ||
| } | ||
| catch (Exception e) | ||
| { | ||
| return Response.Error($"Error getting prefab stage info: {e.Message}"); | ||
| } | ||
| } | ||
| } | ||
| } | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| using System; | ||
| using System.Linq; | ||
| using MCPForUnity.Editor.Helpers; | ||
| using Newtonsoft.Json.Linq; | ||
| using UnityEditor; | ||
|
|
||
| namespace MCPForUnity.Editor.Resources.Editor | ||
| { | ||
| /// <summary> | ||
| /// Provides detailed information about the current editor selection. | ||
| /// </summary> | ||
| [McpForUnityResource("get_selection")] | ||
| public static class Selection | ||
| { | ||
| public static object HandleCommand(JObject @params) | ||
| { | ||
| try | ||
| { | ||
| var selectionInfo = new | ||
| { | ||
| activeObject = UnityEditor.Selection.activeObject?.name, | ||
| activeGameObject = UnityEditor.Selection.activeGameObject?.name, | ||
| activeTransform = UnityEditor.Selection.activeTransform?.name, | ||
| activeInstanceID = UnityEditor.Selection.activeInstanceID, | ||
| count = UnityEditor.Selection.count, | ||
| objects = UnityEditor.Selection.objects | ||
| .Select(obj => new | ||
| { | ||
| name = obj?.name, | ||
| type = obj?.GetType().FullName, | ||
| instanceID = obj?.GetInstanceID() | ||
| }) | ||
| .ToList(), | ||
| gameObjects = UnityEditor.Selection.gameObjects | ||
| .Select(go => new | ||
| { | ||
| name = go?.name, | ||
| instanceID = go?.GetInstanceID() | ||
| }) | ||
| .ToList(), | ||
| assetGUIDs = UnityEditor.Selection.assetGUIDs | ||
| }; | ||
|
|
||
| return Response.Success("Retrieved current selection details.", selectionInfo); | ||
| } | ||
| catch (Exception e) | ||
| { | ||
| return Response.Error($"Error getting selection: {e.Message}"); | ||
| } | ||
| } | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using MCPForUnity.Editor.Helpers; | ||
| using Newtonsoft.Json.Linq; | ||
| using UnityEditor; | ||
| using UnityEngine; | ||
|
|
||
| namespace MCPForUnity.Editor.Resources.Editor | ||
| { | ||
| /// <summary> | ||
| /// Provides list of all open editor windows. | ||
| /// </summary> | ||
| [McpForUnityResource("get_windows")] | ||
| public static class Windows | ||
| { | ||
| public static object HandleCommand(JObject @params) | ||
| { | ||
| try | ||
| { | ||
| EditorWindow[] allWindows = UnityEngine.Resources.FindObjectsOfTypeAll<EditorWindow>(); | ||
| var openWindows = new List<object>(); | ||
|
|
||
| foreach (EditorWindow window in allWindows) | ||
| { | ||
| if (window == null) | ||
| continue; | ||
|
|
||
| try | ||
| { | ||
| openWindows.Add(new | ||
| { | ||
| title = window.titleContent.text, | ||
| typeName = window.GetType().FullName, | ||
| isFocused = EditorWindow.focusedWindow == window, | ||
| position = new | ||
| { | ||
| x = window.position.x, | ||
| y = window.position.y, | ||
| width = window.position.width, | ||
| height = window.position.height | ||
| }, | ||
| instanceID = window.GetInstanceID() | ||
| }); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| Debug.LogWarning($"Could not get info for window {window.GetType().Name}: {ex.Message}"); | ||
| } | ||
| } | ||
|
|
||
| return Response.Success("Retrieved list of open editor windows.", openWindows); | ||
| } | ||
| catch (Exception e) | ||
| { | ||
| return Response.Error($"Error getting editor windows: {e.Message}"); | ||
| } | ||
| } | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.