Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions MCPForUnity/Editor/Helpers/ComponentOps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@ internal static FieldInfo FindSerializedFieldInHierarchy(Type type, string field

private static string CheckPhysicsConflict(GameObject target, Type componentType)
{
// A 2D-vs-3D conflict is only possible when both physics modules are installed;
// if either is absent, its component types can't exist, so there's nothing to check.
#if MCP_HAS_PHYSICS && MCP_HAS_PHYSICS_2D
bool isAdding2DPhysics =
typeof(Rigidbody2D).IsAssignableFrom(componentType) ||
typeof(Collider2D).IsAssignableFrom(componentType);
Expand All @@ -398,6 +401,7 @@ private static string CheckPhysicsConflict(GameObject target, Type componentType
return $"Cannot add 3D physics component '{componentType.Name}' because the GameObject '{target.name}' already has a 2D Rigidbody or Collider.";
}
}
#endif

return null;
}
Expand Down
2 changes: 2 additions & 0 deletions MCPForUnity/Editor/Helpers/GameObjectSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -528,13 +528,15 @@ public static object GetComponentData(Component c, bool includeNonPublicSerializ
}
// --- End Skip Transform Properties ---

#if MCP_HAS_PHYSICS
// --- Skip Collider properties that cause native crashes via PhysX ---
if (typeof(Collider).IsAssignableFrom(componentType) &&
propName == "GeometryHolder")
{
skipProperty = true;
}
// --- End Skip Collider Properties ---
#endif

// Skip if flagged
if (skipProperty)
Expand Down
15 changes: 15 additions & 0 deletions MCPForUnity/Editor/MCPForUnity.Editor.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@
"name": "com.unity.visualeffectgraph",
"expression": "0.0.0",
"define": "UNITY_VFX_GRAPH"
},
{
"name": "com.unity.modules.physics",
"expression": "1.0.0",
"define": "MCP_HAS_PHYSICS"
},
{
"name": "com.unity.modules.physics2d",
"expression": "1.0.0",
"define": "MCP_HAS_PHYSICS_2D"
},
{
"name": "com.unity.modules.screencapture",
"expression": "1.0.0",
"define": "MCP_HAS_SCREEN_CAPTURE"
}
],
"noEngineReferences": false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ internal static object AddComponentInternal(GameObject targetGo, string typeName
return new ErrorResponse("Cannot add another Transform component.");
}

// A 2D-vs-3D conflict is only possible when both physics modules are installed;
// if either is absent, its component types can't exist, so there's nothing to check.
#if MCP_HAS_PHYSICS && MCP_HAS_PHYSICS_2D
bool isAdding2DPhysics = typeof(Rigidbody2D).IsAssignableFrom(componentType) || typeof(Collider2D).IsAssignableFrom(componentType);
bool isAdding3DPhysics = typeof(Rigidbody).IsAssignableFrom(componentType) || typeof(Collider).IsAssignableFrom(componentType);

Expand All @@ -49,6 +52,7 @@ internal static object AddComponentInternal(GameObject targetGo, string typeName
return new ErrorResponse($"Cannot add 3D physics component '{typeName}' because the GameObject '{targetGo.name}' already has a 2D Rigidbody or Collider.");
}
}
#endif

Component existingComponent = targetGo.GetComponent(componentType);
if (existingComponent != null && !AllowsMultiple(componentType))
Expand Down
10 changes: 10 additions & 0 deletions MCPForUnity/Editor/Tools/ManageAsset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
using MCPForUnity.Editor.Tools;
using MCPForUnity.Runtime.Helpers;

#if MCP_HAS_PHYSICS
#if UNITY_6000_0_OR_NEWER
using PhysicsMaterialType = UnityEngine.PhysicsMaterial;
using PhysicsMaterialCombine = UnityEngine.PhysicsMaterialCombine;
#else
using PhysicsMaterialType = UnityEngine.PhysicMaterial;
using PhysicsMaterialCombine = UnityEngine.PhysicMaterialCombine;
#endif
#endif
Comment on lines +13 to +21

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Move Unity version branching into a compat shim.

This #if UNITY_6000_0_OR_NEWER gate is in a tool call site. Please move the API-version split into MCPForUnity/Runtime/Helpers/Unity*Compat.cs and consume a single shim type/API from ManageAsset.

As per coding guidelines, "MCPForUnity/**/*.cs: Unity API version compatibility issues must use shims in MCPForUnity/Runtime/Helpers/Unity*Compat.cs rather than sprinkling #if UNITY_x_y_OR_NEWER at call sites."

🤖 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/ManageAsset.cs` around lines 13 - 21, Move the Unity
version-specific conditional compilation logic from ManageAsset.cs into a
compatibility shim file. Specifically, the `#if` UNITY_6000_0_OR_NEWER
preprocessor directives that define PhysicsMaterialType and
PhysicsMaterialCombine type aliases should be moved to
MCPForUnity/Runtime/Helpers/UnityPhysicsCompat.cs (or similar shim file). In
that shim file, define these type aliases with the appropriate conditional
branches for different Unity versions. Then in ManageAsset.cs, replace the
entire conditional block (lines 13-21) with a single using statement that
imports these type aliases from the compat shim, eliminating all
version-specific branching from the call site.

Source: Coding guidelines


namespace MCPForUnity.Editor.Tools
{
Expand Down Expand Up @@ -224,11 +226,17 @@ private static object CreateAsset(JObject @params)
}
else if (lowerAssetType == "physicsmaterial")
{
#if MCP_HAS_PHYSICS
PhysicsMaterialType pmat = new PhysicsMaterialType();
if (properties != null)
ApplyPhysicsMaterialProperties(pmat, properties);
AssetDatabase.CreateAsset(pmat, fullPath);
newAsset = pmat;
#else
return new ErrorResponse(
"Cannot create a PhysicsMaterial: the Physics module (com.unity.modules.physics) is not installed. "
+ "Enable it via Window > Package Manager > Built-in > Physics.");
#endif
}
else if (lowerAssetType == "prefab")
{
Expand Down Expand Up @@ -876,6 +884,7 @@ private static void EnsureDirectoryExists(string directoryPath)



#if MCP_HAS_PHYSICS
/// <summary>
/// Applies properties from JObject to a PhysicsMaterial.
/// </summary>
Expand Down Expand Up @@ -946,6 +955,7 @@ private static bool ApplyPhysicsMaterialProperties(PhysicsMaterialType pmat, JOb

return modified;
}
#endif

/// <summary>
/// Generic helper to set properties on any UnityEngine.Object using reflection.
Expand Down
6 changes: 5 additions & 1 deletion MCPForUnity/Editor/Tools/ManageScene.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1460,8 +1460,9 @@ private static bool TryGetRendererBounds(GameObject target, out Bounds bounds)
private static bool TryGetColliderBounds(GameObject target, out Bounds bounds)
{
bounds = default(Bounds);
var colliders = target.GetComponentsInChildren<Collider>(true);
bool hasBounds = false;
#if MCP_HAS_PHYSICS
var colliders = target.GetComponentsInChildren<Collider>(true);
foreach (var collider in colliders)
{
if (collider == null || !collider.gameObject.activeInHierarchy)
Expand All @@ -1477,7 +1478,9 @@ private static bool TryGetColliderBounds(GameObject target, out Bounds bounds)
bounds.Encapsulate(collider.bounds);
}
}
#endif

#if MCP_HAS_PHYSICS_2D
var colliders2D = target.GetComponentsInChildren<Collider2D>(true);
foreach (var collider in colliders2D)
{
Expand All @@ -1494,6 +1497,7 @@ private static bool TryGetColliderBounds(GameObject target, out Bounds bounds)
bounds.Encapsulate(collider.bounds);
}
}
#endif

return hasBounds;
}
Expand Down
11 changes: 10 additions & 1 deletion MCPForUnity/Editor/Tools/ManageUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -811,10 +811,12 @@ private static object SerializeVisualElement(VisualElement element, int depth, i

// Play-mode coroutine capture state. Only one capture is in-flight at a
// time; concurrent render_ui calls while a capture is pending are rejected
// with an explicit error.
// with an explicit error. Only used when the Screen Capture module is present.
#if MCP_HAS_SCREEN_CAPTURE
private static Texture2D s_pendingCaptureTex;
private static bool s_pendingCaptureDone;
private static bool s_pendingCaptureStarted;
#endif

private static object RenderUI(JObject @params)
{
Expand Down Expand Up @@ -854,6 +856,7 @@ private static object RenderUI(JObject @params)
// Second call: result is ready – save PNG and return data.
if (Application.isPlaying)
{
#if MCP_HAS_SCREEN_CAPTURE
// Build the output paths (used by both the pending and ready branches)
string resolvedPlayName = string.IsNullOrWhiteSpace(fileName)
? $"ui-render-{DateTime.Now:yyyyMMdd-HHmmss}.png"
Expand Down Expand Up @@ -954,6 +957,12 @@ private static object RenderUI(JObject @params)
{ "gameObject", (object)target ?? uxmlPath },
{ "note", "A screen capture was scheduled for the end of this frame. Call render_ui once more to get the result." }
});
#else
return new ErrorResponse(
"Play-mode UI capture requires the Screen Capture module (com.unity.modules.screencapture), " +
"which is not installed. Enable it via Window > Package Manager > Built-in > Screen Capture, " +
"or render the UI outside Play mode (which captures via a RenderTexture instead).");
#endif
}
// ── End play-mode branch ────────────────────────────────────────────────

Expand Down
41 changes: 38 additions & 3 deletions MCPForUnity/Editor/Tools/Physics/CollisionMatrixOps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ public static object GetCollisionMatrix(JObject @params)
if (dimension != "3d" && dimension != "2d")
return new ErrorResponse($"Invalid dimension: '{dimension}'. Use '3d' or '2d'.");

if (dimension == "2d")
{
#if !MCP_HAS_PHYSICS_2D
return new ErrorResponse("Physics 2D module (com.unity.modules.physics2d) is not installed.");
#endif
}
else
{
#if !MCP_HAS_PHYSICS
return new ErrorResponse("Physics module (com.unity.modules.physics) is not installed.");
#endif
}

var layers = new List<object>();
var populatedIndices = new List<int>();

Expand All @@ -38,9 +51,23 @@ public static object GetCollisionMatrix(JObject @params)
{
if (j > i) continue;
string nameB = LayerMask.LayerToName(j);
bool collides = dimension == "2d"
? !Physics2D.GetIgnoreLayerCollision(i, j)
: !UnityEngine.Physics.GetIgnoreLayerCollision(i, j);
bool collides;
if (dimension == "2d")
{
#if MCP_HAS_PHYSICS_2D
collides = !Physics2D.GetIgnoreLayerCollision(i, j);
#else
return new ErrorResponse("Physics 2D module (com.unity.modules.physics2d) is not installed.");
#endif
}
else
{
#if MCP_HAS_PHYSICS
collides = !UnityEngine.Physics.GetIgnoreLayerCollision(i, j);
#else
return new ErrorResponse("Physics module (com.unity.modules.physics) is not installed.");
#endif
}
row[nameB] = collides;
}

Expand Down Expand Up @@ -83,13 +110,21 @@ public static object SetCollisionMatrix(JObject @params)

if (dimension == "2d")
{
#if MCP_HAS_PHYSICS_2D
Physics2D.IgnoreLayerCollision(layerA, layerB, !collide);
MarkSettingsDirty("ProjectSettings/Physics2DSettings.asset");
#else
return new ErrorResponse("Physics 2D module (com.unity.modules.physics2d) is not installed.");
#endif
}
else
{
#if MCP_HAS_PHYSICS
UnityEngine.Physics.IgnoreLayerCollision(layerA, layerB, !collide);
MarkSettingsDirty("ProjectSettings/DynamicsManager.asset");
#else
return new ErrorResponse("Physics module (com.unity.modules.physics) is not installed.");
#endif
}

string nameA = LayerMask.LayerToName(layerA);
Expand Down
Loading