Skip to content

Commit 2a3db1c

Browse files
authored
Merge pull request #1033 from Scriptwonder/bug-fix
Patch
2 parents eb07941 + 2c6f4eb commit 2a3db1c

22 files changed

Lines changed: 380 additions & 108 deletions

MCPForUnity/Editor/Tools/ManageComponents.cs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,26 @@ 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+
if (type == typeof(Transform) || type == typeof(RectTransform))
156+
return new ErrorResponse("Cannot remove Transform or RectTransform components.");
157+
Undo.DestroyObjectImmediate(components[componentIndex.Value]);
158+
EditorUtility.SetDirty(targetGo);
159+
MarkOwningSceneDirty(targetGo);
160+
return new
161+
{
162+
success = true,
163+
message = $"Component '{componentTypeName}' (index {componentIndex.Value}) removed from '{targetGo.name}'.",
164+
data = new { instanceID = targetGo.GetInstanceID(), componentIndex = componentIndex.Value }
165+
};
166+
}
167+
168+
// Use ComponentOps for the actual operation (removes first instance)
150169
bool removed = ComponentOps.RemoveComponent(targetGo, type, out string error);
151170
if (!removed)
152171
{
@@ -188,7 +207,19 @@ private static object SetProperty(JObject @params, JToken targetToken, string se
188207
return new ErrorResponse($"Component type '{componentType}' not found.");
189208
}
190209

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

MCPForUnity/Editor/Tools/ManageScript.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1910,6 +1910,10 @@ private static bool TryComputeMethodSpan(
19101910
int probe = lineStart - 1;
19111911
while (probe > searchStart)
19121912
{
1913+
// Skip past line-ending chars so LastIndexOf finds the *previous* newline
1914+
while (probe > searchStart && (source[probe] == '\n' || source[probe] == '\r'))
1915+
probe--;
1916+
if (probe <= searchStart) break;
19131917
int prevNl = source.LastIndexOf('\n', probe);
19141918
if (prevNl < 0 || prevNl < searchStart) break;
19151919
string prev = source.Substring(prevNl + 1, attrStart - (prevNl + 1));

MCPForUnity/Editor/Tools/Physics/JointOps.cs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,17 @@ 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+
166+
if (componentIndex.HasValue && string.IsNullOrEmpty(jointTypeStr))
167+
return new ErrorResponse("component_index requires joint_type to be specified.");
168+
169+
Component joint = ResolveJoint(go, jointTypeStr, componentIndex, out int foundCount);
165170
if (joint == null)
166171
{
172+
if (componentIndex.HasValue && foundCount >= 0)
173+
return new ErrorResponse($"component_index {componentIndex.Value} out of range. Found {foundCount} joint(s) on '{go.name}'.");
174+
167175
if (!string.IsNullOrEmpty(jointTypeStr))
168176
return new ErrorResponse($"No joint of type '{jointTypeStr}' found on '{go.name}'.");
169177

@@ -324,6 +332,10 @@ public static object RemoveJoint(JObject @params)
324332
return new ErrorResponse($"Target GameObject '{targetStr}' not found.");
325333

326334
string jointTypeStr = p.Get("joint_type");
335+
int? componentIndex = ParamCoercion.CoerceIntNullable(@params["componentIndex"] ?? @params["component_index"]);
336+
337+
if (componentIndex.HasValue && string.IsNullOrEmpty(jointTypeStr))
338+
return new ErrorResponse("component_index requires joint_type to be specified.");
327339

328340
var jointsToRemove = new List<Component>();
329341

@@ -342,7 +354,17 @@ public static object RemoveJoint(JObject @params)
342354
}
343355

344356
var components = go.GetComponents(jointComponentType);
345-
jointsToRemove.AddRange(components);
357+
358+
if (componentIndex.HasValue)
359+
{
360+
if (componentIndex.Value < 0 || componentIndex.Value >= components.Length)
361+
return new ErrorResponse($"component_index {componentIndex.Value} out of range. Found {components.Length} '{jointComponentType.Name}' joint(s) on '{go.name}'.");
362+
jointsToRemove.Add(components[componentIndex.Value]);
363+
}
364+
else
365+
{
366+
jointsToRemove.AddRange(components);
367+
}
346368
}
347369
else
348370
{
@@ -403,16 +425,27 @@ private static GameObject FindTarget(JToken targetToken, string searchMethod)
403425
return GameObjectLookup.FindByTarget(targetToken, searchMethod ?? "by_name", true);
404426
}
405427

406-
private static Component ResolveJoint(GameObject go, string jointTypeStr)
428+
private static Component ResolveJoint(GameObject go, string jointTypeStr, int? index, out int foundCount)
407429
{
430+
foundCount = -1;
408431
if (!string.IsNullOrEmpty(jointTypeStr))
409432
{
410433
bool is2D = go.GetComponent<Rigidbody2D>() != null;
411434
var typeMap = is2D ? JointTypes2D : JointTypes3D;
412435
string key = jointTypeStr.ToLowerInvariant();
413436

414437
if (typeMap.TryGetValue(key, out Type jointType))
438+
{
439+
if (index.HasValue)
440+
{
441+
var components = go.GetComponents(jointType);
442+
foundCount = components.Length;
443+
if (index.Value < 0 || index.Value >= components.Length)
444+
return null;
445+
return components[index.Value];
446+
}
415447
return go.GetComponent(jointType);
448+
}
416449

417450
return null;
418451
}

MCPForUnity/Editor/Tools/Physics/PhysicsMaterialOps.cs

Lines changed: 65 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,25 @@ 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+
if (type3D != null && typeof(Collider).IsAssignableFrom(type3D))
124+
{
125+
int count3D = go.GetComponents(type3D).Length;
126+
return new ErrorResponse($"component_index {componentIndex.Value} out of range. Found {count3D} '{type3D.Name}' collider(s) on '{go.name}'.");
127+
}
128+
else if (!string.IsNullOrEmpty(colliderType))
129+
{
130+
return new ErrorResponse($"Unknown or invalid 3D collider type: '{colliderType}'.");
131+
}
132+
}
119133
}
120134

121135
// Try 2D colliders
122136
if (mat2D != null)
123137
{
124-
var collider2D = FindCollider2D(go, colliderType);
138+
var collider2D = FindCollider2D(go, colliderType, componentIndex);
125139
if (collider2D != null)
126140
{
127141
Undo.RecordObject(collider2D, "Assign Physics Material 2D");
@@ -139,6 +153,19 @@ public static object Assign(JObject @params)
139153
}
140154
};
141155
}
156+
if (componentIndex.HasValue)
157+
{
158+
var type2D = !string.IsNullOrEmpty(colliderType) ? UnityTypeResolver.ResolveComponent(colliderType) : typeof(Collider2D);
159+
if (type2D != null && typeof(Collider2D).IsAssignableFrom(type2D))
160+
{
161+
int count2D = go.GetComponents(type2D).Length;
162+
return new ErrorResponse($"component_index {componentIndex.Value} out of range. Found {count2D} '{type2D.Name}' collider(s) on '{go.name}'.");
163+
}
164+
else if (!string.IsNullOrEmpty(colliderType))
165+
{
166+
return new ErrorResponse($"Unknown or invalid 2D collider type: '{colliderType}'.");
167+
}
168+
}
142169
}
143170

144171
return new ErrorResponse($"No suitable collider found on '{go.name}'.");
@@ -398,29 +425,63 @@ private static object Configure2D(string path, JObject properties)
398425
// Assign helpers
399426
// =====================================================================
400427

401-
private static Collider FindCollider3D(GameObject go, string colliderType)
428+
private static Collider FindCollider3D(GameObject go, string colliderType, int? index = null)
402429
{
403430
if (!string.IsNullOrEmpty(colliderType))
404431
{
405432
var type = UnityTypeResolver.ResolveComponent(colliderType);
406433
if (type != null && typeof(Collider).IsAssignableFrom(type))
434+
{
435+
if (index.HasValue)
436+
{
437+
var components = go.GetComponents(type);
438+
if (index.Value < 0 || index.Value >= components.Length)
439+
return null;
440+
return components[index.Value] as Collider;
441+
}
407442
return go.GetComponent(type) as Collider;
443+
}
408444
return null;
409445
}
410446

447+
if (index.HasValue)
448+
{
449+
var colliders = go.GetComponents<Collider>();
450+
if (index.Value < 0 || index.Value >= colliders.Length)
451+
return null;
452+
return colliders[index.Value];
453+
}
454+
411455
return go.GetComponent<Collider>();
412456
}
413457

414-
private static Collider2D FindCollider2D(GameObject go, string colliderType)
458+
private static Collider2D FindCollider2D(GameObject go, string colliderType, int? index = null)
415459
{
416460
if (!string.IsNullOrEmpty(colliderType))
417461
{
418462
var type = UnityTypeResolver.ResolveComponent(colliderType);
419463
if (type != null && typeof(Collider2D).IsAssignableFrom(type))
464+
{
465+
if (index.HasValue)
466+
{
467+
var components = go.GetComponents(type);
468+
if (index.Value < 0 || index.Value >= components.Length)
469+
return null;
470+
return components[index.Value] as Collider2D;
471+
}
420472
return go.GetComponent(type) as Collider2D;
473+
}
421474
return null;
422475
}
423476

477+
if (index.HasValue)
478+
{
479+
var colliders = go.GetComponents<Collider2D>();
480+
if (index.Value < 0 || index.Value >= colliders.Length)
481+
return null;
482+
return colliders[index.Value];
483+
}
484+
424485
return go.GetComponent<Collider2D>();
425486
}
426487

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");

0 commit comments

Comments
 (0)