Skip to content

refactor: drop defensive scaffolding made obsolete by module dep declarations#1168

Merged
Scriptwonder merged 1 commit into
CoplayDev:betafrom
Scriptwonder:refactor/cleanup-post-module-deps
May 26, 2026
Merged

refactor: drop defensive scaffolding made obsolete by module dep declarations#1168
Scriptwonder merged 1 commit into
CoplayDev:betafrom
Scriptwonder:refactor/cleanup-post-module-deps

Conversation

@Scriptwonder
Copy link
Copy Markdown
Collaborator

@Scriptwonder Scriptwonder commented May 26, 2026

Summary

Follow-up to #1122 (declared the Physics 2D / Screen Capture / Image Conversion / etc. modules as required deps in package.json). Now that Unity Package Manager keeps those modules enabled while MCP for Unity is installed, two defensive layers that protected against the now-impossible "module disabled" case are dead code. Plus one sub-floor #if gate that was always-true on our unity: 2021.3 floor.

Net: +15 / -144 across 6 files.

Premise check

What needs to stay constant for the cleanup to be safe (validated against the CI matrix in tools/unity-versions.json: 2021.3.45f2 → 2022.3.62f1 → 6000.0.75f1 → 6000.4.8f1):

Symbol Stable since
typeof(Physics2D) Always — in UnityEngine for ~15 years
ScreenCapture.CaptureScreenshot(string, int) Unity 2017
ScreenCapture.CaptureScreenshotAsTexture(int) Unity 2017
com.unity.modules.physics2d built-in Unity 2019.3
com.unity.modules.screencapture built-in Unity 2019.3

All five span the entire supported matrix. The dep declarations from #1122 force the modules to be present, which makes typeof(...) and direct ScreenCapture.X calls safe.

What stays reflective (and should): the property lookups inside UnityPhysicsCompat.cs (autoSyncTransforms, simulationMode) — those are for property-level deprecations in Unity 6.x, a different concern from module presence.

Changes

Tier 1A — UnityPhysicsCompat.cs

Revert Type.GetType(\"UnityEngine.Physics2D, UnityEngine.Physics2DModule\") to typeof(Physics2D). Drop the Physics2DTypeName const and the file-level doc paragraph claiming the file compiles when the module is disabled.

Tier 1B — TrailControl.cs

Strip the #if UNITY_2021_1_OR_NEWER / #else gate around tr.AddPosition(pos). Package floor is 2021.3, so the #else branch ("AddPosition requires Unity 2021.1+") was unreachable.

Tier 2 — ScreenshotUtility.cs + callers

  • Remove IsScreenCaptureModuleAvailable public property, ScreenCaptureModuleNotAvailableError constant, InvokeCaptureScreenshotAsTexture helper, and the three reflection caches (s_screenCaptureModuleAvailable, s_captureScreenshotMethod, s_captureScreenshotAsTextureMethod).
  • Replace MethodInfo.Invoke calls with direct ScreenCapture.CaptureScreenshot(...) / ScreenCapture.CaptureScreenshotAsTexture(...) in CaptureToProjectFolder, CaptureComposited, and the ScreenshotCapturer MonoBehaviour.
  • Camera-based fallback path is preserved (FindAvailableCamera + CaptureFromCameraToProjectFolder) — it still handles transient null returns from ScreenCapture inside CaptureComposited.
  • Drop the pre-flight if (!IsScreenCaptureModuleAvailable) gates in ManageUI.cs (UI render flow) and ManageScene.cs (screenshot flow). The 2022.1+/2021.3 split in ManageScene.cs is preserved — that's about ScreenCapture not behaving identically on the floor version, separate concern.
  • ProjectInfo.cs (mcpforunity://project/info resource): screenCapture field is now hardcoded true. Preserves the resource shape for any consumer that reads it.

Explicitly out of scope

  • The reflective CompilationPipeline.isCompiling lookups in 4 bridge/service files (originally my proposed "Tier 1C") are not touched here — there are open PRs in that area, so leaving for a separate cleanup pass.

Test plan

  • Recommend labelling full-matrix so the cleanup runs against 2021.3.45f2 + 2022.3.62f1 + 6000.0.75f1 + 6000.4.8f1.
  • Smoke-test in a real Unity project that manage_camera action=screenshot still produces a valid PNG (camera-based path + ScreenCapture path).
  • Smoke-test that manage_ui action=render_ui still queues + returns the play-mode capture.
  • No new tests added — this is pure removal of code paths that cannot fire with the current declared deps.

Related

Summary by CodeRabbit

  • Bug Fixes
    • Improved screen capture reliability by streamlining capture logic and removing conditions that could prevent screenshots in certain scenarios.
    • Enhanced trail renderer consistency by ensuring position tracking works uniformly across all supported Unity versions.
    • Refined Physics 2D compatibility handling for more robust runtime property resolution.

Review Change Stack

…arations (CoplayDev#1122)

Since CoplayDev#1122 declared the Physics 2D, Screen Capture, Image Conversion, etc.
built-in modules as required deps in package.json, Unity Package Manager now
keeps them enabled while MCP for Unity is installed. Two defensive layers
that protected against the now-impossible "module disabled" case become dead
code, plus one sub-floor preprocessor gate that was always-true on our
declared `unity: 2021.3` floor.

Tier 1A — UnityPhysicsCompat.cs
- Revert `Type.GetType("UnityEngine.Physics2D, UnityEngine.Physics2DModule")`
  to `typeof(Physics2D)`. The property-level reflection (for `autoSyncTransforms`
  deprecation in Unity 6.x) stays — that's a different concern.

Tier 1B — TrailControl.cs
- Strip `#if UNITY_2021_1_OR_NEWER` gate. Package floor is 2021.3 per
  package.json, so the `#else` branch ("AddPosition requires Unity 2021.1+")
  is unreachable.

Tier 2 — ScreenshotUtility.cs + callers
- Remove `IsScreenCaptureModuleAvailable` property, `ScreenCaptureModuleNotAvailableError`
  constant, `InvokeCaptureScreenshotAsTexture` helper, and the
  `s_captureScreenshotMethod` / `s_captureScreenshotAsTextureMethod` /
  `s_screenCaptureModuleAvailable` reflection caches.
- Replace reflective `MethodInfo.Invoke` calls with direct `ScreenCapture.X`
  calls in `CaptureToProjectFolder`, `CaptureComposited`, and the
  `ScreenshotCapturer` MonoBehaviour.
- Camera-based fallback path (`FindAvailableCamera` + `CaptureFromCameraToProjectFolder`)
  is preserved — it still handles transient null returns from `ScreenCapture`
  inside `CaptureComposited`.
- Drop pre-flight `if (!IsScreenCaptureModuleAvailable)` gates in
  `ManageUI.cs` (UI render) and `ManageScene.cs` (screenshot path).
- `ProjectInfo` resource: `screenCapture` field is now an invariant `true`
  (preserves API shape for `mcpforunity://project/info` consumers).

Net: 144 lines removed, 15 added. No new tests — the changes are pure
removal of code paths that cannot fire with the current deps declared.

Related: CoplayDev#1160, CoplayDev#1122.
Copilot AI review requested due to automatic review settings May 26, 2026 08:14
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

📝 Walkthrough

Walkthrough

This PR removes runtime Screen Capture module availability checks and reflection-based fallback paths throughout the screenshot pipeline. ScreenshotUtility is simplified to call Unity's direct ScreenCapture APIs, and dependent code in ManageScene, ManageUI, and ProjectInfo is updated accordingly. Minor version-gating removals in TrailControl and UnityPhysicsCompat follow the same simplification pattern.

Changes

Screenshot capture pipeline and module availability consolidation

Layer / File(s) Summary
ScreenshotUtility public API and module availability removal
MCPForUnity/Runtime/Helpers/ScreenshotUtility.cs
Public property IsScreenCaptureModuleAvailable, constant ScreenCaptureModuleNotAvailableError, and internal reflection helper InvokeCaptureScreenshotAsTexture are removed, eliminating runtime module detection.
ScreenshotUtility capture method simplification
MCPForUnity/Runtime/Helpers/ScreenshotUtility.cs
CaptureToProjectFolder and CaptureComposited no longer perform module-availability checks or use reflection; they call ScreenCapture APIs directly. Play-mode end-of-frame compositing routing is removed. ScreenshotCapturer.Start uses direct ScreenCapture.CaptureScreenshotAsTexture instead of reflection.
ManageScene and ManageUI screenshot pipeline updates
MCPForUnity/Editor/Tools/ManageScene.cs, MCPForUnity/Editor/Tools/ManageUI.cs
ManageScene simplifies to check only Unity version for camera fallback (pre-2022.1), removing module-availability logic. ManageUI removes preflight module check before queuing captures.
ProjectInfo screenshot capability reporting
MCPForUnity/Editor/Resources/Project/ProjectInfo.cs
screenCapture field changes from computed IsScreenCaptureModuleAvailable check to constant true.
TrailControl and UnityPhysicsCompat version-gating removal
MCPForUnity/Editor/Tools/Vfx/TrailControl.cs, MCPForUnity/Runtime/Helpers/UnityPhysicsCompat.cs
TrailControl.Emit unconditionally handles position emission via AddPosition, removing Unity 2021.1+ conditional compilation. UnityPhysicsCompat uses typeof(Physics2D).GetProperty(...) instead of fallback string-based type resolution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • CoplayDev/unity-mcp#661: Reverses earlier ScreenCapture-module-availability checks and fallback behavior that this PR removes.
  • CoplayDev/unity-mcp#1132: Directly related; modifies the same ScreenshotUtility.CaptureComposited/ScreenshotCapturer behavior and end-of-frame routing that this PR eliminates.
  • CoplayDev/unity-mcp#1122: Adds the required com.unity.modules.screencapture dependency to ensure the ScreenCapture APIs this PR now assumes are always available.

Suggested reviewers

  • dsarno

Poem

🐰 A rabbit hops through module checks—
Gone are the fallback shims and wrecks,
Direct to ScreenCapture we go,
No more reflection's murky glow!
Clean paths ahead, our vision clear—
Much simpler code for all to cheer!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main change: removing defensive code made obsolete by module dependency declarations. It is concise, specific, and clearly summarizes the primary refactoring objective.
Description check ✅ Passed The description is comprehensive and well-structured, covering premise validation, detailed changes across all tiers, scope boundaries, and a clear test plan. It follows the repository template with appropriate sections.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes defensive “module disabled” scaffolding that became obsolete after #1122 declared the relevant Unity built-in modules (Physics2D / ScreenCapture / ImageConversion, etc.) as required dependencies in MCPForUnity/package.json. It simplifies Runtime and Editor code paths by replacing reflection-based module detection with direct API usage, while keeping the existing cross-version property-level reflection in UnityPhysicsCompat.

Changes:

  • Runtime: revert Physics2D type resolution back to typeof(Physics2D) and simplify UnityPhysicsCompat docs accordingly.
  • Runtime: remove ScreenCapture module availability checks/reflection caches and call ScreenCapture.CaptureScreenshot* directly; preserve camera fallback only for the “ScreenCapture returned null” case.
  • Editor: remove unreachable Unity-version gate in TrailControl, and remove preflight ScreenCapture-module checks in UI/scene tools; hardcode ProjectInfo.packages.screenCapture = true.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
MCPForUnity/Runtime/Helpers/UnityPhysicsCompat.cs Drops module-disabled type lookup and uses typeof(Physics2D) while keeping property reflection for deprecation/removal resilience.
MCPForUnity/Runtime/Helpers/ScreenshotUtility.cs Removes ScreenCapture module detection/reflection and uses direct ScreenCapture calls; keeps runtime null-return fallback to camera capture.
MCPForUnity/Editor/Tools/Vfx/TrailControl.cs Removes an unreachable #if UNITY_2021_1_OR_NEWER branch given the package floor (2021.3).
MCPForUnity/Editor/Tools/ManageUI.cs Removes now-obsolete preflight rejection based on ScreenCapture module availability.
MCPForUnity/Editor/Tools/ManageScene.cs Removes ScreenCapture module availability branching; retains version-specific camera requirement behavior for older Unity versions.
MCPForUnity/Editor/Resources/Project/ProjectInfo.cs Keeps API shape but makes screenCapture capability an invariant true.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
MCPForUnity/Editor/Tools/ManageScene.cs (1)

681-690: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Move Unity version gating into UnityCompatShims

Line 682 adds a call-site #if UNITY_* branch in ManageScene. Please centralize this in MCPForUnity/Runtime/Helpers/UnityCompatShims.cs and call a shim method here.

♻️ Proposed refactor
-                // Default path: ScreenCapture API for 2022.1+, camera fallback required on older versions.
-#if !UNITY_2022_1_OR_NEWER
-                bool hasCameraFallback = Camera.main != null || UnityFindObjectsCompat.FindAll<Camera>().Length > 0;
-                if (!hasCameraFallback)
-                {
-                    return new ErrorResponse(
-                        "No camera found in the scene. Screenshot capture on Unity versions before 2022.1 requires a Camera in the scene."
-                    );
-                }
-#endif
+                // Default path: ScreenCapture API for 2022.1+, camera fallback required on older versions.
+                if (UnityCompatShims.RequiresCameraFallbackForScreenCapture())
+                {
+                    bool hasCameraFallback = Camera.main != null || UnityFindObjectsCompat.FindAll<Camera>().Length > 0;
+                    if (!hasCameraFallback)
+                    {
+                        return new ErrorResponse(
+                            "No camera found in the scene. Screenshot capture on Unity versions before 2022.1 requires a Camera in the scene."
+                        );
+                    }
+                }
// MCPForUnity/Runtime/Helpers/UnityCompatShims.cs
public static bool RequiresCameraFallbackForScreenCapture()
{
`#if` !UNITY_2022_1_OR_NEWER
    return true;
`#else`
    return false;
`#endif`
}

As per coding guidelines: MCPForUnity/**/*.cs: Unity API compatibility shims must be added to MCPForUnity/Runtime/Helpers/UnityCompatShims.cs rather than using #if UNITY_*_OR_NEWER at call sites across the codebase.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@MCPForUnity/Editor/Tools/ManageScene.cs` around lines 681 - 690, Replace the
call-site preprocessor check in ManageScene (around the camera-fallback logic)
with a call to a new shim method:
UnityCompatShims.RequiresCameraFallbackForScreenCapture(); implement that shim
in MCPForUnity/Runtime/Helpers/UnityCompatShims.cs using the same `#if`
!UNITY_2022_1_OR_NEWER / else compile-time branches to return true/false. In
ManageScene.cs, call the shim and, if it returns true, perform the existing
Camera.main / UnityFindObjectsCompat.FindAll<Camera>().Length check and return
the same ErrorResponse when no camera is found; remove the local `#if` UNITY_*
block so the version gating lives solely in UnityCompatShims.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@MCPForUnity/Editor/Tools/ManageScene.cs`:
- Around line 681-690: Replace the call-site preprocessor check in ManageScene
(around the camera-fallback logic) with a call to a new shim method:
UnityCompatShims.RequiresCameraFallbackForScreenCapture(); implement that shim
in MCPForUnity/Runtime/Helpers/UnityCompatShims.cs using the same `#if`
!UNITY_2022_1_OR_NEWER / else compile-time branches to return true/false. In
ManageScene.cs, call the shim and, if it returns true, perform the existing
Camera.main / UnityFindObjectsCompat.FindAll<Camera>().Length check and return
the same ErrorResponse when no camera is found; remove the local `#if` UNITY_*
block so the version gating lives solely in UnityCompatShims.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 653d5d3e-b664-4ff0-ae31-ab6e7772a28d

📥 Commits

Reviewing files that changed from the base of the PR and between ce98a2c and c56337e.

📒 Files selected for processing (6)
  • MCPForUnity/Editor/Resources/Project/ProjectInfo.cs
  • MCPForUnity/Editor/Tools/ManageScene.cs
  • MCPForUnity/Editor/Tools/ManageUI.cs
  • MCPForUnity/Editor/Tools/Vfx/TrailControl.cs
  • MCPForUnity/Runtime/Helpers/ScreenshotUtility.cs
  • MCPForUnity/Runtime/Helpers/UnityPhysicsCompat.cs
💤 Files with no reviewable changes (2)
  • MCPForUnity/Editor/Tools/Vfx/TrailControl.cs
  • MCPForUnity/Editor/Tools/ManageUI.cs

@Scriptwonder Scriptwonder added safe-to-test Triggers CI checks full-matrix Enable full-matrix CI test labels May 26, 2026
@Scriptwonder Scriptwonder merged commit e0d6a77 into CoplayDev:beta May 26, 2026
9 of 15 checks passed
@Scriptwonder Scriptwonder deleted the refactor/cleanup-post-module-deps branch May 26, 2026 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

full-matrix Enable full-matrix CI test safe-to-test Triggers CI checks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants