-
Notifications
You must be signed in to change notification settings - Fork 693
fix: improve manage_scene screenshot capture #600
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
fix: improve manage_scene screenshot capture #600
Conversation
Reviewer's GuideCentralizes manage_scene screenshot capture through ScreenshotUtility, adds async-aware import handling for Game View captures, improves camera-based fallback behavior in Unity 2021.3, and tightens robustness/logging while updating developer docs to describe the new behavior. Sequence diagram for manage_scene async-aware screenshot capturesequenceDiagram
actor User
participant ManageScene
participant ScreenshotUtility
participant ScreenCapture
participant Camera
participant FileSystem
participant EditorApplication
participant AssetDatabase
User->>ManageScene: CaptureScreenshot(fileName, superSize)
ManageScene->>ManageScene: BestEffortPrepareGameViewForScreenshot()
ManageScene->>ScreenshotUtility: CaptureToAssetsFolder(fileName, resolvedSuperSize, ensureUniqueFileName)
alt Unity_2022_1_or_newer_async_GameView
ScreenshotUtility->>ScreenCapture: CaptureScreenshot(assetsRelativePath, size)
ScreenshotUtility-->>ManageScene: ScreenshotCaptureResult(IsAsync = true)
ManageScene->>ManageScene: ScheduleAssetImportWhenFileExists(assetsRelativePath, fullPath, timeoutSeconds)
ManageScene-->>User: SuccessResponse(isAsync = true)
loop Until_file_exists_or_timeout
EditorApplication-->>EditorApplication: update event invokes tick
EditorApplication->>FileSystem: File.Exists(fullPath)
alt File_exists
FileSystem-->>EditorApplication: true
EditorApplication->>AssetDatabase: ImportAsset(assetsRelativePath, ForceSynchronousImport)
EditorApplication-->>EditorApplication: unsubscribe tick
else Timeout
FileSystem-->>EditorApplication: false
EditorApplication-->>EditorApplication: check timeout and unsubscribe if exceeded
end
end
else Unity_2021_3_camera_fallback_sync
ScreenshotUtility->>Camera: FindBestCamera()
alt Camera_found
ScreenshotUtility->>Camera: CaptureFromCameraToAssetsFolder(camera, captureName, size, ensureUniqueFileName)
ScreenshotUtility-->>ManageScene: ScreenshotCaptureResult(IsAsync = false)
ManageScene->>AssetDatabase: ImportAsset(assetsRelativePath, ForceSynchronousImport)
ManageScene-->>User: SuccessResponse(isAsync = false)
else No_camera_found
ScreenshotUtility-->>ManageScene: throws InvalidOperationException
ManageScene-->>User: ErrorResponse("No camera found to capture screenshot.")
end
end
Note over ManageScene,User: Verb in success message reflects IsAsync ("Screenshot requested" vs "Screenshot captured")
Updated class diagram for screenshot capture utilities and ManageScene integrationclassDiagram
class ManageScene {
<<static>>
+object CaptureScreenshot(string fileName, int? superSize)
+void BestEffortPrepareGameViewForScreenshot()
+void ScheduleAssetImportWhenFileExists(string assetsRelativePath, string fullPath, double timeoutSeconds)
+object GetActiveSceneInfo()
+object BuildGameObjectSummary(GameObject go, bool includeTransform, int maxChildrenPerNode)
+string GetGameObjectPath(GameObject go)
}
class ScreenshotCaptureResult {
+ScreenshotCaptureResult(string fullPath, string assetsRelativePath, int superSize)
+ScreenshotCaptureResult(string fullPath, string assetsRelativePath, int superSize, bool isAsync)
+string FullPath
+string AssetsRelativePath
+int SuperSize
+bool IsAsync
}
class ScreenshotUtility {
<<static>>
-const string ScreenshotsFolderName
+ScreenshotCaptureResult CaptureToAssetsFolder(string fileName, int superSize, bool ensureUniqueFileName)
+ScreenshotCaptureResult CaptureFromCameraToAssetsFolder(Camera camera, string fileName, int superSize, bool ensureUniqueFileName)
-Camera FindBestCamera()
-string GetProjectRootPath()
}
class UnityEngine_Application {
+static bool isPlaying
+static bool isBatchMode
}
class UnityEditor_EditorApplication {
+static double timeSinceStartup
+static event Action update
+static bool ExecuteMenuItem(string menuPath)
+static void QueuePlayerLoopUpdate()
}
class UnityEditor_AssetDatabase {
+static void ImportAsset(string path, ImportAssetOptions options)
}
class UnityEditor_EditorWindow {
+static EditorWindow GetWindow(System.Type type)
+void Repaint()
}
class UnityEditor_SceneView {
+static void RepaintAll()
}
class UnityEngine_ScreenCapture {
+static void CaptureScreenshot(string filename, int superSize)
}
class UnityEngine_Camera {
+static Camera main
+RenderTexture targetTexture
+void Render()
}
class UnityEngine_RenderTexture {
+static RenderTexture GetTemporary(int width, int height, int depthBuffer, RenderTextureFormat format)
+static void ReleaseTemporary(RenderTexture temp)
+static RenderTexture active
}
class UnityEngine_Texture2D {
+Texture2D(int width, int height, TextureFormat textureFormat, bool mipChain)
+void ReadPixels(Rect source, int destX, int destY)
+void Apply()
+byte[] EncodeToPNG()
}
class System_IO_File {
+static void WriteAllBytes(string path, byte[] bytes)
+static bool Exists(string path)
}
class McpLog {
+static void Debug(string message)
}
ManageScene ..> ScreenshotUtility : uses
ManageScene ..> ScreenshotCaptureResult : creates
ManageScene ..> UnityEditor_AssetDatabase : imports_assets
ManageScene ..> UnityEditor_EditorApplication : schedules_update
ScreenshotUtility ..> ScreenshotCaptureResult : returns
ScreenshotUtility ..> UnityEngine_ScreenCapture : calls
ScreenshotUtility ..> UnityEngine_Camera : uses
ScreenshotUtility ..> UnityEngine_RenderTexture : uses
ScreenshotUtility ..> UnityEngine_Texture2D : uses
ScreenshotUtility ..> System_IO_File : writes_png
ManageScene ..> McpLog : debug_logging
ManageScene ..> System_IO_File : checks_exists
ManageScene ..> UnityEditor_EditorWindow : opens_GameView
ManageScene ..> UnityEditor_SceneView : repaints
ManageScene ..> UnityEngine_Application : checks_modes
ScreenshotUtility ..> UnityEngine_Application : checks_isPlaying
ManageScene ..> UnityEngine_Application : checks_isBatchMode
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Caution Review failedThe pull request is closed. Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughUnified screenshot capture flow with UI preparation and async-aware import scheduling; added camera selection and async flag to capture results; conditional object-finding for Unity 2023.1+; package/version bumps and documentation for manage_scene(action="screenshot"). Changes
Sequence Diagram(s)sequenceDiagram
participant Editor as Editor/ManageScene
participant UI as GameView/UI
participant Capture as ScreenshotUtility
participant FS as FileSystem
participant Importer as AssetImporter
Editor->>UI: EnsureGameView() / trigger repaints
Editor->>Capture: CaptureToAssetsFolder()
alt Unity 2022.1+
Capture->>Capture: ScreenCapture.CaptureScreenshot()\n(async write)
Capture-->>Editor: ScreenshotCaptureResult(IsAsync=true)
else older Unity
Capture->>Capture: FindAvailableCamera() -> RenderTexture -> PNG\n(sync write)
Capture-->>Editor: ScreenshotCaptureResult(IsAsync=false)
end
alt IsAsync = true
Editor->>Editor: ScheduleAssetImportWhenFileExists(path, timeout)
Editor->>FS: Poll for file existence
FS-->>Editor: File appears
Editor->>Importer: Import asset
Importer-->>Editor: Import complete
else IsAsync = false
Editor->>Importer: Import synchronously
Importer-->>Editor: Import complete
end
Editor-->>Editor: Log result (includes isAsync)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
There was a problem hiding this 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 3 issues, and left some high level feedback:
- There are a lot of broad
catch { }blocks in the new screenshot-related helpers (e.g.,BestEffortPrepareGameViewForScreenshot,ScheduleAssetImportWhenFileExists); consider narrowing these catches or adding at least optional/conditional logging so that unexpected failures don’t get completely masked during debugging. - In
ScreenshotUtility.CaptureToAssetsFolderon pre-2022 Unity, theDebug.LogWarningabout the ScreenCapture fallback will fire on every screenshot; consider downgrading this to aLogor gating it (e.g., only once) to avoid log noise when the tool is used frequently.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- There are a lot of broad `catch { }` blocks in the new screenshot-related helpers (e.g., `BestEffortPrepareGameViewForScreenshot`, `ScheduleAssetImportWhenFileExists`); consider narrowing these catches or adding at least optional/conditional logging so that unexpected failures don’t get completely masked during debugging.
- In `ScreenshotUtility.CaptureToAssetsFolder` on pre-2022 Unity, the `Debug.LogWarning` about the ScreenCapture fallback will fire on every screenshot; consider downgrading this to a `Log` or gating it (e.g., only once) to avoid log noise when the tool is used frequently.
## Individual Comments
### Comment 1
<location> `MCPForUnity/Runtime/Helpers/ScreenshotUtility.cs:83-89` </location>
<code_context>
#else
Debug.LogWarning("ScreenCapture is supported after Unity 2022.1. Using main camera capture as fallback.");
- CaptureFromCameraToAssetsFolder(Camera.main, captureName, size, false);
+ var cam = FindBestCamera();
+ if (cam == null)
+ {
+ throw new InvalidOperationException("No camera found to capture screenshot.");
+ }
+ string captureName = Path.GetFileName(normalizedFullPath);
+ CaptureFromCameraToAssetsFolder(cam, captureName, size, false);
+ isAsync = false;
#endif
</code_context>
<issue_to_address>
**question (bug_risk):** Clarify/align the returned paths with the actual file path used in the pre-2022 camera fallback.
In this path we compute `normalizedFullPath` / `assetsRelativePath` for `ScreenshotCaptureResult`, but the actual file path is recomputed inside `CaptureFromCameraToAssetsFolder` from the screenshots folder and `captureName`. If that method ever changes its folder/uniqueness rules, the returned `FullPath` / `AssetsRelativePath` may not match where the file is actually written. Consider having `CaptureFromCameraToAssetsFolder` return a `ScreenshotCaptureResult` and propagate its paths, or factor out the path-building into a shared helper so both code paths use identical logic.
</issue_to_address>
### Comment 2
<location> `MCPForUnity/Editor/Tools/ManageScene.cs:458-467` </location>
<code_context>
+ private static void ScheduleAssetImportWhenFileExists(string assetsRelativePath, string fullPath, double timeoutSeconds)
</code_context>
<issue_to_address>
**suggestion:** Consider surfacing timeout or failure information in the async import scheduler for easier diagnosis.
Right now the scheduler unsubscribes on timeout or exceptions without any signal to the caller. If the file never appears (e.g., permission issues or incorrect path), the only symptom is the missing asset. Consider logging a warning when the timeout is reached or when repeated failures occur (potentially wrapped in `#if UNITY_EDITOR`) so users can understand why the screenshot wasn’t imported, without adding heavy overhead to the polling loop.
Suggested implementation:
```csharp
private static void ScheduleAssetImportWhenFileExists(string assetsRelativePath, string fullPath, double timeoutSeconds)
{
if (string.IsNullOrWhiteSpace(assetsRelativePath) || string.IsNullOrWhiteSpace(fullPath))
{
return;
}
double start = EditorApplication.timeSinceStartup;
int failureCount = 0;
const int maxLoggedFailures = 3;
Action tick = null;
tick = () =>
{
// Stop polling if we've timed out
if (EditorApplication.timeSinceStartup - start > timeoutSeconds)
{
#if UNITY_EDITOR
Debug.LogWarning(
$"[ManageScene] Timed out waiting for asset at path '{fullPath}' (Assets relative: '{assetsRelativePath}') " +
$"after {timeoutSeconds:F1} seconds. The screenshot asset was not imported.");
#endif
EditorApplication.update -= tick;
return;
}
try
{
if (!System.IO.File.Exists(fullPath))
{
// Still waiting for the file to appear; keep polling.
return;
}
// File exists; import the asset.
AssetDatabase.ImportAsset(assetsRelativePath, ImportAssetOptions.ForceUpdate);
#if UNITY_EDITOR
Debug.Log($"[ManageScene] Imported asset at '{assetsRelativePath}' after detecting file on disk.");
#endif
EditorApplication.update -= tick;
}
catch (Exception ex)
{
failureCount++;
if (failureCount <= maxLoggedFailures)
{
#if UNITY_EDITOR
Debug.LogWarning(
$"[ManageScene] Exception while importing asset '{assetsRelativePath}' from '{fullPath}' " +
$"(attempt {failureCount}): {ex}");
#endif
}
// If failures are persistent beyond the first few attempts, stop polling to avoid spamming.
if (failureCount >= maxLoggedFailures)
{
#if UNITY_EDITOR
Debug.LogWarning(
$"[ManageScene] Stopping import polling for '{assetsRelativePath}' after {failureCount} failures.");
#endif
EditorApplication.update -= tick;
}
}
};
// Start polling on the editor update loop
EditorApplication.update += tick;
```
1. Ensure `using UnityEditor;` and `using UnityEngine;` are present at the top of `ManageScene.cs` so that `AssetDatabase`, `EditorApplication`, and `Debug` resolve correctly.
2. If this method is used for assets other than screenshots, you may want to adjust or generalize the log messages (e.g., remove "screenshot" wording or pass a context string into the method).
3. If there is already a centralized logging facility in this project, you may want to replace the direct `Debug.Log/LogWarning` calls with that logger to keep logs consistent.
</issue_to_address>
### Comment 3
<location> `docs/README-DEV.md:205` </location>
<code_context>
+### `manage_scene(action="screenshot")`
+
+- Saves PNGs under `Assets/Screenshots/`.
+- Unity **2022.1+**: captures the **Game View** via `ScreenCapture.CaptureScreenshot`, so `Screen Space - Overlay` UI is included. Note this write is **async**, so the file may appear/import a moment later.
+- Unity **2021.3**: falls back to rendering the best available `Camera` into a `RenderTexture` (camera output only; `Screen Space - Overlay` UI is not included).
+
</code_context>
<issue_to_address>
**nitpick (typo):** Consider adding "that" in "Note this write is async" for smoother grammar.
You could also rephrase to something like “This write is **async**, so the file may appear/import a moment later” if you want to make the note read more smoothly while emphasizing the async behavior.
```suggestion
- Unity **2022.1+**: captures the **Game View** via `ScreenCapture.CaptureScreenshot`, so `Screen Space - Overlay` UI is included. This write is **async**, so the file may appear/import a moment later.
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- Gate pre-2022 ScreenCapture fallback warning to log only once - Downgrade warning to Debug.Log to reduce log noise - Refactor path-building into shared PrepareCaptureResult() helper - Add conditional logging to catch blocks in BestEffortPrepareGameViewForScreenshot - Add timeout/failure logging to ScheduleAssetImportWhenFileExists - Fix grammar in README-DEV.md
|
@toxifly can you do a before and after screenshot, visuals will definitely help with a change like this 🙂 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@MCPForUnity/Editor/Tools/GameObjects/ManageGameObjectCommon.cs`:
- Around line 157-166: The current use of FindObjectsSortMode.None in the
FindObjectsByType call can change which object is returned when only the first
match is used (see findAll), so change the sort mode based on whether findAll is
requested: when findAll is false use FindObjectsSortMode.InstanceID to retain
legacy deterministic ordering, otherwise use FindObjectsSortMode.None (or the
existing behavior); update the FindObjectsByType invocation that sets
searchPoolComp (using componentType and searchInactive) to pick the sort mode
conditionally so the first selected gameObject remains stable.
🧹 Nitpick comments (1)
MCPForUnity/Editor/Tools/ManageScene.cs (1)
476-546: Consider waiting for file size to stabilize before importing.If
ScreenCapture.CaptureScreenshotcreates the file before the write completes, importing immediately onFile.Existsmay still race. A lightweight “stable size for N ticks” guard can avoid partial imports on some platforms.🛠️ Example stabilization guard
- bool hasSeenFile = false; + bool hasSeenFile = false; + long lastSize = -1; + int stableTicks = 0; + const int requiredStableTicks = 2; EditorApplication.CallbackFunction tick = null; tick = () => { try { if (File.Exists(fullPath)) { hasSeenFile = true; - - AssetDatabase.ImportAsset(assetsRelativePath, ImportAssetOptions.ForceSynchronousImport); + long size = new FileInfo(fullPath).Length; + if (size <= 0) + { + return; + } + if (size == lastSize) stableTicks++; + else { stableTicks = 0; lastSize = size; } + if (stableTicks < requiredStableTicks) return; + + AssetDatabase.ImportAsset(assetsRelativePath, ImportAssetOptions.ForceSynchronousImport); try { McpLog.Debug($"[ManageScene] Imported asset at '{assetsRelativePath}'."); } catch { } EditorApplication.update -= tick; return; } }
| #if UNITY_2023_1_OR_NEWER | ||
| var inactive = searchInactive ? FindObjectsInactive.Include : FindObjectsInactive.Exclude; | ||
| searchPoolComp = UnityEngine.Object.FindObjectsByType(componentType, inactive, FindObjectsSortMode.None) | ||
| .Cast<Component>() | ||
| .Select(c => c.gameObject); | ||
| #else | ||
| searchPoolComp = UnityEngine.Object.FindObjectsOfType(componentType, searchInactive) | ||
| .Cast<Component>() | ||
| .Select(c => c.gameObject); | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, find the file
find . -name "ManageGameObjectCommon.cs" -type fRepository: CoplayDev/unity-mcp
Length of output: 127
🏁 Script executed:
# Read the file around the specified lines to understand context
cat -n MCPForUnity/Editor/Tools/GameObjects/ManageGameObjectCommon.cs | sed -n '140,180p'Repository: CoplayDev/unity-mcp
Length of output: 2371
🏁 Script executed:
# Search for findAll variable usage in the file
rg -n "findAll" MCPForUnity/Editor/Tools/GameObjects/ManageGameObjectCommon.csRepository: CoplayDev/unity-mcp
Length of output: 370
🏁 Script executed:
# Read the broader context to see how findAll is used and what happens when it's false
cat -n MCPForUnity/Editor/Tools/GameObjects/ManageGameObjectCommon.cs | sed -n '1,50p'Repository: CoplayDev/unity-mcp
Length of output: 2302
🏁 Script executed:
# Check what happens around line 209 where findAll is used
cat -n MCPForUnity/Editor/Tools/GameObjects/ManageGameObjectCommon.cs | sed -n '200,220p'Repository: CoplayDev/unity-mcp
Length of output: 1026
🏁 Script executed:
# Look at the FindObjectsInternal method signature and overall structure
cat -n MCPForUnity/Editor/Tools/GameObjects/ManageGameObjectCommon.cs | sed -n '30,45p'Repository: CoplayDev/unity-mcp
Length of output: 812
🏁 Script executed:
# Check if there are other search methods to understand the pattern
cat -n MCPForUnity/Editor/Tools/GameObjects/ManageGameObjectCommon.cs | sed -n '50,180p'Repository: CoplayDev/unity-mcp
Length of output: 7042
🌐 Web query:
FindObjectsOfType InstanceID sorting Unity documentation
💡 Result:
Short answer: Unity's Object.FindObjectsOfType always sorts its results by InstanceID. Use Object.FindObjectsByType with FindObjectsSortMode.None if you don't need sorting (faster). [1][2][3]
Sources:
- Unity docs: Object.FindObjectsOfType (notes it always sorts by InstanceID; recommends FindObjectsByType). [1]
- Unity docs: FindObjectsSortMode enum (InstanceID vs None). [2]
- Community confirmation / example showing ordering by GetInstanceID. [3]
🌐 Web query:
FindObjectsByType FindObjectsSortMode.None documentation Unity 2023.1
💡 Result:
FindObjectsByType is documented in the Unity 2023.1 Scripting API. Use the FindObjectsSortMode.None option to return results unsorted (fastest, order not guaranteed).
Key points
- Signature/examples: Object.FindObjectsByType(Type type, FindObjectsSortMode sortMode) and generic overloads (also overloads with FindObjectsInactive). Example: FindObjectsByType(FindObjectsSortMode.None). [1]
- FindObjectsSortMode.None: "Don't sort the objects." It's the least resource‑intensive option; result order may vary between calls. [2]
- Notes: This API finds loaded (non-asset) objects; it doesn't return assets or objects with HideFlags.DontSave. Use Resources.FindObjectsOfTypeAll to include assets. FindObjectsOfType (legacy) is deprecated in favor of FindObjectsByType which lets you choose sorting. [3]
Example
- C#: var found = FindObjectsByType(FindObjectsSortMode.None); [1]
Sources
[1] Unity Scripting API — Object.FindObjectsByType (2023.1).
[2] Unity Scripting API — FindObjectsSortMode.None.
[3] Unity Scripting API — Object.FindObjectsOfType (notes on deprecation and behavior).
Preserve deterministic selection when only returning first match.
FindObjectsSortMode.None produces unsorted results, whereas the previous FindObjectsOfType always returns results sorted by InstanceID. Since the code returns only the first match when findAll is false (line 211), this sorting change can alter which object is selected. To preserve legacy behavior, use FindObjectsSortMode.InstanceID when findAll is false.
🔧 Suggested adjustment
`#if` UNITY_2023_1_OR_NEWER
var inactive = searchInactive ? FindObjectsInactive.Include : FindObjectsInactive.Exclude;
+ var sortMode = findAll ? FindObjectsSortMode.None : FindObjectsSortMode.InstanceID;
- searchPoolComp = UnityEngine.Object.FindObjectsByType(componentType, inactive, FindObjectsSortMode.None)
+ searchPoolComp = UnityEngine.Object.FindObjectsByType(componentType, inactive, sortMode)
.Cast<Component>()
.Select(c => c.gameObject);
`#else`
searchPoolComp = UnityEngine.Object.FindObjectsOfType(componentType, searchInactive)
.Cast<Component>()
.Select(c => c.gameObject);
`#endif`📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| #if UNITY_2023_1_OR_NEWER | |
| var inactive = searchInactive ? FindObjectsInactive.Include : FindObjectsInactive.Exclude; | |
| searchPoolComp = UnityEngine.Object.FindObjectsByType(componentType, inactive, FindObjectsSortMode.None) | |
| .Cast<Component>() | |
| .Select(c => c.gameObject); | |
| #else | |
| searchPoolComp = UnityEngine.Object.FindObjectsOfType(componentType, searchInactive) | |
| .Cast<Component>() | |
| .Select(c => c.gameObject); | |
| #endif | |
| `#if` UNITY_2023_1_OR_NEWER | |
| var inactive = searchInactive ? FindObjectsInactive.Include : FindObjectsInactive.Exclude; | |
| var sortMode = findAll ? FindObjectsSortMode.None : FindObjectsSortMode.InstanceID; | |
| searchPoolComp = UnityEngine.Object.FindObjectsByType(componentType, inactive, sortMode) | |
| .Cast<Component>() | |
| .Select(c => c.gameObject); | |
| `#else` | |
| searchPoolComp = UnityEngine.Object.FindObjectsOfType(componentType, searchInactive) | |
| .Cast<Component>() | |
| .Select(c => c.gameObject); | |
| `#endif` |
🤖 Prompt for AI Agents
In `@MCPForUnity/Editor/Tools/GameObjects/ManageGameObjectCommon.cs` around lines
157 - 166, The current use of FindObjectsSortMode.None in the FindObjectsByType
call can change which object is returned when only the first match is used (see
findAll), so change the sort mode based on whether findAll is requested: when
findAll is false use FindObjectsSortMode.InstanceID to retain legacy
deterministic ordering, otherwise use FindObjectsSortMode.None (or the existing
behavior); update the FindObjectsByType invocation that sets searchPoolComp
(using componentType and searchInactive) to pick the sort mode conditionally so
the first selected gameObject remains stable.
177c786 to
e45052b
Compare
e45052b to
20b9188
Compare
To clear things up: screenshots were working before, but only when in play mode: Before (origin/main)
After (this branch)
|
Update main for new workflow
chore: bump version to 9.2.0
|
Hi! Looks like this is a very important fix! Can you resolve the Readme conflicts first? I will try it in the mean time and merge it to the beta branch. Thanks! |
Done. |


Description
Fixes manage_scene screenshot captures that could appear blank in UI-heavy scenes by preferring Game View capture when available and handling async screenshot import timing.
Also cleans up related implementation details.
Type of Change
Changes Made
Testing/Screenshots/Recordings
Related Issues
Additional Notes
Summary by Sourcery
Unify manage_scene screenshot capture through ScreenshotUtility to prefer Game View screenshots when available and handle async file import, while cleaning up related scene inspection utilities and docs.
Bug Fixes:
Enhancements:
Documentation:
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.