unityflow 0.9.0__tar.gz → 0.9.2__tar.gz
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.
- {unityflow-0.9.0/src/unityflow.egg-info → unityflow-0.9.2}/PKG-INFO +1 -1
- {unityflow-0.9.0 → unityflow-0.9.2}/pyproject.toml +1 -1
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/asset_resolver.py +93 -25
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/cli.py +87 -49
- {unityflow-0.9.0 → unityflow-0.9.2/src/unityflow.egg-info}/PKG-INFO +1 -1
- {unityflow-0.9.0 → unityflow-0.9.2}/LICENSE +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/README.md +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/setup.cfg +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/__init__.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animation/__init__.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animation/cli.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animation/models.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animation/mutate.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animation/parser.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animation/query.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animation/writer.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animator/__init__.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animator/cli.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animator/models.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animator/parser.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animator/query.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/animator/writer.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/asset_tracker.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/bridge/__init__.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/bridge/config.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/bridge/server.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/bridge/unity_client.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/builtin_schema.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/data/__init__.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/data/builtin_schemas.json +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/data/class_ids.json +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/dll_inspector.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/fast_parser.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/fbx_loader.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/formats.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/git_utils.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/hierarchy.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/merge.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/meta_generator.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/normalizer.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/parser.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/query.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/script_parser.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/semantic_diff.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/semantic_merge.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/sprite.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow/validator.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow.egg-info/SOURCES.txt +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow.egg-info/dependency_links.txt +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow.egg-info/entry_points.txt +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow.egg-info/requires.txt +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/src/unityflow.egg-info/top_level.txt +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_asset_resolver.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_asset_tracker.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_bridge.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_cli.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_dll_inspector.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_fbx_loader.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_formats.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_hierarchy.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_incremental.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_llm_helpers.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_merge.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_meta_generator.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_normalizer.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_parser.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_query.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_script_parser.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_semantic_diff.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_semantic_merge.py +0 -0
- {unityflow-0.9.0 → unityflow-0.9.2}/tests/test_validator.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "unityflow"
|
|
7
|
-
version = "0.9.
|
|
7
|
+
version = "0.9.2"
|
|
8
8
|
description = "Unity workflow automation - edit, diff, and merge prefabs, scenes, and assets without the Unity Editor"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -621,35 +621,28 @@ def resolve_internal_reference(
|
|
|
621
621
|
) -> dict[str, int]:
|
|
622
622
|
"""Resolve an internal # reference to a fileID dict.
|
|
623
623
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
hierarchy: Hierarchy instance built from the document
|
|
628
|
-
|
|
629
|
-
Returns:
|
|
630
|
-
Dict with fileID (e.g., {"fileID": 12345})
|
|
631
|
-
|
|
632
|
-
Raises:
|
|
633
|
-
ValueError: If the reference cannot be resolved
|
|
624
|
+
Resolution strategy:
|
|
625
|
+
1. Try the full path as a GameObject path
|
|
626
|
+
2. If not found, split last segment as component type on its parent
|
|
634
627
|
"""
|
|
635
|
-
|
|
628
|
+
raw_path = value[1:] if value.startswith("#") else value
|
|
636
629
|
|
|
637
|
-
target_node = hierarchy.find(
|
|
638
|
-
if target_node is None:
|
|
639
|
-
|
|
630
|
+
target_node = hierarchy.find(raw_path)
|
|
631
|
+
if target_node is not None:
|
|
632
|
+
return {"fileID": target_node.file_id}
|
|
640
633
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
634
|
+
parts = raw_path.rsplit("/", 1)
|
|
635
|
+
if len(parts) == 2:
|
|
636
|
+
parent_path, comp_name = parts
|
|
637
|
+
parent_node = hierarchy.find(parent_path)
|
|
638
|
+
if parent_node is not None:
|
|
639
|
+
for comp in parent_node.components:
|
|
640
|
+
name = comp.script_name or comp.class_name
|
|
641
|
+
if name == comp_name:
|
|
642
|
+
return {"fileID": comp.file_id}
|
|
643
|
+
raise ValueError(f"Component '{comp_name}' not found on '{parent_path}'")
|
|
651
644
|
|
|
652
|
-
|
|
645
|
+
raise ValueError(f"Internal reference not found: {raw_path}")
|
|
653
646
|
|
|
654
647
|
|
|
655
648
|
def resolve_value(
|
|
@@ -765,3 +758,78 @@ def get_asset_info(
|
|
|
765
758
|
pass
|
|
766
759
|
|
|
767
760
|
return info
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
def _is_reference_dict(value: Any) -> bool:
|
|
764
|
+
return isinstance(value, dict) and "fileID" in value
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
def _build_sprite_id_to_name(meta_path: Path) -> dict[int, str]:
|
|
768
|
+
from unityflow.sprite import parse_sprite_meta
|
|
769
|
+
|
|
770
|
+
info = parse_sprite_meta(meta_path)
|
|
771
|
+
if info is None or not info.is_multiple:
|
|
772
|
+
return {}
|
|
773
|
+
return {v: k for k, v in info.internal_id_table.items()}
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
def _humanize_single_reference(
|
|
777
|
+
ref: dict[str, Any],
|
|
778
|
+
guid_index: Any,
|
|
779
|
+
hierarchy: Any | None,
|
|
780
|
+
project_root: Path | None,
|
|
781
|
+
) -> Any:
|
|
782
|
+
file_id = ref.get("fileID", 0)
|
|
783
|
+
guid = ref.get("guid", "")
|
|
784
|
+
|
|
785
|
+
if file_id == 0 and not guid:
|
|
786
|
+
return ""
|
|
787
|
+
|
|
788
|
+
if guid:
|
|
789
|
+
asset_path = guid_index.get_path(guid) if guid_index else None
|
|
790
|
+
if asset_path is None:
|
|
791
|
+
return ref
|
|
792
|
+
|
|
793
|
+
suffix = asset_path.suffix.lower()
|
|
794
|
+
is_sprite_ext = suffix in (".png", ".jpg", ".jpeg", ".tga", ".psd", ".tiff", ".gif", ".bmp")
|
|
795
|
+
if is_sprite_ext and file_id != 21300000 and project_root:
|
|
796
|
+
meta_path = project_root / str(asset_path) / ".." / (asset_path.name + ".meta")
|
|
797
|
+
meta_path = (project_root / str(asset_path)).with_suffix(asset_path.suffix + ".meta")
|
|
798
|
+
id_to_name = _build_sprite_id_to_name(meta_path)
|
|
799
|
+
sprite_name = id_to_name.get(file_id)
|
|
800
|
+
if sprite_name:
|
|
801
|
+
return f"@{asset_path}:{sprite_name}"
|
|
802
|
+
|
|
803
|
+
return f"@{asset_path}"
|
|
804
|
+
|
|
805
|
+
if file_id and hierarchy:
|
|
806
|
+
ref_node = hierarchy._nodes_by_file_id.get(file_id)
|
|
807
|
+
if ref_node:
|
|
808
|
+
return f"#{ref_node.path}"
|
|
809
|
+
|
|
810
|
+
for n in hierarchy.iter_all():
|
|
811
|
+
for c in n.components:
|
|
812
|
+
if c.file_id == file_id:
|
|
813
|
+
return f"#{n.path}/{c.script_name or c.class_name}"
|
|
814
|
+
|
|
815
|
+
return ref
|
|
816
|
+
|
|
817
|
+
return ref
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
def humanize_references(
|
|
821
|
+
value: Any,
|
|
822
|
+
guid_index: Any,
|
|
823
|
+
hierarchy: Any | None = None,
|
|
824
|
+
project_root: Path | None = None,
|
|
825
|
+
) -> Any:
|
|
826
|
+
if _is_reference_dict(value):
|
|
827
|
+
return _humanize_single_reference(value, guid_index, hierarchy, project_root)
|
|
828
|
+
|
|
829
|
+
if isinstance(value, dict):
|
|
830
|
+
return {k: humanize_references(v, guid_index, hierarchy, project_root) for k, v in value.items()}
|
|
831
|
+
|
|
832
|
+
if isinstance(value, list):
|
|
833
|
+
return [humanize_references(item, guid_index, hierarchy, project_root) for item in value]
|
|
834
|
+
|
|
835
|
+
return value
|
|
@@ -986,6 +986,18 @@ def _build_disambiguation_message(
|
|
|
986
986
|
return "\n".join(error_lines)
|
|
987
987
|
|
|
988
988
|
|
|
989
|
+
def _resolve_script_name(guid_index, script_guid: str, script_file_id: int | None = None) -> str | None:
|
|
990
|
+
resolved = guid_index.resolve_name(script_guid)
|
|
991
|
+
if resolved:
|
|
992
|
+
path = guid_index.get_path(script_guid)
|
|
993
|
+
if path and path.suffix.lower() == ".dll" and script_file_id is not None:
|
|
994
|
+
dll_name = guid_index.resolve_dll_class_name(script_guid, script_file_id)
|
|
995
|
+
if dll_name:
|
|
996
|
+
return dll_name
|
|
997
|
+
return resolved
|
|
998
|
+
return None
|
|
999
|
+
|
|
1000
|
+
|
|
989
1001
|
def _resolve_component_path(
|
|
990
1002
|
doc: UnityYAMLDocument,
|
|
991
1003
|
path_spec: str,
|
|
@@ -1089,7 +1101,11 @@ def _resolve_component_path(
|
|
|
1089
1101
|
comp_content = comp.get_content()
|
|
1090
1102
|
if comp_content:
|
|
1091
1103
|
script_ref = comp_content.get("m_Script", {})
|
|
1092
|
-
|
|
1104
|
+
if isinstance(script_ref, dict):
|
|
1105
|
+
script_guid = script_ref.get("guid", "")
|
|
1106
|
+
script_fid = script_ref.get("fileID")
|
|
1107
|
+
else:
|
|
1108
|
+
script_guid, script_fid = "", None
|
|
1093
1109
|
if script_guid:
|
|
1094
1110
|
for key, guid in PACKAGE_COMPONENT_GUIDS.items():
|
|
1095
1111
|
if key.lower() == last_component_type_lower and script_guid.lower() == guid.lower():
|
|
@@ -1097,7 +1113,7 @@ def _resolve_component_path(
|
|
|
1097
1113
|
matched = True
|
|
1098
1114
|
break
|
|
1099
1115
|
if not matched and guid_index:
|
|
1100
|
-
resolved = guid_index
|
|
1116
|
+
resolved = _resolve_script_name(guid_index, script_guid, script_fid)
|
|
1101
1117
|
if resolved and resolved.lower() == last_component_type_lower:
|
|
1102
1118
|
matching_components.append(comp_id)
|
|
1103
1119
|
|
|
@@ -1178,7 +1194,11 @@ def _resolve_component_path(
|
|
|
1178
1194
|
comp_content = comp.get_content()
|
|
1179
1195
|
if comp_content:
|
|
1180
1196
|
script_ref = comp_content.get("m_Script", {})
|
|
1181
|
-
|
|
1197
|
+
if isinstance(script_ref, dict):
|
|
1198
|
+
script_guid = script_ref.get("guid", "")
|
|
1199
|
+
script_fid = script_ref.get("fileID")
|
|
1200
|
+
else:
|
|
1201
|
+
script_guid, script_fid = "", None
|
|
1182
1202
|
if script_guid:
|
|
1183
1203
|
for key, guid in PACKAGE_COMPONENT_GUIDS.items():
|
|
1184
1204
|
if key.lower() == component_type_lower and script_guid.lower() == guid.lower():
|
|
@@ -1186,7 +1206,7 @@ def _resolve_component_path(
|
|
|
1186
1206
|
matched = True
|
|
1187
1207
|
break
|
|
1188
1208
|
if not matched and guid_index:
|
|
1189
|
-
resolved = guid_index
|
|
1209
|
+
resolved = _resolve_script_name(guid_index, script_guid, script_fid)
|
|
1190
1210
|
if resolved and resolved.lower() == component_type_lower:
|
|
1191
1211
|
matching_components.append(comp_id)
|
|
1192
1212
|
|
|
@@ -1245,6 +1265,7 @@ def _handle_add_component(
|
|
|
1245
1265
|
output: Path | None,
|
|
1246
1266
|
project_root: Path | None,
|
|
1247
1267
|
explicit_script_guid: str | None = None,
|
|
1268
|
+
before: str | None = None,
|
|
1248
1269
|
) -> None:
|
|
1249
1270
|
from unityflow.asset_tracker import get_cached_guid_index
|
|
1250
1271
|
from unityflow.formats import CLASS_NAME_TO_ID
|
|
@@ -1441,7 +1462,30 @@ def _handle_add_component(
|
|
|
1441
1462
|
go_content = go_obj.get_content()
|
|
1442
1463
|
if go_content:
|
|
1443
1464
|
components = go_content.get("m_Component", [])
|
|
1444
|
-
|
|
1465
|
+
new_entry = {"component": {"fileID": new_file_id}}
|
|
1466
|
+
insert_idx = len(components)
|
|
1467
|
+
if before is not None:
|
|
1468
|
+
before_lower = before.lower()
|
|
1469
|
+
for idx, comp_ref in enumerate(components):
|
|
1470
|
+
cid = comp_ref.get("component", {}).get("fileID", 0)
|
|
1471
|
+
comp_obj = doc.get_by_file_id(cid)
|
|
1472
|
+
if comp_obj:
|
|
1473
|
+
comp_name = comp_obj.class_name.lower()
|
|
1474
|
+
if comp_name == before_lower:
|
|
1475
|
+
insert_idx = idx
|
|
1476
|
+
break
|
|
1477
|
+
if comp_obj.class_id == 114 and guid_index:
|
|
1478
|
+
comp_content = comp_obj.get_content()
|
|
1479
|
+
if comp_content:
|
|
1480
|
+
sr = comp_content.get("m_Script", {})
|
|
1481
|
+
if isinstance(sr, dict):
|
|
1482
|
+
sg = sr.get("guid", "")
|
|
1483
|
+
sf = sr.get("fileID")
|
|
1484
|
+
resolved = _resolve_script_name(guid_index, sg, sf) if sg else None
|
|
1485
|
+
if resolved and resolved.lower() == before_lower:
|
|
1486
|
+
insert_idx = idx
|
|
1487
|
+
break
|
|
1488
|
+
components.insert(insert_idx, new_entry)
|
|
1445
1489
|
go_content["m_Component"] = components
|
|
1446
1490
|
|
|
1447
1491
|
_normalize_and_save(doc, output_path, project_root)
|
|
@@ -1850,6 +1894,12 @@ def get_value_cmd(
|
|
|
1850
1894
|
default=None,
|
|
1851
1895
|
help="Script GUID for --add-component (for DLL-based scripts not discoverable by filename)",
|
|
1852
1896
|
)
|
|
1897
|
+
@click.option(
|
|
1898
|
+
"--before",
|
|
1899
|
+
"before_component",
|
|
1900
|
+
default=None,
|
|
1901
|
+
help="Insert component before this component type (for --add-component ordering)",
|
|
1902
|
+
)
|
|
1853
1903
|
def set_value_cmd(
|
|
1854
1904
|
file: Path,
|
|
1855
1905
|
set_path: str,
|
|
@@ -1864,6 +1914,7 @@ def set_value_cmd(
|
|
|
1864
1914
|
remove_object: str | None,
|
|
1865
1915
|
object_type: str,
|
|
1866
1916
|
script_guid: str | None,
|
|
1917
|
+
before_component: str | None,
|
|
1867
1918
|
) -> None:
|
|
1868
1919
|
"""Set a value at a specific path in a Unity YAML file.
|
|
1869
1920
|
|
|
@@ -1991,7 +2042,9 @@ def set_value_cmd(
|
|
|
1991
2042
|
|
|
1992
2043
|
# Handle --add-component
|
|
1993
2044
|
if add_component is not None:
|
|
1994
|
-
_handle_add_component(
|
|
2045
|
+
_handle_add_component(
|
|
2046
|
+
doc, set_path, add_component, output_path, output, project_root, script_guid, before_component
|
|
2047
|
+
)
|
|
1995
2048
|
return
|
|
1996
2049
|
|
|
1997
2050
|
# Handle --remove-component
|
|
@@ -2787,6 +2840,7 @@ def inspect_cmd(
|
|
|
2787
2840
|
import json as json_module
|
|
2788
2841
|
|
|
2789
2842
|
from unityflow import UnityYAMLDocument, build_hierarchy
|
|
2843
|
+
from unityflow.asset_resolver import humanize_references
|
|
2790
2844
|
from unityflow.asset_tracker import find_unity_project_root, get_lazy_guid_index
|
|
2791
2845
|
|
|
2792
2846
|
# Load document
|
|
@@ -2881,38 +2935,36 @@ def inspect_cmd(
|
|
|
2881
2935
|
script_path = guid_index.resolve_path(comp.script_guid)
|
|
2882
2936
|
if script_path:
|
|
2883
2937
|
comp_data["script_path"] = str(script_path)
|
|
2884
|
-
|
|
2938
|
+
filtered = {
|
|
2939
|
+
k: v
|
|
2940
|
+
for k, v in comp.data.items()
|
|
2941
|
+
if k
|
|
2942
|
+
not in {
|
|
2943
|
+
"m_ObjectHideFlags",
|
|
2944
|
+
"m_CorrespondingSourceObject",
|
|
2945
|
+
"m_PrefabInstance",
|
|
2946
|
+
"m_PrefabAsset",
|
|
2947
|
+
"m_GameObject",
|
|
2948
|
+
"m_Script",
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
comp_data["properties"] = humanize_references(filtered, guid_index, hier, resolved_project_root)
|
|
2885
2952
|
result["components"].append(comp_data)
|
|
2886
2953
|
|
|
2887
2954
|
click.echo(json_module.dumps(result, indent=2, default=str))
|
|
2888
2955
|
else:
|
|
2889
|
-
|
|
2890
|
-
def
|
|
2891
|
-
|
|
2892
|
-
if
|
|
2893
|
-
return "None"
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
# Try to find component by file_id
|
|
2902
|
-
for n in hier.iter_all():
|
|
2903
|
-
for c in n.components:
|
|
2904
|
-
if c.file_id == file_id:
|
|
2905
|
-
return f"{n.path}/{c.script_name or c.class_name}"
|
|
2906
|
-
|
|
2907
|
-
return f"(internal ref #{file_id})"
|
|
2908
|
-
|
|
2909
|
-
# External reference (different asset)
|
|
2910
|
-
if guid and guid_index:
|
|
2911
|
-
asset_path = guid_index.get_path(guid)
|
|
2912
|
-
if asset_path:
|
|
2913
|
-
return f"@{asset_path}"
|
|
2914
|
-
|
|
2915
|
-
return "(external ref)"
|
|
2956
|
+
|
|
2957
|
+
def format_value(value):
|
|
2958
|
+
resolved = humanize_references(value, guid_index, hier, resolved_project_root)
|
|
2959
|
+
if isinstance(resolved, str):
|
|
2960
|
+
return resolved if resolved else "None"
|
|
2961
|
+
if isinstance(resolved, dict):
|
|
2962
|
+
if "fileID" in resolved:
|
|
2963
|
+
return f"(unresolved ref fileID={resolved['fileID']})"
|
|
2964
|
+
return "{...}"
|
|
2965
|
+
if isinstance(resolved, list):
|
|
2966
|
+
return f"[{len(resolved)} items]"
|
|
2967
|
+
return str(resolved)
|
|
2916
2968
|
|
|
2917
2969
|
# Text output - Inspector-like format
|
|
2918
2970
|
click.echo(f"GameObject: {node.name}")
|
|
@@ -3009,21 +3061,7 @@ def inspect_cmd(
|
|
|
3009
3061
|
}
|
|
3010
3062
|
for key, value in comp.data.items():
|
|
3011
3063
|
if key not in skip_keys:
|
|
3012
|
-
|
|
3013
|
-
if isinstance(value, dict) and "fileID" in value:
|
|
3014
|
-
# Reference field - resolve to path
|
|
3015
|
-
file_id = value.get("fileID", 0)
|
|
3016
|
-
guid = value.get("guid", "")
|
|
3017
|
-
resolved = resolve_reference(file_id, guid)
|
|
3018
|
-
click.echo(f" {key}: {resolved}")
|
|
3019
|
-
elif isinstance(value, dict | list):
|
|
3020
|
-
# Complex value - show abbreviated
|
|
3021
|
-
if isinstance(value, list):
|
|
3022
|
-
click.echo(f" {key}: [{len(value)} items]")
|
|
3023
|
-
else:
|
|
3024
|
-
click.echo(f" {key}: {{...}}")
|
|
3025
|
-
else:
|
|
3026
|
-
click.echo(f" {key}: {value}")
|
|
3064
|
+
click.echo(f" {key}: {format_value(value)}")
|
|
3027
3065
|
|
|
3028
3066
|
click.echo()
|
|
3029
3067
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|