unity-agentic-tools 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/cli.js +700 -253
- package/dist/index.js +418 -184
- package/native/unity-file-tools.darwin-arm64.node +0 -0
- package/native/unity-file-tools.darwin-x64.node +0 -0
- package/native/unity-file-tools.linux-x64-gnu.node +0 -0
- package/native/unity-file-tools.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2299,7 +2299,7 @@ var require_package = __commonJS((exports2, module2) => {
|
|
|
2299
2299
|
module2.exports = {
|
|
2300
2300
|
name: "unity-agentic-tools",
|
|
2301
2301
|
packageManager: "bun@latest",
|
|
2302
|
-
version: "0.3.
|
|
2302
|
+
version: "0.3.3",
|
|
2303
2303
|
description: "Fast, token-efficient Unity YAML parser for AI agents",
|
|
2304
2304
|
exports: {
|
|
2305
2305
|
".": {
|
|
@@ -3358,188 +3358,61 @@ function resolve_enum_fields(fields, project_path) {
|
|
|
3358
3358
|
}
|
|
3359
3359
|
} catch {}
|
|
3360
3360
|
}
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
Boolean: "0",
|
|
3381
|
-
String: "",
|
|
3382
|
-
Byte: "0",
|
|
3383
|
-
SByte: "0",
|
|
3384
|
-
Int16: "0",
|
|
3385
|
-
UInt16: "0",
|
|
3386
|
-
UInt32: "0",
|
|
3387
|
-
Int64: "0",
|
|
3388
|
-
UInt64: "0",
|
|
3389
|
-
Char: "0"
|
|
3390
|
-
};
|
|
3391
|
-
var STRUCT_DEFAULTS = {
|
|
3392
|
-
Vector2: "{x: 0, y: 0}",
|
|
3393
|
-
Vector3: "{x: 0, y: 0, z: 0}",
|
|
3394
|
-
Vector4: "{x: 0, y: 0, z: 0, w: 0}",
|
|
3395
|
-
Vector2Int: "{x: 0, y: 0}",
|
|
3396
|
-
Vector3Int: "{x: 0, y: 0, z: 0}",
|
|
3397
|
-
Quaternion: "{x: 0, y: 0, z: 0, w: 1}",
|
|
3398
|
-
Color: "{r: 0, g: 0, b: 0, a: 0}",
|
|
3399
|
-
Color32: "{r: 0, g: 0, b: 0, a: 0}",
|
|
3400
|
-
Rect: `serializedVersion: 2
|
|
3401
|
-
x: 0
|
|
3402
|
-
y: 0
|
|
3403
|
-
width: 0
|
|
3404
|
-
height: 0`,
|
|
3405
|
-
RectInt: "{x: 0, y: 0, width: 0, height: 0}",
|
|
3406
|
-
RectOffset: "{m_Left: 0, m_Right: 0, m_Top: 0, m_Bottom: 0}",
|
|
3407
|
-
Matrix4x4: "{e00: 1, e01: 0, e02: 0, e03: 0, e10: 0, e11: 1, e12: 0, e13: 0, e20: 0, e21: 0, e22: 1, e23: 0, e30: 0, e31: 0, e32: 0, e33: 1}",
|
|
3408
|
-
LayerMask: `serializedVersion: 2
|
|
3409
|
-
m_Bits: 0`
|
|
3410
|
-
};
|
|
3411
|
-
var VERSION_GATED_STRUCT_DEFAULTS = {
|
|
3412
|
-
Hash128: { value: `serializedVersion: 2
|
|
3413
|
-
Hash: 00000000000000000000000000000000`, min_major: 2021, min_minor: 1 },
|
|
3414
|
-
RenderingLayerMask: { value: `serializedVersion: 2
|
|
3415
|
-
m_Bits: 0`, min_major: 6000, min_minor: 0 }
|
|
3416
|
-
};
|
|
3417
|
-
var BLOCK_STRUCT_DEFAULTS = {
|
|
3418
|
-
Bounds: `m_Center: {x: 0, y: 0, z: 0}
|
|
3419
|
-
m_Extent: {x: 0, y: 0, z: 0}`,
|
|
3420
|
-
BoundsInt: `m_Position: {x: 0, y: 0, z: 0}
|
|
3421
|
-
m_Size: {x: 0, y: 0, z: 0}`
|
|
3422
|
-
};
|
|
3423
|
-
var OBJECT_REF_TYPES = new Set([
|
|
3424
|
-
"GameObject",
|
|
3425
|
-
"Transform",
|
|
3426
|
-
"RectTransform",
|
|
3427
|
-
"Material",
|
|
3428
|
-
"Texture",
|
|
3429
|
-
"Texture2D",
|
|
3430
|
-
"Texture3D",
|
|
3431
|
-
"RenderTexture",
|
|
3432
|
-
"Sprite",
|
|
3433
|
-
"AudioClip",
|
|
3434
|
-
"VideoClip",
|
|
3435
|
-
"Mesh",
|
|
3436
|
-
"Shader",
|
|
3437
|
-
"ComputeShader",
|
|
3438
|
-
"AnimationClip",
|
|
3439
|
-
"AnimatorController",
|
|
3440
|
-
"RuntimeAnimatorController",
|
|
3441
|
-
"PhysicMaterial",
|
|
3442
|
-
"PhysicsMaterial",
|
|
3443
|
-
"PhysicsMaterial2D",
|
|
3444
|
-
"Font",
|
|
3445
|
-
"TMP_FontAsset",
|
|
3446
|
-
"Object",
|
|
3447
|
-
"Component",
|
|
3448
|
-
"Behaviour",
|
|
3449
|
-
"MonoBehaviour",
|
|
3450
|
-
"ScriptableObject",
|
|
3451
|
-
"Rigidbody",
|
|
3452
|
-
"Rigidbody2D",
|
|
3453
|
-
"Collider",
|
|
3454
|
-
"Collider2D",
|
|
3455
|
-
"Camera",
|
|
3456
|
-
"Light",
|
|
3457
|
-
"Canvas",
|
|
3458
|
-
"CanvasGroup",
|
|
3459
|
-
"EventSystem",
|
|
3460
|
-
"AudioSource",
|
|
3461
|
-
"ParticleSystem",
|
|
3462
|
-
"TextAsset",
|
|
3463
|
-
"TerrainData"
|
|
3464
|
-
]);
|
|
3465
|
-
function version_at_least(version, min_major, min_minor) {
|
|
3466
|
-
if (!version)
|
|
3467
|
-
return false;
|
|
3468
|
-
if (version.major > min_major)
|
|
3469
|
-
return true;
|
|
3470
|
-
if (version.major === min_major)
|
|
3471
|
-
return version.minor >= min_minor;
|
|
3472
|
-
return false;
|
|
3473
|
-
}
|
|
3474
|
-
function yaml_default_for_type(csharp_type, version) {
|
|
3475
|
-
if (csharp_type.endsWith("?")) {
|
|
3476
|
-
return null;
|
|
3477
|
-
}
|
|
3478
|
-
if (csharp_type in PRIMITIVE_DEFAULTS) {
|
|
3479
|
-
return PRIMITIVE_DEFAULTS[csharp_type];
|
|
3480
|
-
}
|
|
3481
|
-
if (csharp_type in STRUCT_DEFAULTS) {
|
|
3482
|
-
return STRUCT_DEFAULTS[csharp_type];
|
|
3483
|
-
}
|
|
3484
|
-
if (csharp_type in VERSION_GATED_STRUCT_DEFAULTS) {
|
|
3485
|
-
const gated = VERSION_GATED_STRUCT_DEFAULTS[csharp_type];
|
|
3486
|
-
if (version_at_least(version, gated.min_major, gated.min_minor)) {
|
|
3487
|
-
return gated.value;
|
|
3488
|
-
}
|
|
3489
|
-
return null;
|
|
3490
|
-
}
|
|
3491
|
-
if (csharp_type in BLOCK_STRUCT_DEFAULTS) {
|
|
3492
|
-
return BLOCK_STRUCT_DEFAULTS[csharp_type];
|
|
3493
|
-
}
|
|
3494
|
-
if (csharp_type.endsWith("[]")) {
|
|
3495
|
-
return "[]";
|
|
3496
|
-
}
|
|
3497
|
-
if (csharp_type.startsWith("List<") && csharp_type.endsWith(">")) {
|
|
3498
|
-
return "[]";
|
|
3499
|
-
}
|
|
3500
|
-
if (OBJECT_REF_TYPES.has(csharp_type)) {
|
|
3501
|
-
return "{fileID: 0}";
|
|
3502
|
-
}
|
|
3503
|
-
return "{fileID: 0}";
|
|
3504
|
-
}
|
|
3505
|
-
function generate_field_yaml(fields, version, indent = " ") {
|
|
3506
|
-
const lines = [];
|
|
3507
|
-
for (const field of fields) {
|
|
3508
|
-
if (field.hasSerializeReference) {
|
|
3509
|
-
const t = field.typeName;
|
|
3510
|
-
if (t.endsWith("[]") || t.startsWith("List<") && t.endsWith(">")) {
|
|
3511
|
-
lines.push(`${indent}${field.name}: []`);
|
|
3512
|
-
} else {
|
|
3513
|
-
lines.push(`${indent}${field.name}:`);
|
|
3514
|
-
lines.push(`${indent} rid: 0`);
|
|
3361
|
+
function build_type_lookup(project_path) {
|
|
3362
|
+
let extractFn = null;
|
|
3363
|
+
try {
|
|
3364
|
+
const { getNativeExtractSerializedFields: getNativeExtractSerializedFields2 } = (init_scanner(), __toCommonJS(exports_scanner));
|
|
3365
|
+
extractFn = getNativeExtractSerializedFields2();
|
|
3366
|
+
} catch {}
|
|
3367
|
+
if (!extractFn)
|
|
3368
|
+
return () => null;
|
|
3369
|
+
const assetsDir = path.join(project_path, "Assets");
|
|
3370
|
+
const csIndex = new Map;
|
|
3371
|
+
try {
|
|
3372
|
+
const { readdirSync: readdirSync3 } = require("fs");
|
|
3373
|
+
const entries = readdirSync3(assetsDir, { recursive: true, withFileTypes: false });
|
|
3374
|
+
for (const entry of entries) {
|
|
3375
|
+
if (typeof entry === "string" && entry.endsWith(".cs")) {
|
|
3376
|
+
const basename3 = entry.substring(entry.lastIndexOf("/") + 1).replace(/\.cs$/, "");
|
|
3377
|
+
if (!csIndex.has(basename3)) {
|
|
3378
|
+
csIndex.set(basename3, path.join(assetsDir, entry));
|
|
3379
|
+
}
|
|
3515
3380
|
}
|
|
3516
|
-
continue;
|
|
3517
3381
|
}
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3382
|
+
} catch {}
|
|
3383
|
+
if (csIndex.size === 0)
|
|
3384
|
+
return () => null;
|
|
3385
|
+
const cache = new Map;
|
|
3386
|
+
return (typeName) => {
|
|
3387
|
+
if (cache.has(typeName))
|
|
3388
|
+
return cache.get(typeName) ?? null;
|
|
3389
|
+
const shortName = typeName.includes(".") ? typeName.substring(typeName.lastIndexOf(".") + 1) : typeName;
|
|
3390
|
+
const csPath = csIndex.get(shortName);
|
|
3391
|
+
if (!csPath || !import_fs6.existsSync(csPath)) {
|
|
3392
|
+
cache.set(typeName, null);
|
|
3393
|
+
return null;
|
|
3521
3394
|
}
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
lines.push(`${indent}${sub_line}`);
|
|
3395
|
+
try {
|
|
3396
|
+
const typeInfos = extractFn(csPath);
|
|
3397
|
+
if (!typeInfos || typeInfos.length === 0) {
|
|
3398
|
+
cache.set(typeName, null);
|
|
3399
|
+
return null;
|
|
3528
3400
|
}
|
|
3529
|
-
|
|
3530
|
-
|
|
3401
|
+
const match = typeInfos.find((t) => t.name === shortName);
|
|
3402
|
+
if (match && match.fields && match.fields.length > 0) {
|
|
3403
|
+
resolve_enum_fields(match.fields, project_path);
|
|
3404
|
+
cache.set(typeName, match.fields);
|
|
3405
|
+
return match.fields;
|
|
3406
|
+
}
|
|
3407
|
+
cache.set(typeName, null);
|
|
3408
|
+
return null;
|
|
3409
|
+
} catch {
|
|
3410
|
+
cache.set(typeName, null);
|
|
3411
|
+
return null;
|
|
3531
3412
|
}
|
|
3532
|
-
}
|
|
3533
|
-
return lines.length > 0 ? `
|
|
3534
|
-
` + lines.join(`
|
|
3535
|
-
`) + `
|
|
3536
|
-
` : `
|
|
3537
|
-
`;
|
|
3413
|
+
};
|
|
3538
3414
|
}
|
|
3539
3415
|
|
|
3540
|
-
// src/editor/unity-document.ts
|
|
3541
|
-
var import_fs7 = require("fs");
|
|
3542
|
-
|
|
3543
3416
|
// src/editor/unity-block.ts
|
|
3544
3417
|
var HEADER_PATTERN = /^--- !u!(\d+) &(-?\d+)(\s+stripped)?/;
|
|
3545
3418
|
function parse_header(raw) {
|
|
@@ -3635,10 +3508,36 @@ class UnityBlock {
|
|
|
3635
3508
|
const old_raw = this._raw;
|
|
3636
3509
|
const effective_ref = object_reference && object_reference !== "{fileID: 0}" ? object_reference : undefined;
|
|
3637
3510
|
if (!path2.includes(".") && !path2.includes("Array")) {
|
|
3638
|
-
const prop_pattern = new RegExp(`(^\\s*${escape_regex(path2)}
|
|
3639
|
-
|
|
3511
|
+
const prop_pattern = new RegExp(`(^\\s*${escape_regex(path2)}:[ \\t]*)(.*)$`, "m");
|
|
3512
|
+
const match = this._raw.match(prop_pattern);
|
|
3513
|
+
if (match && match.index !== undefined) {
|
|
3640
3514
|
const replacement_value = effective_ref ?? yaml_quote_if_needed(value);
|
|
3641
|
-
|
|
3515
|
+
const current_inline = match[2];
|
|
3516
|
+
if (current_inline.trim() === "") {
|
|
3517
|
+
const key_indent = (match[0].match(/^[ \t]*/)?.[0] || "").length;
|
|
3518
|
+
const after = match.index + match[0].length;
|
|
3519
|
+
let end = after;
|
|
3520
|
+
const rest = this._raw.slice(after);
|
|
3521
|
+
const rest_lines = rest.split(`
|
|
3522
|
+
`);
|
|
3523
|
+
for (let i = 1;i < rest_lines.length; i++) {
|
|
3524
|
+
const line = rest_lines[i];
|
|
3525
|
+
if (line.trim() === "") {
|
|
3526
|
+
end += 1 + line.length;
|
|
3527
|
+
continue;
|
|
3528
|
+
}
|
|
3529
|
+
const line_indent = (line.match(/^[ \t]*/)?.[0] || "").length;
|
|
3530
|
+
if (line_indent > key_indent) {
|
|
3531
|
+
end += 1 + line.length;
|
|
3532
|
+
} else {
|
|
3533
|
+
break;
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
const prefix = match[1].trimEnd() + " ";
|
|
3537
|
+
this._raw = this._raw.slice(0, match.index) + prefix + replacement_value + this._raw.slice(end);
|
|
3538
|
+
} else {
|
|
3539
|
+
this._raw = this._raw.replace(prop_pattern, (_match, prefix) => prefix + replacement_value);
|
|
3540
|
+
}
|
|
3642
3541
|
} else {
|
|
3643
3542
|
const insert_value = effective_ref ?? yaml_quote_if_needed(value);
|
|
3644
3543
|
this._insert_property(path2, insert_value);
|
|
@@ -3718,6 +3617,11 @@ class UnityBlock {
|
|
|
3718
3617
|
if (parent_pattern.test(this._raw)) {
|
|
3719
3618
|
return;
|
|
3720
3619
|
}
|
|
3620
|
+
const alt = parent.startsWith("m_") ? parent.slice(2) : "m_" + parent;
|
|
3621
|
+
const alt_pattern = new RegExp(`^[ \\t]*${escape_regex(alt)}:`, "m");
|
|
3622
|
+
if (alt_pattern.test(this._raw)) {
|
|
3623
|
+
return;
|
|
3624
|
+
}
|
|
3721
3625
|
const struct_block = ` ${parent}:
|
|
3722
3626
|
${child}: ${value}`;
|
|
3723
3627
|
const eci_pattern = /^([ \t]*m_EditorClassIdentifier:[ \t]*[^\n]*)/m;
|
|
@@ -4020,81 +3924,359 @@ ${element_indent2}- ${value}`);
|
|
|
4020
3924
|
}
|
|
4021
3925
|
return null;
|
|
4022
3926
|
}
|
|
4023
|
-
_resolve_block_style_path(segments, value) {
|
|
4024
|
-
const lines = this._raw.split(`
|
|
4025
|
-
`);
|
|
4026
|
-
let search_start = 0;
|
|
4027
|
-
let search_end = lines.length;
|
|
4028
|
-
for (let seg = 0;seg < segments.length - 1; seg++) {
|
|
4029
|
-
const segment = segments[seg];
|
|
4030
|
-
let parent_idx = -1;
|
|
4031
|
-
let parent_indent = -1;
|
|
4032
|
-
for (let i = search_start;i < search_end; i++) {
|
|
4033
|
-
const match = lines[i].match(new RegExp(`^(\\s*)${escape_regex(segment)}:\\s*(.*)$`));
|
|
4034
|
-
if (match) {
|
|
4035
|
-
const trailing = match[2].trim();
|
|
4036
|
-
if (trailing === "") {
|
|
4037
|
-
parent_idx = i;
|
|
4038
|
-
parent_indent = match[1].length;
|
|
4039
|
-
break;
|
|
4040
|
-
}
|
|
4041
|
-
for (let j = i + 1;j < search_end; j++) {
|
|
4042
|
-
if (lines[j].trim() === "")
|
|
4043
|
-
continue;
|
|
4044
|
-
const nextLeading = lines[j].match(/^(\s*)/);
|
|
4045
|
-
if (nextLeading && nextLeading[1].length > match[1].length) {
|
|
4046
|
-
parent_idx = i;
|
|
4047
|
-
parent_indent = match[1].length;
|
|
4048
|
-
}
|
|
4049
|
-
break;
|
|
4050
|
-
}
|
|
4051
|
-
if (parent_idx !== -1)
|
|
4052
|
-
break;
|
|
4053
|
-
}
|
|
3927
|
+
_resolve_block_style_path(segments, value) {
|
|
3928
|
+
const lines = this._raw.split(`
|
|
3929
|
+
`);
|
|
3930
|
+
let search_start = 0;
|
|
3931
|
+
let search_end = lines.length;
|
|
3932
|
+
for (let seg = 0;seg < segments.length - 1; seg++) {
|
|
3933
|
+
const segment = segments[seg];
|
|
3934
|
+
let parent_idx = -1;
|
|
3935
|
+
let parent_indent = -1;
|
|
3936
|
+
for (let i = search_start;i < search_end; i++) {
|
|
3937
|
+
const match = lines[i].match(new RegExp(`^(\\s*)${escape_regex(segment)}:\\s*(.*)$`));
|
|
3938
|
+
if (match) {
|
|
3939
|
+
const trailing = match[2].trim();
|
|
3940
|
+
if (trailing === "") {
|
|
3941
|
+
parent_idx = i;
|
|
3942
|
+
parent_indent = match[1].length;
|
|
3943
|
+
break;
|
|
3944
|
+
}
|
|
3945
|
+
for (let j = i + 1;j < search_end; j++) {
|
|
3946
|
+
if (lines[j].trim() === "")
|
|
3947
|
+
continue;
|
|
3948
|
+
const nextLeading = lines[j].match(/^(\s*)/);
|
|
3949
|
+
if (nextLeading && nextLeading[1].length > match[1].length) {
|
|
3950
|
+
parent_idx = i;
|
|
3951
|
+
parent_indent = match[1].length;
|
|
3952
|
+
}
|
|
3953
|
+
break;
|
|
3954
|
+
}
|
|
3955
|
+
if (parent_idx !== -1)
|
|
3956
|
+
break;
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
if (parent_idx === -1)
|
|
3960
|
+
return null;
|
|
3961
|
+
let child_indent = -1;
|
|
3962
|
+
for (let i = parent_idx + 1;i < search_end; i++) {
|
|
3963
|
+
if (lines[i].trim() === "")
|
|
3964
|
+
continue;
|
|
3965
|
+
const leading_spaces = lines[i].match(/^(\s*)/);
|
|
3966
|
+
if (leading_spaces) {
|
|
3967
|
+
const indent = leading_spaces[1].length;
|
|
3968
|
+
if (indent > parent_indent) {
|
|
3969
|
+
child_indent = indent;
|
|
3970
|
+
break;
|
|
3971
|
+
}
|
|
3972
|
+
}
|
|
3973
|
+
break;
|
|
3974
|
+
}
|
|
3975
|
+
if (child_indent === -1)
|
|
3976
|
+
return null;
|
|
3977
|
+
search_start = parent_idx + 1;
|
|
3978
|
+
for (let i = parent_idx + 1;i < search_end; i++) {
|
|
3979
|
+
if (lines[i].trim() === "")
|
|
3980
|
+
continue;
|
|
3981
|
+
const leading_spaces = lines[i].match(/^(\s*)/);
|
|
3982
|
+
if (leading_spaces && leading_spaces[1].length < child_indent) {
|
|
3983
|
+
search_end = i;
|
|
3984
|
+
break;
|
|
3985
|
+
}
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
const final_prop = segments[segments.length - 1];
|
|
3989
|
+
for (let i = search_start;i < search_end; i++) {
|
|
3990
|
+
const match = lines[i].match(new RegExp(`^(\\s*${escape_regex(final_prop)}:\\s*).+$`));
|
|
3991
|
+
if (match) {
|
|
3992
|
+
lines[i] = match[1] + value;
|
|
3993
|
+
return lines.join(`
|
|
3994
|
+
`);
|
|
3995
|
+
}
|
|
3996
|
+
}
|
|
3997
|
+
return null;
|
|
3998
|
+
}
|
|
3999
|
+
}
|
|
4000
|
+
|
|
4001
|
+
// src/editor/yaml-fields.ts
|
|
4002
|
+
var PRIMITIVE_DEFAULTS = {
|
|
4003
|
+
int: "0",
|
|
4004
|
+
float: "0",
|
|
4005
|
+
double: "0",
|
|
4006
|
+
bool: "0",
|
|
4007
|
+
string: "",
|
|
4008
|
+
byte: "0",
|
|
4009
|
+
sbyte: "0",
|
|
4010
|
+
short: "0",
|
|
4011
|
+
ushort: "0",
|
|
4012
|
+
uint: "0",
|
|
4013
|
+
long: "0",
|
|
4014
|
+
ulong: "0",
|
|
4015
|
+
char: "0",
|
|
4016
|
+
Int32: "0",
|
|
4017
|
+
Single: "0",
|
|
4018
|
+
Double: "0",
|
|
4019
|
+
Boolean: "0",
|
|
4020
|
+
String: "",
|
|
4021
|
+
Byte: "0",
|
|
4022
|
+
SByte: "0",
|
|
4023
|
+
Int16: "0",
|
|
4024
|
+
UInt16: "0",
|
|
4025
|
+
UInt32: "0",
|
|
4026
|
+
Int64: "0",
|
|
4027
|
+
UInt64: "0",
|
|
4028
|
+
Char: "0"
|
|
4029
|
+
};
|
|
4030
|
+
var STRUCT_DEFAULTS = {
|
|
4031
|
+
Vector2: "{x: 0, y: 0}",
|
|
4032
|
+
Vector3: "{x: 0, y: 0, z: 0}",
|
|
4033
|
+
Vector4: "{x: 0, y: 0, z: 0, w: 0}",
|
|
4034
|
+
Vector2Int: "{x: 0, y: 0}",
|
|
4035
|
+
Vector3Int: "{x: 0, y: 0, z: 0}",
|
|
4036
|
+
Quaternion: "{x: 0, y: 0, z: 0, w: 1}",
|
|
4037
|
+
Color: "{r: 0, g: 0, b: 0, a: 0}",
|
|
4038
|
+
Color32: "{r: 0, g: 0, b: 0, a: 0}",
|
|
4039
|
+
Rect: `serializedVersion: 2
|
|
4040
|
+
x: 0
|
|
4041
|
+
y: 0
|
|
4042
|
+
width: 0
|
|
4043
|
+
height: 0`,
|
|
4044
|
+
RectInt: "{x: 0, y: 0, width: 0, height: 0}",
|
|
4045
|
+
RectOffset: "{m_Left: 0, m_Right: 0, m_Top: 0, m_Bottom: 0}",
|
|
4046
|
+
Matrix4x4: "{e00: 1, e01: 0, e02: 0, e03: 0, e10: 0, e11: 1, e12: 0, e13: 0, e20: 0, e21: 0, e22: 1, e23: 0, e30: 0, e31: 0, e32: 0, e33: 1}",
|
|
4047
|
+
LayerMask: `serializedVersion: 2
|
|
4048
|
+
m_Bits: 0`
|
|
4049
|
+
};
|
|
4050
|
+
var VERSION_GATED_STRUCT_DEFAULTS = {
|
|
4051
|
+
Hash128: { value: `serializedVersion: 2
|
|
4052
|
+
Hash: 00000000000000000000000000000000`, min_major: 2021, min_minor: 1 },
|
|
4053
|
+
RenderingLayerMask: { value: `serializedVersion: 2
|
|
4054
|
+
m_Bits: 0`, min_major: 6000, min_minor: 0 }
|
|
4055
|
+
};
|
|
4056
|
+
var BLOCK_STRUCT_DEFAULTS = {
|
|
4057
|
+
Bounds: `m_Center: {x: 0, y: 0, z: 0}
|
|
4058
|
+
m_Extent: {x: 0, y: 0, z: 0}`,
|
|
4059
|
+
BoundsInt: `m_Position: {x: 0, y: 0, z: 0}
|
|
4060
|
+
m_Size: {x: 0, y: 0, z: 0}`
|
|
4061
|
+
};
|
|
4062
|
+
var OBJECT_REF_TYPES = new Set([
|
|
4063
|
+
"GameObject",
|
|
4064
|
+
"Transform",
|
|
4065
|
+
"RectTransform",
|
|
4066
|
+
"Material",
|
|
4067
|
+
"Texture",
|
|
4068
|
+
"Texture2D",
|
|
4069
|
+
"Texture3D",
|
|
4070
|
+
"RenderTexture",
|
|
4071
|
+
"Sprite",
|
|
4072
|
+
"AudioClip",
|
|
4073
|
+
"VideoClip",
|
|
4074
|
+
"Mesh",
|
|
4075
|
+
"Shader",
|
|
4076
|
+
"ComputeShader",
|
|
4077
|
+
"AnimationClip",
|
|
4078
|
+
"AnimatorController",
|
|
4079
|
+
"RuntimeAnimatorController",
|
|
4080
|
+
"PhysicMaterial",
|
|
4081
|
+
"PhysicsMaterial",
|
|
4082
|
+
"PhysicsMaterial2D",
|
|
4083
|
+
"Font",
|
|
4084
|
+
"TMP_FontAsset",
|
|
4085
|
+
"Object",
|
|
4086
|
+
"Component",
|
|
4087
|
+
"Behaviour",
|
|
4088
|
+
"MonoBehaviour",
|
|
4089
|
+
"ScriptableObject",
|
|
4090
|
+
"Rigidbody",
|
|
4091
|
+
"Rigidbody2D",
|
|
4092
|
+
"Collider",
|
|
4093
|
+
"Collider2D",
|
|
4094
|
+
"Camera",
|
|
4095
|
+
"Light",
|
|
4096
|
+
"Canvas",
|
|
4097
|
+
"CanvasGroup",
|
|
4098
|
+
"EventSystem",
|
|
4099
|
+
"AudioSource",
|
|
4100
|
+
"ParticleSystem",
|
|
4101
|
+
"TextAsset",
|
|
4102
|
+
"TerrainData"
|
|
4103
|
+
]);
|
|
4104
|
+
function version_at_least(version, min_major, min_minor) {
|
|
4105
|
+
if (!version)
|
|
4106
|
+
return false;
|
|
4107
|
+
if (version.major > min_major)
|
|
4108
|
+
return true;
|
|
4109
|
+
if (version.major === min_major)
|
|
4110
|
+
return version.minor >= min_minor;
|
|
4111
|
+
return false;
|
|
4112
|
+
}
|
|
4113
|
+
function yaml_default_for_type(csharp_type, version) {
|
|
4114
|
+
if (csharp_type.endsWith("?")) {
|
|
4115
|
+
return null;
|
|
4116
|
+
}
|
|
4117
|
+
if (csharp_type in PRIMITIVE_DEFAULTS) {
|
|
4118
|
+
return PRIMITIVE_DEFAULTS[csharp_type];
|
|
4119
|
+
}
|
|
4120
|
+
if (csharp_type in STRUCT_DEFAULTS) {
|
|
4121
|
+
return STRUCT_DEFAULTS[csharp_type];
|
|
4122
|
+
}
|
|
4123
|
+
if (csharp_type in VERSION_GATED_STRUCT_DEFAULTS) {
|
|
4124
|
+
const gated = VERSION_GATED_STRUCT_DEFAULTS[csharp_type];
|
|
4125
|
+
if (version_at_least(version, gated.min_major, gated.min_minor)) {
|
|
4126
|
+
return gated.value;
|
|
4127
|
+
}
|
|
4128
|
+
return null;
|
|
4129
|
+
}
|
|
4130
|
+
if (csharp_type in BLOCK_STRUCT_DEFAULTS) {
|
|
4131
|
+
return BLOCK_STRUCT_DEFAULTS[csharp_type];
|
|
4132
|
+
}
|
|
4133
|
+
if (csharp_type.endsWith("[]")) {
|
|
4134
|
+
return "[]";
|
|
4135
|
+
}
|
|
4136
|
+
if (csharp_type.startsWith("List<") && csharp_type.endsWith(">")) {
|
|
4137
|
+
return "[]";
|
|
4138
|
+
}
|
|
4139
|
+
if (OBJECT_REF_TYPES.has(csharp_type)) {
|
|
4140
|
+
return "{fileID: 0}";
|
|
4141
|
+
}
|
|
4142
|
+
return "{fileID: 0}";
|
|
4143
|
+
}
|
|
4144
|
+
function generate_field_yaml(fields, version, indent = " ", type_lookup) {
|
|
4145
|
+
const lines = [];
|
|
4146
|
+
for (const field of fields) {
|
|
4147
|
+
if (field.hasSerializeReference) {
|
|
4148
|
+
const t = field.typeName;
|
|
4149
|
+
if (t.endsWith("[]") || t.startsWith("List<") && t.endsWith(">")) {
|
|
4150
|
+
lines.push(`${indent}${field.name}: []`);
|
|
4151
|
+
} else {
|
|
4152
|
+
lines.push(`${indent}${field.name}:`);
|
|
4153
|
+
lines.push(`${indent} rid: 0`);
|
|
4054
4154
|
}
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4155
|
+
continue;
|
|
4156
|
+
}
|
|
4157
|
+
const default_value = yaml_default_for_type(field.typeName, version);
|
|
4158
|
+
if (default_value === null) {
|
|
4159
|
+
continue;
|
|
4160
|
+
}
|
|
4161
|
+
if (default_value === "{fileID: 0}" && type_lookup) {
|
|
4162
|
+
const struct_fields = type_lookup(field.typeName);
|
|
4163
|
+
if (struct_fields && struct_fields.length > 0) {
|
|
4164
|
+
lines.push(`${indent}${field.name}:`);
|
|
4165
|
+
const nested = generate_field_yaml(struct_fields, version, indent + " ", type_lookup);
|
|
4166
|
+
const nested_lines = nested.slice(1).replace(/\n$/, "").split(`
|
|
4167
|
+
`);
|
|
4168
|
+
for (const nl of nested_lines) {
|
|
4169
|
+
lines.push(nl);
|
|
4068
4170
|
}
|
|
4069
|
-
|
|
4171
|
+
continue;
|
|
4070
4172
|
}
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
if (leading_spaces && leading_spaces[1].length < child_indent) {
|
|
4079
|
-
search_end = i;
|
|
4080
|
-
break;
|
|
4081
|
-
}
|
|
4173
|
+
}
|
|
4174
|
+
if (default_value.includes(`
|
|
4175
|
+
`)) {
|
|
4176
|
+
lines.push(`${indent}${field.name}:`);
|
|
4177
|
+
for (const sub_line of default_value.split(`
|
|
4178
|
+
`)) {
|
|
4179
|
+
lines.push(`${indent}${sub_line}`);
|
|
4082
4180
|
}
|
|
4181
|
+
} else {
|
|
4182
|
+
lines.push(`${indent}${field.name}: ${default_value}`);
|
|
4083
4183
|
}
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4184
|
+
}
|
|
4185
|
+
return lines.length > 0 ? `
|
|
4186
|
+
` + lines.join(`
|
|
4187
|
+
`) + `
|
|
4188
|
+
` : `
|
|
4189
|
+
`;
|
|
4190
|
+
}
|
|
4191
|
+
function json_value_to_yaml_lines(value, indent = " ") {
|
|
4192
|
+
if (value === null || value === undefined) {
|
|
4193
|
+
return [""];
|
|
4194
|
+
}
|
|
4195
|
+
if (typeof value === "string") {
|
|
4196
|
+
return [yaml_quote_if_needed(value)];
|
|
4197
|
+
}
|
|
4198
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
4199
|
+
return [String(value)];
|
|
4200
|
+
}
|
|
4201
|
+
if (Array.isArray(value)) {
|
|
4202
|
+
if (value.length === 0)
|
|
4203
|
+
return ["[]"];
|
|
4204
|
+
const lines = [];
|
|
4205
|
+
for (const item of value) {
|
|
4206
|
+
if (is_scalar(item) || is_empty_collection(item)) {
|
|
4207
|
+
const scalar = json_value_to_yaml_lines(item);
|
|
4208
|
+
lines.push(`${indent}- ${scalar[0]}`);
|
|
4209
|
+
} else if (is_flow_mappable(item)) {
|
|
4210
|
+
lines.push(`${indent}- ${to_flow_mapping(item)}`);
|
|
4211
|
+
} else {
|
|
4212
|
+
const child_lines = json_value_to_yaml_lines(item, indent + " ");
|
|
4213
|
+
lines.push(`${indent}- ${child_lines[0].trimStart()}`);
|
|
4214
|
+
for (let i = 1;i < child_lines.length; i++) {
|
|
4215
|
+
lines.push(child_lines[i]);
|
|
4216
|
+
}
|
|
4217
|
+
}
|
|
4218
|
+
}
|
|
4219
|
+
return lines;
|
|
4220
|
+
}
|
|
4221
|
+
if (typeof value === "object") {
|
|
4222
|
+
const entries = Object.entries(value);
|
|
4223
|
+
if (entries.length === 0)
|
|
4224
|
+
return ["{}"];
|
|
4225
|
+
const lines = [];
|
|
4226
|
+
for (const [key, val] of entries) {
|
|
4227
|
+
if (is_scalar(val) || is_empty_collection(val)) {
|
|
4228
|
+
const scalar = json_value_to_yaml_lines(val);
|
|
4229
|
+
lines.push(`${indent}${key}: ${scalar[0]}`);
|
|
4230
|
+
} else if (is_flow_mappable(val)) {
|
|
4231
|
+
lines.push(`${indent}${key}: ${to_flow_mapping(val)}`);
|
|
4232
|
+
} else {
|
|
4233
|
+
const child_indent = Array.isArray(val) ? indent : indent + " ";
|
|
4234
|
+
lines.push(`${indent}${key}:`);
|
|
4235
|
+
const child_lines = json_value_to_yaml_lines(val, child_indent);
|
|
4236
|
+
for (const cl of child_lines) {
|
|
4237
|
+
lines.push(cl);
|
|
4238
|
+
}
|
|
4091
4239
|
}
|
|
4092
4240
|
}
|
|
4093
|
-
return
|
|
4241
|
+
return lines;
|
|
4094
4242
|
}
|
|
4243
|
+
return [String(value)];
|
|
4244
|
+
}
|
|
4245
|
+
function is_scalar(value) {
|
|
4246
|
+
return value === null || value === undefined || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
4247
|
+
}
|
|
4248
|
+
function is_empty_collection(value) {
|
|
4249
|
+
if (Array.isArray(value))
|
|
4250
|
+
return value.length === 0;
|
|
4251
|
+
if (typeof value === "object" && value !== null)
|
|
4252
|
+
return Object.keys(value).length === 0;
|
|
4253
|
+
return false;
|
|
4254
|
+
}
|
|
4255
|
+
function is_flow_mappable(value) {
|
|
4256
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
4257
|
+
return false;
|
|
4258
|
+
const entries = Object.entries(value);
|
|
4259
|
+
if (entries.length === 0)
|
|
4260
|
+
return false;
|
|
4261
|
+
return entries.every(([, v]) => is_scalar(v) || is_empty_collection(v));
|
|
4262
|
+
}
|
|
4263
|
+
function to_flow_mapping(obj) {
|
|
4264
|
+
const parts = Object.entries(obj).map(([k, v]) => {
|
|
4265
|
+
if (v === null || v === undefined)
|
|
4266
|
+
return `${k}: `;
|
|
4267
|
+
if (typeof v === "string")
|
|
4268
|
+
return `${k}: ${yaml_quote_if_needed(v)}`;
|
|
4269
|
+
if (Array.isArray(v) && v.length === 0)
|
|
4270
|
+
return `${k}: []`;
|
|
4271
|
+
if (typeof v === "object" && v !== null && Object.keys(v).length === 0)
|
|
4272
|
+
return `${k}: {}`;
|
|
4273
|
+
return `${k}: ${String(v)}`;
|
|
4274
|
+
});
|
|
4275
|
+
return `{${parts.join(", ")}}`;
|
|
4095
4276
|
}
|
|
4096
4277
|
|
|
4097
4278
|
// src/editor/unity-document.ts
|
|
4279
|
+
var import_fs7 = require("fs");
|
|
4098
4280
|
class UnityDocument {
|
|
4099
4281
|
file_path;
|
|
4100
4282
|
_header;
|
|
@@ -5085,8 +5267,8 @@ function addComponentToGameObject(doc, gameObjectId, componentId) {
|
|
|
5085
5267
|
`);
|
|
5086
5268
|
goBlock.replace_raw(raw);
|
|
5087
5269
|
}
|
|
5088
|
-
function createMonoBehaviourYAML(componentId, gameObjectId, scriptGuid, fields, version, scriptFileId = 11500000) {
|
|
5089
|
-
const field_yaml = fields && fields.length > 0 ? generate_field_yaml(fields, version) : `
|
|
5270
|
+
function createMonoBehaviourYAML(componentId, gameObjectId, scriptGuid, fields, version, scriptFileId = 11500000, type_lookup) {
|
|
5271
|
+
const field_yaml = fields && fields.length > 0 ? generate_field_yaml(fields, version, " ", type_lookup) : `
|
|
5090
5272
|
`;
|
|
5091
5273
|
const has_serialize_ref = fields?.some((f) => f.hasSerializeReference) ?? false;
|
|
5092
5274
|
const references_section = has_serialize_ref ? ` references:
|
|
@@ -5744,6 +5926,170 @@ PrefabImporter:
|
|
|
5744
5926
|
prefab_instance_id: prefabInstanceId
|
|
5745
5927
|
};
|
|
5746
5928
|
}
|
|
5929
|
+
function createPrefabInstance(options) {
|
|
5930
|
+
const { scene_path, prefab_path, name, parent, position } = options;
|
|
5931
|
+
const pathError = validate_file_path(scene_path, "write");
|
|
5932
|
+
if (pathError) {
|
|
5933
|
+
return { success: false, file_path: scene_path, error: pathError };
|
|
5934
|
+
}
|
|
5935
|
+
if (!scene_path.endsWith(".unity")) {
|
|
5936
|
+
return { success: false, file_path: scene_path, error: "Scene path must be a .unity file" };
|
|
5937
|
+
}
|
|
5938
|
+
if (!prefab_path.endsWith(".prefab")) {
|
|
5939
|
+
return { success: false, file_path: scene_path, error: "Prefab path must be a .prefab file" };
|
|
5940
|
+
}
|
|
5941
|
+
if (!import_fs8.existsSync(scene_path)) {
|
|
5942
|
+
return { success: false, file_path: scene_path, error: `Scene file not found: ${scene_path}` };
|
|
5943
|
+
}
|
|
5944
|
+
if (!import_fs8.existsSync(prefab_path)) {
|
|
5945
|
+
return { success: false, file_path: scene_path, error: `Prefab file not found: ${prefab_path}` };
|
|
5946
|
+
}
|
|
5947
|
+
const metaPath = prefab_path + ".meta";
|
|
5948
|
+
const sourceGuid = extractGuidFromMeta(metaPath);
|
|
5949
|
+
if (!sourceGuid) {
|
|
5950
|
+
return { success: false, file_path: scene_path, error: `Could not find or read .meta file for prefab: ${metaPath}` };
|
|
5951
|
+
}
|
|
5952
|
+
let prefabDoc;
|
|
5953
|
+
try {
|
|
5954
|
+
prefabDoc = UnityDocument.from_file(prefab_path);
|
|
5955
|
+
} catch (err) {
|
|
5956
|
+
return { success: false, file_path: scene_path, error: `Failed to read prefab: ${err instanceof Error ? err.message : String(err)}` };
|
|
5957
|
+
}
|
|
5958
|
+
const rootInfo = prefabDoc.find_prefab_root();
|
|
5959
|
+
if (!rootInfo) {
|
|
5960
|
+
return { success: false, file_path: scene_path, error: "Could not find root GameObject in source prefab" };
|
|
5961
|
+
}
|
|
5962
|
+
let doc;
|
|
5963
|
+
try {
|
|
5964
|
+
doc = UnityDocument.from_file(scene_path);
|
|
5965
|
+
} catch (err) {
|
|
5966
|
+
return { success: false, file_path: scene_path, error: `Failed to read scene: ${err instanceof Error ? err.message : String(err)}` };
|
|
5967
|
+
}
|
|
5968
|
+
let parentTransformIdStr = "0";
|
|
5969
|
+
if (parent !== undefined) {
|
|
5970
|
+
if (typeof parent === "number") {
|
|
5971
|
+
const parentIdStr = String(parent);
|
|
5972
|
+
const parentBlock = doc.find_by_file_id(parentIdStr);
|
|
5973
|
+
if (!parentBlock) {
|
|
5974
|
+
return { success: false, file_path: scene_path, error: `Parent with fileID ${parent} not found. Provide a GameObject or Transform fileID.` };
|
|
5975
|
+
}
|
|
5976
|
+
if (parentBlock.is_stripped) {
|
|
5977
|
+
return { success: false, file_path: scene_path, error: `Parent with fileID ${parent} is a stripped block (inside a PrefabInstance). Cannot parent to stripped transforms.` };
|
|
5978
|
+
}
|
|
5979
|
+
if (parentBlock.class_id === 4) {
|
|
5980
|
+
parentTransformIdStr = parentIdStr;
|
|
5981
|
+
} else if (parentBlock.class_id === 1) {
|
|
5982
|
+
const compMatch = parentBlock.raw.match(/m_Component:\s*\n\s*-\s*component:\s*\{fileID:\s*(\d+)\}/);
|
|
5983
|
+
if (compMatch) {
|
|
5984
|
+
parentTransformIdStr = compMatch[1];
|
|
5985
|
+
} else {
|
|
5986
|
+
return { success: false, file_path: scene_path, error: `Parent with fileID ${parent} has no Transform component.` };
|
|
5987
|
+
}
|
|
5988
|
+
} else {
|
|
5989
|
+
return { success: false, file_path: scene_path, error: `Parent with fileID ${parent} is not a GameObject or Transform.` };
|
|
5990
|
+
}
|
|
5991
|
+
} else {
|
|
5992
|
+
const foundResult = findTransformIdByName(doc, parent);
|
|
5993
|
+
if (foundResult === null) {
|
|
5994
|
+
return { success: false, file_path: scene_path, error: `Parent GameObject "${parent}" not found` };
|
|
5995
|
+
}
|
|
5996
|
+
if (typeof foundResult === "object") {
|
|
5997
|
+
return { success: false, file_path: scene_path, error: foundResult.error };
|
|
5998
|
+
}
|
|
5999
|
+
parentTransformIdStr = foundResult;
|
|
6000
|
+
}
|
|
6001
|
+
}
|
|
6002
|
+
const prefabInstanceId = doc.generate_file_id();
|
|
6003
|
+
const strippedGoId = doc.generate_file_id();
|
|
6004
|
+
const strippedTransformId = doc.generate_file_id();
|
|
6005
|
+
const instanceName = name || path3.basename(prefab_path, ".prefab");
|
|
6006
|
+
const pos = position ?? { x: 0, y: 0, z: 0 };
|
|
6007
|
+
const rootGoFileId = rootInfo.game_object.file_id;
|
|
6008
|
+
const rootTransformFileId = rootInfo.transform.file_id;
|
|
6009
|
+
const yaml = `--- !u!1 &${strippedGoId} stripped
|
|
6010
|
+
GameObject:
|
|
6011
|
+
m_CorrespondingSourceObject: {fileID: ${rootGoFileId}, guid: ${sourceGuid}, type: 3}
|
|
6012
|
+
m_PrefabInstance: {fileID: ${prefabInstanceId}}
|
|
6013
|
+
m_PrefabAsset: {fileID: 0}
|
|
6014
|
+
--- !u!4 &${strippedTransformId} stripped
|
|
6015
|
+
Transform:
|
|
6016
|
+
m_CorrespondingSourceObject: {fileID: ${rootTransformFileId}, guid: ${sourceGuid}, type: 3}
|
|
6017
|
+
m_PrefabInstance: {fileID: ${prefabInstanceId}}
|
|
6018
|
+
m_PrefabAsset: {fileID: 0}
|
|
6019
|
+
--- !u!1001 &${prefabInstanceId}
|
|
6020
|
+
PrefabInstance:
|
|
6021
|
+
m_ObjectHideFlags: 0
|
|
6022
|
+
serializedVersion: 2
|
|
6023
|
+
m_Modification:
|
|
6024
|
+
m_TransformParent: {fileID: ${parentTransformIdStr}}
|
|
6025
|
+
m_Modifications:
|
|
6026
|
+
- target: {fileID: ${rootGoFileId}, guid: ${sourceGuid}, type: 3}
|
|
6027
|
+
propertyPath: m_Name
|
|
6028
|
+
value: ${instanceName}
|
|
6029
|
+
objectReference: {fileID: 0}
|
|
6030
|
+
- target: {fileID: ${rootTransformFileId}, guid: ${sourceGuid}, type: 3}
|
|
6031
|
+
propertyPath: m_LocalPosition.x
|
|
6032
|
+
value: ${pos.x}
|
|
6033
|
+
objectReference: {fileID: 0}
|
|
6034
|
+
- target: {fileID: ${rootTransformFileId}, guid: ${sourceGuid}, type: 3}
|
|
6035
|
+
propertyPath: m_LocalPosition.y
|
|
6036
|
+
value: ${pos.y}
|
|
6037
|
+
objectReference: {fileID: 0}
|
|
6038
|
+
- target: {fileID: ${rootTransformFileId}, guid: ${sourceGuid}, type: 3}
|
|
6039
|
+
propertyPath: m_LocalPosition.z
|
|
6040
|
+
value: ${pos.z}
|
|
6041
|
+
objectReference: {fileID: 0}
|
|
6042
|
+
- target: {fileID: ${rootTransformFileId}, guid: ${sourceGuid}, type: 3}
|
|
6043
|
+
propertyPath: m_LocalRotation.w
|
|
6044
|
+
value: 1
|
|
6045
|
+
objectReference: {fileID: 0}
|
|
6046
|
+
- target: {fileID: ${rootTransformFileId}, guid: ${sourceGuid}, type: 3}
|
|
6047
|
+
propertyPath: m_LocalRotation.x
|
|
6048
|
+
value: 0
|
|
6049
|
+
objectReference: {fileID: 0}
|
|
6050
|
+
- target: {fileID: ${rootTransformFileId}, guid: ${sourceGuid}, type: 3}
|
|
6051
|
+
propertyPath: m_LocalRotation.y
|
|
6052
|
+
value: 0
|
|
6053
|
+
objectReference: {fileID: 0}
|
|
6054
|
+
- target: {fileID: ${rootTransformFileId}, guid: ${sourceGuid}, type: 3}
|
|
6055
|
+
propertyPath: m_LocalRotation.z
|
|
6056
|
+
value: 0
|
|
6057
|
+
objectReference: {fileID: 0}
|
|
6058
|
+
- target: {fileID: ${rootTransformFileId}, guid: ${sourceGuid}, type: 3}
|
|
6059
|
+
propertyPath: m_LocalEulerAnglesHint.x
|
|
6060
|
+
value: 0
|
|
6061
|
+
objectReference: {fileID: 0}
|
|
6062
|
+
- target: {fileID: ${rootTransformFileId}, guid: ${sourceGuid}, type: 3}
|
|
6063
|
+
propertyPath: m_LocalEulerAnglesHint.y
|
|
6064
|
+
value: 0
|
|
6065
|
+
objectReference: {fileID: 0}
|
|
6066
|
+
- target: {fileID: ${rootTransformFileId}, guid: ${sourceGuid}, type: 3}
|
|
6067
|
+
propertyPath: m_LocalEulerAnglesHint.z
|
|
6068
|
+
value: 0
|
|
6069
|
+
objectReference: {fileID: 0}
|
|
6070
|
+
m_RemovedComponents: []
|
|
6071
|
+
m_RemovedGameObjects: []
|
|
6072
|
+
m_AddedGameObjects: []
|
|
6073
|
+
m_AddedComponents: []
|
|
6074
|
+
m_SourcePrefab: {fileID: 100100000, guid: ${sourceGuid}, type: 3}
|
|
6075
|
+
`;
|
|
6076
|
+
doc.append_raw(yaml);
|
|
6077
|
+
if (parentTransformIdStr !== "0") {
|
|
6078
|
+
doc.add_child_to_parent(parentTransformIdStr, strippedTransformId);
|
|
6079
|
+
}
|
|
6080
|
+
try {
|
|
6081
|
+
doc.save();
|
|
6082
|
+
} catch (err) {
|
|
6083
|
+
return { success: false, file_path: scene_path, error: `Failed to save scene: ${err instanceof Error ? err.message : String(err)}` };
|
|
6084
|
+
}
|
|
6085
|
+
return {
|
|
6086
|
+
success: true,
|
|
6087
|
+
file_path: scene_path,
|
|
6088
|
+
prefab_instance_id: prefabInstanceId,
|
|
6089
|
+
game_object_id: strippedGoId,
|
|
6090
|
+
transform_id: strippedTransformId
|
|
6091
|
+
};
|
|
6092
|
+
}
|
|
5747
6093
|
function createScriptableObject(options) {
|
|
5748
6094
|
const { output_path, script } = options;
|
|
5749
6095
|
const project_path = options.project_path || find_unity_project_root(path3.dirname(output_path)) || undefined;
|
|
@@ -5789,7 +6135,8 @@ function createScriptableObject(options) {
|
|
|
5789
6135
|
} catch {}
|
|
5790
6136
|
}
|
|
5791
6137
|
const baseName = path3.basename(output_path, ".asset");
|
|
5792
|
-
const
|
|
6138
|
+
const type_lookup = project_path ? build_type_lookup(project_path) : undefined;
|
|
6139
|
+
const field_yaml = resolved.fields && resolved.fields.length > 0 ? generate_field_yaml(resolved.fields, version, " ", type_lookup) : `
|
|
5793
6140
|
`;
|
|
5794
6141
|
let assetYaml = `%YAML 1.1
|
|
5795
6142
|
%TAG !u! tag:unity3d.com,2011:
|
|
@@ -5809,8 +6156,58 @@ MonoBehaviour:
|
|
|
5809
6156
|
const doc = UnityDocument.from_string(assetYaml);
|
|
5810
6157
|
const block = doc.blocks[0];
|
|
5811
6158
|
if (block) {
|
|
6159
|
+
const complex_entries = [];
|
|
5812
6160
|
for (const [key, val] of Object.entries(options.initial_values)) {
|
|
5813
|
-
|
|
6161
|
+
if (val === null || val === undefined || typeof val === "string" || typeof val === "number" || typeof val === "boolean") {
|
|
6162
|
+
block.set_property(key, String(val ?? ""));
|
|
6163
|
+
} else if (Array.isArray(val) && val.length === 0) {
|
|
6164
|
+
block.set_property(key, "[]");
|
|
6165
|
+
} else if (typeof val === "object" && val !== null && !Array.isArray(val) && Object.keys(val).length === 0) {
|
|
6166
|
+
block.set_property(key, "{}");
|
|
6167
|
+
} else {
|
|
6168
|
+
complex_entries.push([key, val]);
|
|
6169
|
+
}
|
|
6170
|
+
}
|
|
6171
|
+
if (complex_entries.length > 0) {
|
|
6172
|
+
let raw = block.raw;
|
|
6173
|
+
for (const [key, val] of complex_entries) {
|
|
6174
|
+
const yaml_lines = json_value_to_yaml_lines(val, " ");
|
|
6175
|
+
const key_pattern = new RegExp(`^([ \\t]*${key}:)[^\\n]*$`, "m");
|
|
6176
|
+
const key_match = raw.match(key_pattern);
|
|
6177
|
+
if (key_match && key_match.index !== undefined) {
|
|
6178
|
+
const key_indent = key_match[0].match(/^[ \t]*/)?.[0].length ?? 0;
|
|
6179
|
+
const after_key = key_match.index + key_match[0].length;
|
|
6180
|
+
let end = after_key;
|
|
6181
|
+
const remaining = raw.slice(after_key);
|
|
6182
|
+
const remaining_lines = remaining.split(`
|
|
6183
|
+
`);
|
|
6184
|
+
for (let i = 1;i < remaining_lines.length; i++) {
|
|
6185
|
+
const line = remaining_lines[i];
|
|
6186
|
+
if (line.trim() === "") {
|
|
6187
|
+
end += 1 + line.length;
|
|
6188
|
+
continue;
|
|
6189
|
+
}
|
|
6190
|
+
const line_indent = line.match(/^[ \t]*/)?.[0].length ?? 0;
|
|
6191
|
+
if (line_indent > key_indent) {
|
|
6192
|
+
end += 1 + line.length;
|
|
6193
|
+
} else {
|
|
6194
|
+
break;
|
|
6195
|
+
}
|
|
6196
|
+
}
|
|
6197
|
+
const block_yaml = ` ${key}:
|
|
6198
|
+
${yaml_lines.join(`
|
|
6199
|
+
`)}`;
|
|
6200
|
+
raw = raw.slice(0, key_match.index) + block_yaml + raw.slice(end);
|
|
6201
|
+
} else {
|
|
6202
|
+
const block_yaml = ` ${key}:
|
|
6203
|
+
${yaml_lines.join(`
|
|
6204
|
+
`)}`;
|
|
6205
|
+
raw = raw.trimEnd() + `
|
|
6206
|
+
` + block_yaml + `
|
|
6207
|
+
`;
|
|
6208
|
+
}
|
|
6209
|
+
}
|
|
6210
|
+
block.replace_raw(raw);
|
|
5814
6211
|
}
|
|
5815
6212
|
assetYaml = doc.serialize();
|
|
5816
6213
|
}
|
|
@@ -6083,7 +6480,8 @@ function addComponent(options) {
|
|
|
6083
6480
|
if (resolved.path?.endsWith(".dll") && resolved.class_name) {
|
|
6084
6481
|
scriptFileId = compute_dll_script_file_id(resolved.namespace ?? "", resolved.class_name);
|
|
6085
6482
|
}
|
|
6086
|
-
|
|
6483
|
+
const type_lookup_comp = project_path ? build_type_lookup(project_path) : undefined;
|
|
6484
|
+
componentYAML = createMonoBehaviourYAML(componentId, gameObjectId, resolved.guid, resolved.fields, version, scriptFileId, type_lookup_comp);
|
|
6087
6485
|
scriptGuid = resolved.guid;
|
|
6088
6486
|
scriptPath = resolved.path || undefined;
|
|
6089
6487
|
extractionError = resolved.extraction_error;
|
|
@@ -8150,11 +8548,15 @@ function applyManagedReference(doc, block, file_path, field_path, typeInfo, appe
|
|
|
8150
8548
|
const refEntry = ` - rid: ${nextRid}
|
|
8151
8549
|
type: {class: ${typeInfo.class_name}, ns: ${typeInfo.namespace}, asm: ${typeInfo.assembly}}
|
|
8152
8550
|
data: ${dataBlock}`;
|
|
8153
|
-
const
|
|
8551
|
+
const refIdsBlockPattern = /(\s*RefIds:\s*\n)/;
|
|
8552
|
+
const refIdsEmptyPattern = /(\s*RefIds:)[ \t]*\[\]/;
|
|
8154
8553
|
const referencesPattern = /(\s*references:\s*\n\s*version:\s*\d+\s*\n)/;
|
|
8155
|
-
if (
|
|
8156
|
-
raw = raw.replace(
|
|
8554
|
+
if (refIdsBlockPattern.test(raw)) {
|
|
8555
|
+
raw = raw.replace(refIdsBlockPattern, `$1${refEntry}
|
|
8157
8556
|
`);
|
|
8557
|
+
} else if (refIdsEmptyPattern.test(raw)) {
|
|
8558
|
+
raw = raw.replace(refIdsEmptyPattern, `$1
|
|
8559
|
+
${refEntry}`);
|
|
8158
8560
|
} else if (referencesPattern.test(raw)) {
|
|
8159
8561
|
raw = raw.replace(referencesPattern, `$1 RefIds:
|
|
8160
8562
|
${refEntry}
|
|
@@ -8167,8 +8569,23 @@ ${refEntry}
|
|
|
8167
8569
|
${refEntry}
|
|
8168
8570
|
`;
|
|
8169
8571
|
}
|
|
8170
|
-
|
|
8171
|
-
|
|
8572
|
+
const escaped_field = field_path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8573
|
+
if (append) {
|
|
8574
|
+
const fieldLineMatch = raw.match(new RegExp(`^([ \\t]*)${escaped_field}:`, "m"));
|
|
8575
|
+
const fieldIndent = fieldLineMatch ? fieldLineMatch[1] : " ";
|
|
8576
|
+
const ridEntry = `
|
|
8577
|
+
${fieldIndent} - rid: ${nextRid}`;
|
|
8578
|
+
const emptyArrayPattern = new RegExp(`(${escaped_field}:)[ \\t]*\\[\\]`, "m");
|
|
8579
|
+
if (emptyArrayPattern.test(raw)) {
|
|
8580
|
+
raw = raw.replace(emptyArrayPattern, `$1${ridEntry}`);
|
|
8581
|
+
} else {
|
|
8582
|
+
const lastRidPattern = new RegExp(`(^[ \\t]*${escaped_field}:[\\s\\S]*?- rid: \\d+)`, "m");
|
|
8583
|
+
if (lastRidPattern.test(raw)) {
|
|
8584
|
+
raw = raw.replace(lastRidPattern, `$1${ridEntry}`);
|
|
8585
|
+
}
|
|
8586
|
+
}
|
|
8587
|
+
} else {
|
|
8588
|
+
const fieldRidPattern = new RegExp(`(${escaped_field}:\\s*\\n\\s*rid:[ \\t]*)\\d+`, "m");
|
|
8172
8589
|
if (fieldRidPattern.test(raw)) {
|
|
8173
8590
|
raw = raw.replace(fieldRidPattern, `$1${nextRid}`);
|
|
8174
8591
|
}
|
|
@@ -9297,6 +9714,36 @@ function build_create_command() {
|
|
|
9297
9714
|
if (!result.success)
|
|
9298
9715
|
process.exitCode = 1;
|
|
9299
9716
|
});
|
|
9717
|
+
cmd.command("prefab-instance <scene_file> <prefab_path>").description("Instantiate a prefab into a scene file").option("-n, --name <name>", "Instance name (defaults to prefab filename)").option("-p, --parent <name|id>", "Parent GameObject name or Transform fileID").option("--position <x,y,z>", "Local position (default: 0,0,0)").option("-j, --json", "Output as JSON").action((scene_file, prefab_path_arg, options) => {
|
|
9718
|
+
let position;
|
|
9719
|
+
if (options.position) {
|
|
9720
|
+
const parts = options.position.split(",").map(Number);
|
|
9721
|
+
if (parts.length !== 3 || parts.some(isNaN)) {
|
|
9722
|
+
console.log(JSON.stringify({
|
|
9723
|
+
success: false,
|
|
9724
|
+
error: "--position must be three comma-separated numbers, e.g. 1,2,3"
|
|
9725
|
+
}, null, 2));
|
|
9726
|
+
process.exitCode = 1;
|
|
9727
|
+
return;
|
|
9728
|
+
}
|
|
9729
|
+
position = { x: parts[0], y: parts[1], z: parts[2] };
|
|
9730
|
+
}
|
|
9731
|
+
let parent;
|
|
9732
|
+
if (options.parent) {
|
|
9733
|
+
const asNumber = parseInt(options.parent, 10);
|
|
9734
|
+
parent = isNaN(asNumber) ? options.parent : asNumber;
|
|
9735
|
+
}
|
|
9736
|
+
const result = createPrefabInstance({
|
|
9737
|
+
scene_path: scene_file,
|
|
9738
|
+
prefab_path: prefab_path_arg,
|
|
9739
|
+
name: options.name,
|
|
9740
|
+
parent,
|
|
9741
|
+
position
|
|
9742
|
+
});
|
|
9743
|
+
console.log(JSON.stringify(result, null, 2));
|
|
9744
|
+
if (!result.success)
|
|
9745
|
+
process.exitCode = 1;
|
|
9746
|
+
});
|
|
9300
9747
|
cmd.command("scriptable-object <output_path> <script>").description("Create a new ScriptableObject .asset file").option("-p, --project <path>", "Unity project path (for script GUID lookup)").option("--set <json>", `Initial field values as JSON object (e.g. '{"damage": "10", "targetScope": "1"}')`).option("-j, --json", "Output as JSON").action((output_path, script, options) => {
|
|
9301
9748
|
let initial_values;
|
|
9302
9749
|
if (options.set) {
|