chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,306 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using MCPForUnity.Editor.Helpers;
|
||||
using MCPForUnity.Runtime.Helpers;
|
||||
|
||||
namespace MCPForUnity.Editor.Tools.Physics
|
||||
{
|
||||
internal static class PhysicsSettingsOps
|
||||
{
|
||||
public static object Ping(JObject @params)
|
||||
{
|
||||
var gravity3d = UnityEngine.Physics.gravity;
|
||||
var gravity2d = Physics2D.gravity;
|
||||
var simMode = UnityPhysicsCompat.GetPhysicsSimulationMode().ToString();
|
||||
|
||||
return new
|
||||
{
|
||||
success = true,
|
||||
message = "Physics tool ready.",
|
||||
data = new
|
||||
{
|
||||
gravity3d = new[] { gravity3d.x, gravity3d.y, gravity3d.z },
|
||||
gravity2d = new[] { gravity2d.x, gravity2d.y },
|
||||
simulationMode = simMode,
|
||||
defaultSolverIterations = UnityEngine.Physics.defaultSolverIterations,
|
||||
defaultSolverVelocityIterations = UnityEngine.Physics.defaultSolverVelocityIterations,
|
||||
bounceThreshold = UnityEngine.Physics.bounceThreshold,
|
||||
sleepThreshold = UnityEngine.Physics.sleepThreshold,
|
||||
defaultContactOffset = UnityEngine.Physics.defaultContactOffset,
|
||||
queriesHitTriggers = UnityEngine.Physics.queriesHitTriggers
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static object GetSettings(JObject @params)
|
||||
{
|
||||
var p = new ToolParams(@params);
|
||||
string dimension = (p.Get("dimension") ?? "3d").ToLowerInvariant();
|
||||
|
||||
if (dimension == "2d")
|
||||
{
|
||||
var g = Physics2D.gravity;
|
||||
return new
|
||||
{
|
||||
success = true,
|
||||
message = "Physics2D settings retrieved.",
|
||||
data = new
|
||||
{
|
||||
dimension = "2d",
|
||||
gravity = new[] { g.x, g.y },
|
||||
velocityIterations = Physics2D.velocityIterations,
|
||||
positionIterations = Physics2D.positionIterations,
|
||||
queriesHitTriggers = Physics2D.queriesHitTriggers,
|
||||
queriesStartInColliders = Physics2D.queriesStartInColliders,
|
||||
callbacksOnDisable = Physics2D.callbacksOnDisable,
|
||||
autoSyncTransforms = UnityPhysicsCompat.GetPhysics2DAutoSyncTransforms()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (dimension != "3d")
|
||||
return new ErrorResponse($"Invalid dimension: '{dimension}'. Use '3d' or '2d'.");
|
||||
|
||||
var g3 = UnityEngine.Physics.gravity;
|
||||
var simMode = UnityPhysicsCompat.GetPhysicsSimulationMode().ToString();
|
||||
|
||||
return new
|
||||
{
|
||||
success = true,
|
||||
message = "Physics3D settings retrieved.",
|
||||
data = new
|
||||
{
|
||||
dimension = "3d",
|
||||
gravity = new[] { g3.x, g3.y, g3.z },
|
||||
defaultContactOffset = UnityEngine.Physics.defaultContactOffset,
|
||||
sleepThreshold = UnityEngine.Physics.sleepThreshold,
|
||||
defaultSolverIterations = UnityEngine.Physics.defaultSolverIterations,
|
||||
defaultSolverVelocityIterations = UnityEngine.Physics.defaultSolverVelocityIterations,
|
||||
bounceThreshold = UnityEngine.Physics.bounceThreshold,
|
||||
defaultMaxAngularSpeed = UnityEngine.Physics.defaultMaxAngularSpeed,
|
||||
queriesHitTriggers = UnityEngine.Physics.queriesHitTriggers,
|
||||
queriesHitBackfaces = UnityEngine.Physics.queriesHitBackfaces,
|
||||
simulationMode = simMode,
|
||||
autoSyncTransforms = UnityPhysicsCompat.GetPhysicsAutoSyncTransforms()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static object SetSettings(JObject @params)
|
||||
{
|
||||
var p = new ToolParams(@params);
|
||||
string dimension = (p.Get("dimension") ?? "3d").ToLowerInvariant();
|
||||
var settings = p.GetRaw("settings") as JObject;
|
||||
|
||||
if (settings == null || settings.Count == 0)
|
||||
return new ErrorResponse("'settings' parameter is required and must be a non-empty object.");
|
||||
|
||||
if (dimension != "3d" && dimension != "2d")
|
||||
return new ErrorResponse($"Invalid dimension: '{dimension}'. Use '3d' or '2d'.");
|
||||
|
||||
if (dimension == "2d")
|
||||
return SetSettings2D(settings);
|
||||
|
||||
return SetSettings3D(settings);
|
||||
}
|
||||
|
||||
private static readonly HashSet<string> Valid3DKeys = new HashSet<string>
|
||||
{
|
||||
"gravity", "defaultcontactoffset", "sleepthreshold",
|
||||
"defaultsolveriterations", "defaultsolvervelocityiterations",
|
||||
"bouncethreshold", "defaultmaxangularspeed",
|
||||
"querieshittriggers", "querieshitbackfaces", "simulationmode",
|
||||
"autosynctransforms"
|
||||
};
|
||||
|
||||
private static object SetSettings3D(JObject settings)
|
||||
{
|
||||
// Validate all keys before applying any changes
|
||||
var unknown = new List<string>();
|
||||
foreach (var prop in settings.Properties())
|
||||
{
|
||||
if (!Valid3DKeys.Contains(prop.Name.ToLowerInvariant()))
|
||||
unknown.Add(prop.Name);
|
||||
}
|
||||
if (unknown.Count > 0)
|
||||
return new ErrorResponse(
|
||||
$"Unknown 3D physics setting(s): {string.Join(", ", unknown)}.");
|
||||
|
||||
var changed = new List<string>();
|
||||
|
||||
foreach (var prop in settings.Properties())
|
||||
{
|
||||
string key = prop.Name.ToLowerInvariant();
|
||||
switch (key)
|
||||
{
|
||||
case "gravity":
|
||||
{
|
||||
var arr = prop.Value as JArray;
|
||||
if (arr == null || arr.Count < 3)
|
||||
return new ErrorResponse("3D gravity requires [x, y, z] array.");
|
||||
UnityEngine.Physics.gravity = new Vector3(
|
||||
arr[0].Value<float>(), arr[1].Value<float>(), arr[2].Value<float>());
|
||||
changed.Add("gravity");
|
||||
break;
|
||||
}
|
||||
case "defaultcontactoffset":
|
||||
UnityEngine.Physics.defaultContactOffset = prop.Value.Value<float>();
|
||||
changed.Add("defaultContactOffset");
|
||||
break;
|
||||
case "sleepthreshold":
|
||||
UnityEngine.Physics.sleepThreshold = prop.Value.Value<float>();
|
||||
changed.Add("sleepThreshold");
|
||||
break;
|
||||
case "defaultsolveriterations":
|
||||
UnityEngine.Physics.defaultSolverIterations = prop.Value.Value<int>();
|
||||
changed.Add("defaultSolverIterations");
|
||||
break;
|
||||
case "defaultsolvervelocityiterations":
|
||||
UnityEngine.Physics.defaultSolverVelocityIterations = prop.Value.Value<int>();
|
||||
changed.Add("defaultSolverVelocityIterations");
|
||||
break;
|
||||
case "bouncethreshold":
|
||||
UnityEngine.Physics.bounceThreshold = prop.Value.Value<float>();
|
||||
changed.Add("bounceThreshold");
|
||||
break;
|
||||
case "defaultmaxangularspeed":
|
||||
UnityEngine.Physics.defaultMaxAngularSpeed = prop.Value.Value<float>();
|
||||
changed.Add("defaultMaxAngularSpeed");
|
||||
break;
|
||||
case "querieshittriggers":
|
||||
UnityEngine.Physics.queriesHitTriggers = prop.Value.Value<bool>();
|
||||
changed.Add("queriesHitTriggers");
|
||||
break;
|
||||
case "querieshitbackfaces":
|
||||
UnityEngine.Physics.queriesHitBackfaces = prop.Value.Value<bool>();
|
||||
changed.Add("queriesHitBackfaces");
|
||||
break;
|
||||
case "simulationmode":
|
||||
{
|
||||
string modeStr = prop.Value.ToString();
|
||||
if (!System.Enum.TryParse<UnityPhysicsCompat.SimulationMode>(modeStr, true, out var mode)
|
||||
|| mode == UnityPhysicsCompat.SimulationMode.Unknown)
|
||||
{
|
||||
return new ErrorResponse(
|
||||
$"Invalid simulationMode: '{modeStr}'. Valid: FixedUpdate, Update, Script.");
|
||||
}
|
||||
if (!UnityPhysicsCompat.TrySetPhysicsSimulationMode(mode))
|
||||
{
|
||||
return new ErrorResponse(
|
||||
$"simulationMode '{modeStr}' is not supported on this Unity version.");
|
||||
}
|
||||
changed.Add("simulationMode");
|
||||
break;
|
||||
}
|
||||
case "autosynctransforms":
|
||||
if (UnityPhysicsCompat.TrySetPhysicsAutoSyncTransforms(prop.Value.Value<bool>()))
|
||||
{
|
||||
changed.Add("autoSyncTransforms");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MarkDynamicsManagerDirty();
|
||||
|
||||
return new
|
||||
{
|
||||
success = true,
|
||||
message = $"Updated {changed.Count} physics 3D setting(s).",
|
||||
data = new { changed }
|
||||
};
|
||||
}
|
||||
|
||||
private static readonly HashSet<string> Valid2DKeys = new HashSet<string>
|
||||
{
|
||||
"gravity", "velocityiterations", "positioniterations",
|
||||
"querieshittriggers", "queriesstartincolliders",
|
||||
"callbacksondisable", "autosynctransforms"
|
||||
};
|
||||
|
||||
private static object SetSettings2D(JObject settings)
|
||||
{
|
||||
// Validate all keys before applying any changes
|
||||
var unknown = new List<string>();
|
||||
foreach (var prop in settings.Properties())
|
||||
{
|
||||
if (!Valid2DKeys.Contains(prop.Name.ToLowerInvariant()))
|
||||
unknown.Add(prop.Name);
|
||||
}
|
||||
if (unknown.Count > 0)
|
||||
return new ErrorResponse(
|
||||
$"Unknown 2D physics setting(s): {string.Join(", ", unknown)}.");
|
||||
|
||||
var changed = new List<string>();
|
||||
|
||||
foreach (var prop in settings.Properties())
|
||||
{
|
||||
string key = prop.Name.ToLowerInvariant();
|
||||
switch (key)
|
||||
{
|
||||
case "gravity":
|
||||
{
|
||||
var arr = prop.Value as JArray;
|
||||
if (arr == null || arr.Count < 2)
|
||||
return new ErrorResponse("2D gravity requires [x, y] array.");
|
||||
Physics2D.gravity = new Vector2(
|
||||
arr[0].Value<float>(), arr[1].Value<float>());
|
||||
changed.Add("gravity");
|
||||
break;
|
||||
}
|
||||
case "velocityiterations":
|
||||
Physics2D.velocityIterations = prop.Value.Value<int>();
|
||||
changed.Add("velocityIterations");
|
||||
break;
|
||||
case "positioniterations":
|
||||
Physics2D.positionIterations = prop.Value.Value<int>();
|
||||
changed.Add("positionIterations");
|
||||
break;
|
||||
case "querieshittriggers":
|
||||
Physics2D.queriesHitTriggers = prop.Value.Value<bool>();
|
||||
changed.Add("queriesHitTriggers");
|
||||
break;
|
||||
case "queriesstartincolliders":
|
||||
Physics2D.queriesStartInColliders = prop.Value.Value<bool>();
|
||||
changed.Add("queriesStartInColliders");
|
||||
break;
|
||||
case "callbacksondisable":
|
||||
Physics2D.callbacksOnDisable = prop.Value.Value<bool>();
|
||||
changed.Add("callbacksOnDisable");
|
||||
break;
|
||||
case "autosynctransforms":
|
||||
if (UnityPhysicsCompat.TrySetPhysics2DAutoSyncTransforms(prop.Value.Value<bool>()))
|
||||
{
|
||||
changed.Add("autoSyncTransforms");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MarkPhysics2DSettingsDirty();
|
||||
|
||||
return new
|
||||
{
|
||||
success = true,
|
||||
message = $"Updated {changed.Count} physics 2D setting(s).",
|
||||
data = new { changed }
|
||||
};
|
||||
}
|
||||
|
||||
private static void MarkDynamicsManagerDirty()
|
||||
{
|
||||
var assets = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/DynamicsManager.asset");
|
||||
if (assets != null && assets.Length > 0)
|
||||
EditorUtility.SetDirty(assets[0]);
|
||||
}
|
||||
|
||||
private static void MarkPhysics2DSettingsDirty()
|
||||
{
|
||||
var assets = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/Physics2DSettings.asset");
|
||||
if (assets != null && assets.Length > 0)
|
||||
EditorUtility.SetDirty(assets[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user