Skip to content

Commit 97a418e

Browse files
committed
bug-fix-and-component-index-update
1. Fix the bug mentioned in CoplayDev#956 and add index mentioned in CoplayDev#1014
1 parent 22c7829 commit 97a418e

21 files changed

Lines changed: 342 additions & 106 deletions

MCPForUnity/Editor/Tools/ManageComponents.cs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,24 @@ private static object RemoveComponent(JObject @params, JToken targetToken, strin
146146
return new ErrorResponse($"Component type '{componentTypeName}' not found.");
147147
}
148148

149-
// Use ComponentOps for the actual operation
149+
int? componentIndex = ParamCoercion.CoerceIntNullable(@params["componentIndex"] ?? @params["component_index"]);
150+
if (componentIndex.HasValue)
151+
{
152+
var components = targetGo.GetComponents(type);
153+
if (componentIndex.Value < 0 || componentIndex.Value >= components.Length)
154+
return new ErrorResponse($"component_index {componentIndex.Value} out of range. Found {components.Length} '{componentTypeName}' component(s).");
155+
Undo.DestroyObjectImmediate(components[componentIndex.Value]);
156+
EditorUtility.SetDirty(targetGo);
157+
MarkOwningSceneDirty(targetGo);
158+
return new
159+
{
160+
success = true,
161+
message = $"Component '{componentTypeName}' (index {componentIndex.Value}) removed from '{targetGo.name}'.",
162+
data = new { instanceID = targetGo.GetInstanceID() }
163+
};
164+
}
165+
166+
// Use ComponentOps for the actual operation (removes first instance)
150167
bool removed = ComponentOps.RemoveComponent(targetGo, type, out string error);
151168
if (!removed)
152169
{
@@ -188,7 +205,19 @@ private static object SetProperty(JObject @params, JToken targetToken, string se
188205
return new ErrorResponse($"Component type '{componentType}' not found.");
189206
}
190207

191-
Component component = targetGo.GetComponent(type);
208+
int? componentIndex = ParamCoercion.CoerceIntNullable(@params["componentIndex"] ?? @params["component_index"]);
209+
Component component;
210+
if (componentIndex.HasValue)
211+
{
212+
var components = targetGo.GetComponents(type);
213+
if (componentIndex.Value < 0 || componentIndex.Value >= components.Length)
214+
return new ErrorResponse($"component_index {componentIndex.Value} out of range. Found {components.Length} '{componentType}' component(s).");
215+
component = components[componentIndex.Value];
216+
}
217+
else
218+
{
219+
component = targetGo.GetComponent(type);
220+
}
192221
if (component == null)
193222
{
194223
return new ErrorResponse($"Component '{componentType}' not found on '{targetGo.name}'.");

MCPForUnity/Editor/Tools/Physics/JointOps.cs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,13 @@ public static object ConfigureJoint(JObject @params)
161161
return new ErrorResponse($"Target GameObject '{targetStr}' not found.");
162162

163163
string jointTypeStr = p.Get("joint_type");
164-
Component joint = ResolveJoint(go, jointTypeStr);
164+
int? componentIndex = ParamCoercion.CoerceIntNullable(@params["componentIndex"] ?? @params["component_index"]);
165+
Component joint = ResolveJoint(go, jointTypeStr, componentIndex, out int foundCount);
165166
if (joint == null)
166167
{
168+
if (componentIndex.HasValue && foundCount >= 0)
169+
return new ErrorResponse($"component_index {componentIndex.Value} out of range. Found {foundCount} joint(s) on '{go.name}'.");
170+
167171
if (!string.IsNullOrEmpty(jointTypeStr))
168172
return new ErrorResponse($"No joint of type '{jointTypeStr}' found on '{go.name}'.");
169173

@@ -324,6 +328,7 @@ public static object RemoveJoint(JObject @params)
324328
return new ErrorResponse($"Target GameObject '{targetStr}' not found.");
325329

326330
string jointTypeStr = p.Get("joint_type");
331+
int? componentIndex = ParamCoercion.CoerceIntNullable(@params["componentIndex"] ?? @params["component_index"]);
327332

328333
var jointsToRemove = new List<Component>();
329334

@@ -342,7 +347,17 @@ public static object RemoveJoint(JObject @params)
342347
}
343348

344349
var components = go.GetComponents(jointComponentType);
345-
jointsToRemove.AddRange(components);
350+
351+
if (componentIndex.HasValue)
352+
{
353+
if (componentIndex.Value < 0 || componentIndex.Value >= components.Length)
354+
return new ErrorResponse($"component_index {componentIndex.Value} out of range. Found {components.Length} '{jointComponentType.Name}' joint(s) on '{go.name}'.");
355+
jointsToRemove.Add(components[componentIndex.Value]);
356+
}
357+
else
358+
{
359+
jointsToRemove.AddRange(components);
360+
}
346361
}
347362
else
348363
{
@@ -403,16 +418,27 @@ private static GameObject FindTarget(JToken targetToken, string searchMethod)
403418
return GameObjectLookup.FindByTarget(targetToken, searchMethod ?? "by_name", true);
404419
}
405420

406-
private static Component ResolveJoint(GameObject go, string jointTypeStr)
421+
private static Component ResolveJoint(GameObject go, string jointTypeStr, int? index, out int foundCount)
407422
{
423+
foundCount = -1;
408424
if (!string.IsNullOrEmpty(jointTypeStr))
409425
{
410426
bool is2D = go.GetComponent<Rigidbody2D>() != null;
411427
var typeMap = is2D ? JointTypes2D : JointTypes3D;
412428
string key = jointTypeStr.ToLowerInvariant();
413429

414430
if (typeMap.TryGetValue(key, out Type jointType))
431+
{
432+
if (index.HasValue)
433+
{
434+
var components = go.GetComponents(jointType);
435+
foundCount = components.Length;
436+
if (index.Value < 0 || index.Value >= components.Length)
437+
return null;
438+
return components[index.Value];
439+
}
415440
return go.GetComponent(jointType);
441+
}
416442

417443
return null;
418444
}

MCPForUnity/Editor/Tools/Physics/PhysicsMaterialOps.cs

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public static object Assign(JObject @params)
7979

8080
string searchMethod = p.Get("search_method") ?? "by_name";
8181
string colliderType = p.Get("collider_type");
82+
int? componentIndex = ParamCoercion.CoerceIntNullable(p.GetRaw("componentIndex") ?? p.GetRaw("component_index"));
8283

8384
var go = GameObjectLookup.FindByTarget(targetToken, searchMethod);
8485
if (go == null)
@@ -98,7 +99,7 @@ public static object Assign(JObject @params)
9899
// Try 3D colliders first
99100
if (mat3D != null)
100101
{
101-
var collider3D = FindCollider3D(go, colliderType);
102+
var collider3D = FindCollider3D(go, colliderType, componentIndex);
102103
if (collider3D != null)
103104
{
104105
Undo.RecordObject(collider3D, "Assign Physics Material");
@@ -116,12 +117,18 @@ public static object Assign(JObject @params)
116117
}
117118
};
118119
}
120+
if (componentIndex.HasValue)
121+
{
122+
var type3D = !string.IsNullOrEmpty(colliderType) ? UnityTypeResolver.ResolveComponent(colliderType) : typeof(Collider);
123+
int count3D = type3D != null ? go.GetComponents(type3D).Length : 0;
124+
return new ErrorResponse($"component_index {componentIndex.Value} out of range. Found {count3D} '{(type3D ?? typeof(Collider)).Name}' collider(s) on '{go.name}'.");
125+
}
119126
}
120127

121128
// Try 2D colliders
122129
if (mat2D != null)
123130
{
124-
var collider2D = FindCollider2D(go, colliderType);
131+
var collider2D = FindCollider2D(go, colliderType, componentIndex);
125132
if (collider2D != null)
126133
{
127134
Undo.RecordObject(collider2D, "Assign Physics Material 2D");
@@ -139,6 +146,12 @@ public static object Assign(JObject @params)
139146
}
140147
};
141148
}
149+
if (componentIndex.HasValue)
150+
{
151+
var type2D = !string.IsNullOrEmpty(colliderType) ? UnityTypeResolver.ResolveComponent(colliderType) : typeof(Collider2D);
152+
int count2D = type2D != null ? go.GetComponents(type2D).Length : 0;
153+
return new ErrorResponse($"component_index {componentIndex.Value} out of range. Found {count2D} '{(type2D ?? typeof(Collider2D)).Name}' collider(s) on '{go.name}'.");
154+
}
142155
}
143156

144157
return new ErrorResponse($"No suitable collider found on '{go.name}'.");
@@ -398,29 +411,63 @@ private static object Configure2D(string path, JObject properties)
398411
// Assign helpers
399412
// =====================================================================
400413

401-
private static Collider FindCollider3D(GameObject go, string colliderType)
414+
private static Collider FindCollider3D(GameObject go, string colliderType, int? index = null)
402415
{
403416
if (!string.IsNullOrEmpty(colliderType))
404417
{
405418
var type = UnityTypeResolver.ResolveComponent(colliderType);
406419
if (type != null && typeof(Collider).IsAssignableFrom(type))
420+
{
421+
if (index.HasValue)
422+
{
423+
var components = go.GetComponents(type);
424+
if (index.Value < 0 || index.Value >= components.Length)
425+
return null;
426+
return components[index.Value] as Collider;
427+
}
407428
return go.GetComponent(type) as Collider;
429+
}
408430
return null;
409431
}
410432

433+
if (index.HasValue)
434+
{
435+
var colliders = go.GetComponents<Collider>();
436+
if (index.Value < 0 || index.Value >= colliders.Length)
437+
return null;
438+
return colliders[index.Value];
439+
}
440+
411441
return go.GetComponent<Collider>();
412442
}
413443

414-
private static Collider2D FindCollider2D(GameObject go, string colliderType)
444+
private static Collider2D FindCollider2D(GameObject go, string colliderType, int? index = null)
415445
{
416446
if (!string.IsNullOrEmpty(colliderType))
417447
{
418448
var type = UnityTypeResolver.ResolveComponent(colliderType);
419449
if (type != null && typeof(Collider2D).IsAssignableFrom(type))
450+
{
451+
if (index.HasValue)
452+
{
453+
var components = go.GetComponents(type);
454+
if (index.Value < 0 || index.Value >= components.Length)
455+
return null;
456+
return components[index.Value] as Collider2D;
457+
}
420458
return go.GetComponent(type) as Collider2D;
459+
}
421460
return null;
422461
}
423462

463+
if (index.HasValue)
464+
{
465+
var colliders = go.GetComponents<Collider2D>();
466+
if (index.Value < 0 || index.Value >= colliders.Length)
467+
return null;
468+
return colliders[index.Value];
469+
}
470+
424471
return go.GetComponent<Collider2D>();
425472
}
426473

MCPForUnity/Editor/Tools/Vfx/LineCreate.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ internal static class LineCreate
1010
public static object CreateLine(JObject @params)
1111
{
1212
LineRenderer lr = LineRead.FindLineRenderer(@params);
13-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
13+
if (lr == null) return new { success = false, message = LineRead.FindLineRendererError(@params) };
1414

1515
Vector3 start = ManageVfxCommon.ParseVector3(@params["start"]);
1616
Vector3 end = ManageVfxCommon.ParseVector3(@params["end"]);
@@ -50,7 +50,7 @@ public static object CreateLine(JObject @params)
5050
public static object CreateCircle(JObject @params)
5151
{
5252
LineRenderer lr = LineRead.FindLineRenderer(@params);
53-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
53+
if (lr == null) return new { success = false, message = LineRead.FindLineRendererError(@params) };
5454

5555
Vector3 center = ManageVfxCommon.ParseVector3(@params["center"]);
5656
float radius = @params["radius"]?.ToObject<float>() ?? 1f;
@@ -102,7 +102,7 @@ public static object CreateCircle(JObject @params)
102102
public static object CreateArc(JObject @params)
103103
{
104104
LineRenderer lr = LineRead.FindLineRenderer(@params);
105-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
105+
if (lr == null) return new { success = false, message = LineRead.FindLineRendererError(@params) };
106106

107107
Vector3 center = ManageVfxCommon.ParseVector3(@params["center"]);
108108
float radius = @params["radius"]?.ToObject<float>() ?? 1f;
@@ -157,7 +157,7 @@ public static object CreateArc(JObject @params)
157157
public static object CreateBezier(JObject @params)
158158
{
159159
LineRenderer lr = LineRead.FindLineRenderer(@params);
160-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
160+
if (lr == null) return new { success = false, message = LineRead.FindLineRendererError(@params) };
161161

162162
Vector3 start = ManageVfxCommon.ParseVector3(@params["start"]);
163163
Vector3 end = ManageVfxCommon.ParseVector3(@params["end"]);

MCPForUnity/Editor/Tools/Vfx/LineRead.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ namespace MCPForUnity.Editor.Tools.Vfx
77
internal static class LineRead
88
{
99
public static LineRenderer FindLineRenderer(JObject @params)
10-
{
11-
GameObject go = ManageVfxCommon.FindTargetGameObject(@params);
12-
return go?.GetComponent<LineRenderer>();
13-
}
10+
=> ManageVfxCommon.FindComponent<LineRenderer>(@params);
11+
12+
public static string FindLineRendererError(JObject @params)
13+
=> ManageVfxCommon.FindComponentError<LineRenderer>(@params);
1414

1515
public static object GetInfo(JObject @params)
1616
{
1717
LineRenderer lr = FindLineRenderer(@params);
18-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
18+
if (lr == null) return new { success = false, message = FindLineRendererError(@params) };
1919

2020
var positions = new Vector3[lr.positionCount];
2121
lr.GetPositions(positions);

MCPForUnity/Editor/Tools/Vfx/LineWrite.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ internal static class LineWrite
1111
public static object SetPositions(JObject @params)
1212
{
1313
LineRenderer lr = LineRead.FindLineRenderer(@params);
14-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
14+
if (lr == null) return new { success = false, message = LineRead.FindLineRendererError(@params) };
1515

1616
RendererHelpers.EnsureMaterial(lr);
1717

@@ -35,7 +35,7 @@ public static object SetPositions(JObject @params)
3535
public static object AddPosition(JObject @params)
3636
{
3737
LineRenderer lr = LineRead.FindLineRenderer(@params);
38-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
38+
if (lr == null) return new { success = false, message = LineRead.FindLineRendererError(@params) };
3939

4040
RendererHelpers.EnsureMaterial(lr);
4141

@@ -53,7 +53,7 @@ public static object AddPosition(JObject @params)
5353
public static object SetPosition(JObject @params)
5454
{
5555
LineRenderer lr = LineRead.FindLineRenderer(@params);
56-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
56+
if (lr == null) return new { success = false, message = LineRead.FindLineRendererError(@params) };
5757

5858
RendererHelpers.EnsureMaterial(lr);
5959

@@ -72,7 +72,7 @@ public static object SetPosition(JObject @params)
7272
public static object SetWidth(JObject @params)
7373
{
7474
LineRenderer lr = LineRead.FindLineRenderer(@params);
75-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
75+
if (lr == null) return new { success = false, message = LineRead.FindLineRendererError(@params) };
7676

7777
RendererHelpers.EnsureMaterial(lr);
7878

@@ -91,7 +91,7 @@ public static object SetWidth(JObject @params)
9191
public static object SetColor(JObject @params)
9292
{
9393
LineRenderer lr = LineRead.FindLineRenderer(@params);
94-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
94+
if (lr == null) return new { success = false, message = LineRead.FindLineRendererError(@params) };
9595

9696
RendererHelpers.EnsureMaterial(lr);
9797

@@ -116,7 +116,7 @@ public static object SetMaterial(JObject @params)
116116
public static object SetProperties(JObject @params)
117117
{
118118
LineRenderer lr = LineRead.FindLineRenderer(@params);
119-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
119+
if (lr == null) return new { success = false, message = LineRead.FindLineRendererError(@params) };
120120

121121
RendererHelpers.EnsureMaterial(lr);
122122

@@ -176,7 +176,7 @@ public static object SetProperties(JObject @params)
176176
public static object Clear(JObject @params)
177177
{
178178
LineRenderer lr = LineRead.FindLineRenderer(@params);
179-
if (lr == null) return new { success = false, message = "LineRenderer not found" };
179+
if (lr == null) return new { success = false, message = LineRead.FindLineRendererError(@params) };
180180

181181
int count = lr.positionCount;
182182
Undo.RecordObject(lr, "Clear Line");

MCPForUnity/Editor/Tools/Vfx/ManageVfxCommon.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,33 @@ public static GameObject FindTargetGameObject(JObject @params)
1818

1919
public static Material FindMaterialByPath(string path)
2020
=> ObjectResolver.ResolveMaterial(path);
21+
22+
public static T FindComponent<T>(JObject @params) where T : Component
23+
{
24+
GameObject go = FindTargetGameObject(@params);
25+
if (go == null) return null;
26+
int? idx = ParamCoercion.CoerceIntNullable(@params["componentIndex"] ?? @params["component_index"]);
27+
if (idx.HasValue)
28+
{
29+
var all = go.GetComponents<T>();
30+
return (idx.Value >= 0 && idx.Value < all.Length) ? all[idx.Value] : null;
31+
}
32+
return go.GetComponent<T>();
33+
}
34+
35+
public static string FindComponentError<T>(JObject @params) where T : Component
36+
{
37+
string typeName = typeof(T).Name;
38+
GameObject go = FindTargetGameObject(@params);
39+
if (go == null) return $"{typeName} not found";
40+
int? idx = ParamCoercion.CoerceIntNullable(@params["componentIndex"] ?? @params["component_index"]);
41+
if (idx.HasValue)
42+
{
43+
int count = go.GetComponents<T>().Length;
44+
if (idx.Value < 0 || idx.Value >= count)
45+
return $"component_index {idx.Value} out of range. Found {count} {typeName} component(s) on '{go.name}'.";
46+
}
47+
return $"{typeName} not found";
48+
}
2149
}
2250
}

0 commit comments

Comments
 (0)