Skip to content

Commit 1fba429

Browse files
committed
Update0503
1.Add Compat based scripts revolving around UnityCompatShims.cs, that will document our current API Compatibility changes in several files. 2.Add custom screenshot folder selection
1 parent 81c5759 commit 1fba429

30 files changed

Lines changed: 1017 additions & 178 deletions

CLAUDE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ Use `CommandRegistry.InvokeCommandAsync` to call other tools from within a handl
140140
var result = await CommandRegistry.InvokeCommandAsync("read_console", consoleParams);
141141
```
142142

143+
### Unity API Compatibility Shims
144+
We support a wide Unity version range (2021+ → 6.x → CoreCLR 6.8). When an API is renamed, deprecated, or removed across versions, **don't sprinkle `#if UNITY_x_y_OR_NEWER` at every call site** — add a shim in `MCPForUnity/Runtime/Helpers/Unity*Compat.cs` and route every caller through it.
145+
146+
The catalog of active shims, the policy for when to add one, what does NOT belong in a shim, and the reflection-cache pattern all live in **`MCPForUnity/Runtime/Helpers/UnityCompatShims.cs`** — the XML doc on that empty marker class is the source of truth and ships inside the UPM package, so end-users can `F12`/Go-to-definition into it. Sources for current deprecations: Unity 6.x upgrade guides and the [CoreCLR 2026 thread](https://discussions.unity.com/t/path-to-coreclr-2026-upgrade-guide/1714279).
147+
143148
## Commands
144149

145150
### Running Tests

MCPForUnity/Editor/Helpers/EditorWindowScreenshotUtility.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ namespace MCPForUnity.Editor.Helpers
1616
/// </summary>
1717
internal static class EditorWindowScreenshotUtility
1818
{
19-
private const string ScreenshotsFolderName = "Screenshots";
2019
// Keep capture synchronous so callers can immediately return the screenshot payload.
2120
// The short sleep gives Unity a chance to flush repaint work before GrabPixels reads the viewport.
2221
private const int RepaintSettlingDelayMs = 75;
@@ -40,15 +39,16 @@ internal static class EditorWindowScreenshotUtility
4039
/// <param name="maxResolution">Maximum edge length for the inline image payload.</param>
4140
/// <param name="viewportWidth">Captured viewport width in pixels.</param>
4241
/// <param name="viewportHeight">Captured viewport height in pixels.</param>
43-
public static ScreenshotCaptureResult CaptureSceneViewViewportToAssets(
42+
public static ScreenshotCaptureResult CaptureSceneViewViewportToProject(
4443
SceneView sceneView,
4544
string fileName,
4645
int superSize,
4746
bool ensureUniqueFileName,
4847
bool includeImage,
4948
int maxResolution,
5049
out int viewportWidth,
51-
out int viewportHeight)
50+
out int viewportHeight,
51+
string folderOverride = null)
5252
{
5353
if (sceneView == null)
5454
throw new ArgumentNullException(nameof(sceneView));
@@ -70,7 +70,7 @@ public static ScreenshotCaptureResult CaptureSceneViewViewportToAssets(
7070
{
7171
captured = CaptureViewRect(sceneView, viewportRectPixels);
7272

73-
var result = PrepareCaptureResult(fileName, effectiveSuperSize, ensureUniqueFileName);
73+
var result = PrepareCaptureResult(fileName, effectiveSuperSize, ensureUniqueFileName, folderOverride);
7474
byte[] png = captured.EncodeToPNG();
7575
File.WriteAllBytes(result.FullPath, png);
7676

@@ -97,7 +97,7 @@ public static ScreenshotCaptureResult CaptureSceneViewViewportToAssets(
9797

9898
return new ScreenshotCaptureResult(
9999
result.FullPath,
100-
result.AssetsRelativePath,
100+
result.ProjectRelativePath,
101101
result.SuperSize,
102102
false,
103103
imageBase64,
@@ -317,11 +317,11 @@ private static void FlipTextureVertically(Texture2D texture)
317317
texture.Apply();
318318
}
319319

320-
private static ScreenshotCaptureResult PrepareCaptureResult(string fileName, int superSize, bool ensureUniqueFileName)
320+
private static ScreenshotCaptureResult PrepareCaptureResult(string fileName, int superSize, bool ensureUniqueFileName, string folderOverride)
321321
{
322322
int size = Mathf.Max(1, superSize);
323323
string resolvedName = BuildFileName(fileName);
324-
string folder = Path.Combine(Application.dataPath, ScreenshotsFolderName);
324+
string folder = ScreenshotUtility.ResolveFolderAbsolute(folderOverride);
325325
Directory.CreateDirectory(folder);
326326

327327
string fullPath = Path.Combine(folder, resolvedName);
@@ -331,8 +331,12 @@ private static ScreenshotCaptureResult PrepareCaptureResult(string fileName, int
331331
}
332332

333333
string normalizedFullPath = fullPath.Replace('\\', '/');
334-
string assetsRelativePath = "Assets/" + normalizedFullPath.Substring(Application.dataPath.Length).TrimStart('/');
335-
return new ScreenshotCaptureResult(normalizedFullPath, assetsRelativePath, size, false);
334+
string projectRoot = Path.GetFullPath(Path.Combine(Application.dataPath, "..")).Replace('\\', '/');
335+
string normalizedRoot = projectRoot.EndsWith("/") ? projectRoot : projectRoot + "/";
336+
string projectRelativePath = normalizedFullPath.StartsWith(normalizedRoot, StringComparison.OrdinalIgnoreCase)
337+
? normalizedFullPath.Substring(normalizedRoot.Length)
338+
: normalizedFullPath;
339+
return new ScreenshotCaptureResult(normalizedFullPath, projectRelativePath, size, false);
336340
}
337341

338342
private static string BuildFileName(string fileName)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using MCPForUnity.Runtime.Helpers;
2+
using UnityEditor;
3+
4+
namespace MCPForUnity.Editor.Helpers
5+
{
6+
/// <summary>
7+
/// Per-user EditorPrefs override for the default screenshot output folder.
8+
/// Resolution priority used by callers:
9+
/// 1. Per-call <c>output_folder</c> tool parameter
10+
/// 2. <see cref="DefaultFolder"/> (this preference)
11+
/// 3. <see cref="ScreenshotUtility.DefaultFolder"/> built-in fallback
12+
/// </summary>
13+
public static class ScreenshotPreferences
14+
{
15+
public const string EditorPrefsKey = "MCPForUnity_ScreenshotsFolder";
16+
17+
/// <summary>
18+
/// User-configured default folder, or empty string when unset.
19+
/// Stored as a project-relative path (e.g. "Assets/Screenshots", "Captures").
20+
/// </summary>
21+
public static string DefaultFolder
22+
{
23+
get => EditorPrefs.GetString(EditorPrefsKey, string.Empty);
24+
set
25+
{
26+
if (string.IsNullOrWhiteSpace(value))
27+
{
28+
EditorPrefs.DeleteKey(EditorPrefsKey);
29+
}
30+
else
31+
{
32+
EditorPrefs.SetString(EditorPrefsKey, value.Trim());
33+
}
34+
}
35+
}
36+
37+
/// <summary>
38+
/// Resolves the effective folder: caller override → user pref → built-in default.
39+
/// Returns a project-relative path string suitable for <see cref="ScreenshotUtility.ResolveFolderAbsolute"/>.
40+
/// </summary>
41+
public static string Resolve(string callerOverride)
42+
{
43+
if (!string.IsNullOrWhiteSpace(callerOverride)) return callerOverride.Trim();
44+
string pref = DefaultFolder;
45+
if (!string.IsNullOrWhiteSpace(pref)) return pref;
46+
return ScreenshotUtility.DefaultFolder;
47+
}
48+
}
49+
}

MCPForUnity/Editor/Helpers/ScreenshotPreferences.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MCPForUnity/Editor/Helpers/UnityTypeResolver.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Reflection;
5+
using MCPForUnity.Runtime.Helpers;
56
using UnityEngine;
67
#if UNITY_EDITOR
78
using UnityEditor;
@@ -150,7 +151,7 @@ private static void Cache(Type t)
150151
private static List<Type> FindCandidates(string query, Type requiredBaseType)
151152
{
152153
bool isShort = !query.Contains('.');
153-
var loaded = AppDomain.CurrentDomain.GetAssemblies();
154+
var loaded = UnityAssembliesCompat.GetLoadedAssemblies();
154155

155156
#if UNITY_EDITOR
156157
// Names of Player (runtime) script assemblies

MCPForUnity/Editor/Tools/Animation/ClipCreate.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using Newtonsoft.Json.Linq;
66
using MCPForUnity.Editor.Helpers;
7+
using MCPForUnity.Runtime.Helpers;
78
using UnityEditor;
89
using UnityEngine;
910

@@ -491,7 +492,7 @@ private static Type ResolveType(string typeName)
491492
if (type != null) return type;
492493

493494
// Fallback: search all loaded assemblies
494-
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
495+
foreach (var assembly in UnityAssembliesCompat.GetLoadedAssemblies())
495496
{
496497
type = assembly.GetType(typeName);
497498
if (type != null) return type;

MCPForUnity/Editor/Tools/CommandRegistry.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Threading.Tasks;
66
using MCPForUnity.Editor.Helpers;
77
using MCPForUnity.Editor.Resources;
8+
using MCPForUnity.Runtime.Helpers;
89
using Newtonsoft.Json;
910
using Newtonsoft.Json.Linq;
1011

@@ -59,7 +60,7 @@ private static void AutoDiscoverCommands()
5960
{
6061
try
6162
{
62-
var allTypes = AppDomain.CurrentDomain.GetAssemblies()
63+
var allTypes = UnityAssembliesCompat.GetLoadedAssemblies()
6364
.Where(a => !a.IsDynamic)
6465
.SelectMany(a =>
6566
{

MCPForUnity/Editor/Tools/ExecuteCode.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Reflection;
77
using System.Text;
88
using MCPForUnity.Editor.Helpers;
9+
using MCPForUnity.Runtime.Helpers;
910
using Microsoft.CSharp;
1011
using Newtonsoft.Json.Linq;
1112
using UnityEngine;
@@ -360,7 +361,7 @@ private static string[] ResolveAssemblyPaths()
360361
{
361362
var paths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
362363

363-
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
364+
foreach (var assembly in UnityAssembliesCompat.GetLoadedAssemblies())
364365
{
365366
try
366367
{

0 commit comments

Comments
 (0)