Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 6 additions & 6 deletions UnityCtl.Cli/ScriptCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -613,15 +613,15 @@ internal static string ExtractLeadingUsingDirectives(string expression, List<str
return expression;
}

internal static int[] ParseInstanceIds(string idArg)
internal static long[] ParseInstanceIds(string idArg)
{
var parts = idArg.Split(',');
var ids = new List<int>();
var ids = new List<long>();
foreach (var part in parts)
{
var trimmed = part.Trim();
if (trimmed.Length == 0) continue;
if (!int.TryParse(trimmed, out var id))
if (!long.TryParse(trimmed, out var id))
throw new ArgumentException($"Invalid instance ID: '{trimmed}' — must be an integer");
ids.Add(id);
}
Expand All @@ -630,22 +630,22 @@ internal static int[] ParseInstanceIds(string idArg)
return ids.ToArray();
}

internal static string BuildInstanceIdPreamble(int[] ids)
internal static string BuildInstanceIdPreamble(long[] ids)
{
const string pad = "\n ";
var sb = new System.Text.StringBuilder();

if (ids.Length == 1)
{
sb.Append($"var target = (GameObject)UnityEditor.EditorUtility.InstanceIDToObject({ids[0]});");
sb.Append($"var target = (GameObject)UnityCtl.UnityCtlClient.ResolveObjectById({ids[0]});");
sb.Append($"{pad}if (target == null) throw new System.Exception(\"Object {ids[0]} not found (destroyed?)\");");
}
else
{
sb.Append($"var targets = new GameObject[{ids.Length}];");
for (int i = 0; i < ids.Length; i++)
{
sb.Append($"{pad}targets[{i}] = (GameObject)UnityEditor.EditorUtility.InstanceIDToObject({ids[i]});");
sb.Append($"{pad}targets[{i}] = (GameObject)UnityCtl.UnityCtlClient.ResolveObjectById({ids[i]});");
sb.Append($"{pad}if (targets[{i}] == null) throw new System.Exception(\"Object {ids[i]} not found (destroyed?)\");");
}
}
Expand Down
2 changes: 1 addition & 1 deletion UnityCtl.Cli/SnapshotCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static Command CreateCommand()
{
var snapshotCommand = new Command("snapshot", "Snapshot the scene hierarchy as a compact, LLM-friendly tree with instance IDs");

var idOption = new Option<int?>(
var idOption = new Option<long?>(
"--id",
"Drill into a specific object by instance ID"
);
Expand Down
2 changes: 1 addition & 1 deletion UnityCtl.Cli/UICommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ private static Command CreateClickCommand()
{
var clickCommand = new Command("click", "Click a UI element by instance ID, name, or screen coordinates");

var idOption = new Option<int?>("--id", "Instance ID of the UI element to click");
var idOption = new Option<long?>("--id", "Instance ID of the UI element to click");
var nameOption = new Option<string?>("--name", "Find and click a GameObject by name (uses GameObject.Find)");
var xArg = new Argument<int?>("x", () => null, "Screen X coordinate");
var yArg = new Argument<int?>("y", () => null, "Screen Y coordinate");
Expand Down
10 changes: 5 additions & 5 deletions UnityCtl.Protocol/DTOs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ public class SnapshotResult
public bool? HasUnsavedChanges { get; init; }

[JsonProperty("openedFromInstanceId", NullValueHandling = NullValueHandling.Ignore)]
public int? OpenedFromInstanceId { get; init; }
public long? OpenedFromInstanceId { get; init; }

[JsonProperty("isPlaying")]
public required bool IsPlaying { get; init; }
Expand Down Expand Up @@ -521,7 +521,7 @@ public class SnapshotSceneInfo
public class SnapshotObject
{
[JsonProperty("instanceId")]
public int InstanceId { get; set; }
public long InstanceId { get; set; }

[JsonProperty("name")]
public string Name { get; set; } = "";
Expand Down Expand Up @@ -583,7 +583,7 @@ public class SnapshotObject
public bool? Hittable { get; set; }

[JsonProperty("blockedBy", NullValueHandling = NullValueHandling.Ignore)]
public int? BlockedBy { get; set; }
public long? BlockedBy { get; set; }

[JsonProperty("childCount")]
public int ChildCount { get; set; }
Expand Down Expand Up @@ -646,7 +646,7 @@ public class SnapshotQueryResult
public class SnapshotQueryHit
{
[JsonProperty("instanceId")]
public int InstanceId { get; set; }
public long InstanceId { get; set; }

[JsonProperty("name")]
public string Name { get; set; } = "";
Expand All @@ -664,7 +664,7 @@ public class SnapshotQueryHit
public class UIClickResult
{
[JsonProperty("instanceId")]
public int InstanceId { get; set; }
public long InstanceId { get; set; }

[JsonProperty("name")]
public string Name { get; set; } = "";
Expand Down
25 changes: 21 additions & 4 deletions UnityCtl.Tests/Unit/Cli/EvalCodeGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public void InstanceId_SingleId_InjectsTarget()
{
var code = ScriptCommands.BuildEvalCode("target.name", [], hasArgs: false, instanceIds: "14200");

Assert.Contains("InstanceIDToObject(14200)", code);
Assert.Contains("ResolveObjectById(14200)", code);
Assert.Contains("var target =", code);
}

Expand All @@ -129,16 +129,25 @@ public void InstanceId_MultipleIds_InjectsTargetsArray()
var code = ScriptCommands.BuildEvalCode("targets[0].name", [], hasArgs: false, instanceIds: "14200,14210");

Assert.Contains("var targets = new GameObject[2]", code);
Assert.Contains("InstanceIDToObject(14200)", code);
Assert.Contains("InstanceIDToObject(14210)", code);
Assert.Contains("ResolveObjectById(14200)", code);
Assert.Contains("ResolveObjectById(14210)", code);
}

[Fact]
public void InstanceId_NegativeId_Accepted()
{
var code = ScriptCommands.BuildEvalCode("target.name", [], hasArgs: false, instanceIds: "-1290");

Assert.Contains("InstanceIDToObject(-1290)", code);
Assert.Contains("ResolveObjectById(-1290)", code);
}

[Fact]
public void InstanceId_BeyondInt32_Accepted()
{
// Unity 6000.5 EntityIds are 64-bit; ids beyond int range must round-trip.
var code = ScriptCommands.BuildEvalCode("target.name", [], hasArgs: false, instanceIds: "5000000000");

Assert.Contains("ResolveObjectById(5000000000)", code);
}

[Fact]
Expand All @@ -157,6 +166,14 @@ public void ParseInstanceIds_ValidInput_ReturnsInts()
Assert.Equal([14200, -1290, 0], ids);
}

[Fact]
public void ParseInstanceIds_BeyondInt32_ParsesAsLong()
{
var ids = ScriptCommands.ParseInstanceIds("5000000000,-5000000000");

Assert.Equal([5000000000L, -5000000000L], ids);
}

[Fact]
public void ExtraUsings_CommaSeparated_SplitIntoMultiple()
{
Expand Down
Loading
Loading