diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 393fe40..aa40627 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -12,7 +12,9 @@ "Bash(ls:*)", "Bash(find:*)", "Bash(grep:*)", - "Bash(wc:*)" + "Bash(wc:*)", + "Bash(pgrep:*)", + "Bash(cargo doc:*)" ], "additionalDirectories": [ "/home/connor/repos/CBAssets/" diff --git a/README.md b/README.md index eef7d4e..1d9a735 100644 --- a/README.md +++ b/README.md @@ -253,78 +253,6 @@ Raw YAML Documents - New: O(1) integer comparison - **Significant speedup** for HashMap lookups -## Project Structure - -``` -cursebreaker-parser-rust/ -├── unity-parser/ # Main library crate -│ ├── src/ -│ │ ├── ecs/ # ECS world building -│ │ │ └── builder.rs -│ │ ├── model/ # UnityFile, Scene, Prefab, Asset -│ │ │ └── mod.rs -│ │ ├── parser/ # YAML parsing & GUID resolution -│ │ │ ├── guid_resolver.rs # Script GUID → Class Name -│ │ │ ├── prefab_guid_resolver.rs # Prefab GUID → Path -│ │ │ ├── meta.rs # .meta file parsing -│ │ │ ├── yaml.rs # YAML document splitting -│ │ │ └── mod.rs -│ │ ├── project/ # ⚠️ OUTDATED - needs refactoring -│ │ │ └── mod.rs -│ │ ├── types/ # Unity types & components -│ │ │ ├── unity_types/ -│ │ │ │ ├── game_object.rs -│ │ │ │ ├── transform.rs -│ │ │ │ ├── prefab_instance.rs -│ │ │ │ └── mod.rs -│ │ │ ├── component.rs # UnityComponent trait & helpers -│ │ │ ├── guid.rs # 128-bit GUID type -│ │ │ ├── ids.rs # FileID, LocalID -│ │ │ ├── reference.rs # UnityReference enum -│ │ │ ├── type_filter.rs # TypeFilter for selective parsing -│ │ │ ├── values.rs # Vector3, Quaternion, Color, etc. -│ │ │ └── mod.rs -│ │ ├── error.rs # Error types -│ │ ├── macros.rs -│ │ ├── property/ -│ │ └── lib.rs -│ ├── examples/ -│ │ ├── basic_parsing.rs -│ │ ├── custom_component.rs -│ │ ├── ecs_integration.rs -│ │ ├── find_playsfx.rs -│ │ ├── parse_resources.rs -│ │ └── parse_resource_prefabs.rs -│ ├── tests/ -│ └── Cargo.toml -├── unity-parser-macros/ # Proc macro crate (⚠️ has bugs) -│ ├── src/ -│ │ └── lib.rs -│ └── Cargo.toml -├── Cargo.toml # Workspace config -└── README.md -``` - -## Known Issues - -### Critical Issues -1. **`unity-parser/src/project/mod.rs` is OUTDATED** - - Built for old architecture before `UnityFile` enum refactor - - References non-existent `UnityDocument` type (should be `RawDocument`) - - Module is disabled in lib.rs until refactored - -2. **Derive macro namespace mismatch** - - `unity-parser-macros` uses `unity_parser` namespace - - Actual crate name is `unity_parser::` (underscore, not hyphen) - - Manual `UnityComponent` implementation recommended - -3. **Placeholder values in Cargo.toml** - - Author and repository fields need updating - -### Minor Issues -1. Disabled example/test files may reference outdated APIs -2. Some examples may have incorrect YAML access patterns - ## Running Examples ```bash @@ -386,15 +314,6 @@ Contributions welcome! Areas needing help: - **Testing**: Integration tests with real Unity projects - **Performance**: Optimize YAML parsing, parallel processing -## License - -Licensed under either of: - -- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) -- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) - -at your option. - ## Acknowledgments - **Unity Technologies**: For the YAML-based file format diff --git a/cursebreaker-parser/src/main.rs b/cursebreaker-parser/src/main.rs index 6afc4b8..9207648 100644 --- a/cursebreaker-parser/src/main.rs +++ b/cursebreaker-parser/src/main.rs @@ -14,7 +14,7 @@ use std::fs::File; use std::io::Write; use std::path::Path; use unity_parser::log::DedupLogger; -use log::{info, warn, error, LevelFilter}; +use log::{info, error, LevelFilter}; fn main() -> Result<(), Box> { @@ -36,6 +36,8 @@ fn main() -> Result<(), Box> { let scene_path = "_GameAssets/Scenes/Tiles/10_3.unity"; info!("📁 Parsing scene: {}", scene_path); + log::logger().flush(); + // Parse the scene using the project match project.parse_scene(scene_path) { Ok(scene) => { @@ -47,6 +49,23 @@ fn main() -> Result<(), Box> { let transform_view = scene.world.borrow::(); let gameobject_view = scene.world.borrow::(); + info!("DEBUG: entity_map size: {}", scene.entity_map.len()); + info!("DEBUG: Checking world for InteractableResource components..."); + + // Check how many entities in entity_map have the component + let mut entities_in_map_with_resource = 0; + for entity in scene.entity_map.values() { + if resource_view.contains(*entity) { + entities_in_map_with_resource += 1; + if entities_in_map_with_resource <= 5 { // Only log first 5 + if let Some(resource) = resource_view.get(*entity) { + info!("DEBUG: Entity {:?} in entity_map has InteractableResource, typeId: {}", entity, resource.type_id); + } + } + } + } + info!("DEBUG: Entities in entity_map with InteractableResource: {}", entities_in_map_with_resource); + // Find all entities that have Interactable_Resource let mut found_resources = Vec::new(); @@ -68,6 +87,7 @@ fn main() -> Result<(), Box> { } info!("🔍 Found {} Interactable_Resource component(s)", found_resources.len()); + log::logger().flush(); if !found_resources.is_empty() { // Display resources in console diff --git a/resource_prefabs_output.txt b/resource_prefabs_output.txt deleted file mode 100644 index 4e809b1..0000000 --- a/resource_prefabs_output.txt +++ /dev/null @@ -1,693 +0,0 @@ -Cursebreaker Resource Prefabs -====================================================================== - -Total resources found: 171 - ----------------------------------------------------------------------- - -Prefab: HarvestableSpawner_73Medicinal Herbs - TypeID: 73 - MaxHealth: 0 - -Prefab: HarvestableSpawner_65Radishes - TypeID: 65 - MaxHealth: 0 - -Prefab: HarvestableSpawner_22Sandstone Grouper - TypeID: 22 - MaxHealth: 0 - -Prefab: HarvestableSpawner_14Mageflower - TypeID: 14 - MaxHealth: 0 - -Prefab: HarvestableSpawner_108mountain Ore3 - TypeID: 108 - MaxHealth: 0 - -Prefab: HarvestableSpawner_120Swamp Brambles - TypeID: 120 - MaxHealth: 0 - -Prefab: HarvestableSpawner_20Caveshroom - TypeID: 20 - MaxHealth: 0 - -Prefab: Prefab_Resource_30HeartbellVine - TypeID: 30 - MaxHealth: 5 - -Prefab: HarvestableSpawner_76Speed herb - TypeID: 76 - MaxHealth: 0 - -Prefab: Prefab_Resource_22SandstoneGrouper - TypeID: 22 - MaxHealth: 5 - -Prefab: Prefab_Resource_64Carrot_Field - TypeID: 64 - MaxHealth: 5 - -Prefab: HarvestableSpawner_26Betta Iotachi - TypeID: 26 - MaxHealth: 0 - -Prefab: HarvestableSpawner_85Magic res ampoule crafting mat - TypeID: 85 - MaxHealth: 0 - -Prefab: Prefab_Resource_15Blueberries - TypeID: 15 - MaxHealth: 5 - -Prefab: HarvestableSpawner_58Radiant Sunflower - TypeID: 58 - MaxHealth: 0 - -Prefab: HarvestableSpawner_76Waspheart Iris - TypeID: 76 - MaxHealth: 0 - -Prefab: HarvestableSpawner_30Heartbell Vine - TypeID: 30 - MaxHealth: 0 - -Prefab: HarvestableSpawner_61Eggplants - TypeID: 61 - MaxHealth: 0 - -Prefab: Prefab_Resource_8Deadwood - TypeID: 0 - MaxHealth: 5 - -Prefab: HarvestableSpawner_70Cabbage - TypeID: 70 - MaxHealth: 0 - -Prefab: Prefab_Resource_19Coal - TypeID: 19 - MaxHealth: 20 - -Prefab: Prefab_Resource_12PebbleSturgeon - TypeID: 12 - MaxHealth: 5 - -Prefab: Prefab_Resource_6Oak - TypeID: 6 - MaxHealth: 5 - -Prefab: HarvestableSpawner_2Copper Ore - TypeID: 2 - MaxHealth: 0 - -Prefab: HarvestableSpawner_111Deep Earth Moss - TypeID: 111 - MaxHealth: 0 - -Prefab: HarvestableSpawner_49Dreamylion - TypeID: 49 - MaxHealth: 0 - -Prefab: HarvestableSpawner_71Nest - TypeID: 71 - MaxHealth: 0 - -Prefab: HarvestableSpawner_19Coal - TypeID: 19 - MaxHealth: 0 - -Prefab: Prefab_Resource_21CharcoalSnapper - TypeID: 21 - MaxHealth: 5 - -Prefab: HarvestableSpawner_12Pebble Sturgeon - TypeID: 12 - MaxHealth: 0 - -Prefab: Prefab_Resource_25ObsidianWalleye - TypeID: 25 - MaxHealth: 5 - -Prefab: Prefab_Resource_65Radish_Field - TypeID: 65 - MaxHealth: 5 - -Prefab: HarvestableSpawner_83Phys res ampoule crafting mat - TypeID: 83 - MaxHealth: 0 - -Prefab: HarvestableSpawner_78Firestick flower - TypeID: 78 - MaxHealth: 0 - -Prefab: Prefab_Resource_13ArcaneSeedTree - TypeID: 13 - MaxHealth: 5 - -Prefab: HarvestableSpawner_116Tree - TypeID: 116 - MaxHealth: 0 - -Prefab: HarvestableSpawner_6Oak - TypeID: 6 - MaxHealth: 0 - -Prefab: HarvestableSpawner_37Ancients' Tears - TypeID: 37 - MaxHealth: 0 - -Prefab: HarvestableSpawner_63Corn - TypeID: 63 - MaxHealth: 0 - -Prefab: HarvestableSpawner_44Voidlight Tendril - TypeID: 44 - MaxHealth: 0 - -Prefab: Prefab_Resource_5TitaniumOre - TypeID: 5 - MaxHealth: 20 - -Prefab: HarvestableSpawner_55Poppy of the Fallen - TypeID: 55 - MaxHealth: 0 - -Prefab: HarvestableSpawner_102mountain fish3 - TypeID: 102 - MaxHealth: 0 - -Prefab: HarvestableSpawner_15Blueberries - TypeID: 15 - MaxHealth: 0 - -Prefab: HarvestableSpawner_41Falls Hydrangea - TypeID: 41 - MaxHealth: 0 - -Prefab: Prefab_Resource_26BettaIotachi - TypeID: 26 - MaxHealth: 5 - -Prefab: Prefab_Resource_36Noblerose - TypeID: 36 - MaxHealth: 5 - -Prefab: Prefab_Resource_58Sunflower - TypeID: 58 - MaxHealth: 5 - -Prefab: HarvestableSpawner_45Autumnleaf Lily - TypeID: 45 - MaxHealth: 0 - -Prefab: Prefab_Resource_32Lakesberry - TypeID: 32 - MaxHealth: 5 - -Prefab: HarvestableSpawner_106Imberite Ore - TypeID: 106 - MaxHealth: 0 - -Prefab: HarvestableSpawner_100mountain fish1 - TypeID: 100 - MaxHealth: 0 - -Prefab: HarvestableSpawner_27Rock Lobster - TypeID: 27 - MaxHealth: 0 - -Prefab: HarvestableSpawner_9Wild Goopy - TypeID: 9 - MaxHealth: 0 - -Prefab: HarvestableSpawner_68Epic ore - TypeID: 68 - MaxHealth: 0 - -Prefab: HarvestableSpawner_113Soulgrowth Mushrooms - TypeID: 113 - MaxHealth: 0 - -Prefab: HarvestableSpawner_28Horsetail Reed Bass - TypeID: 28 - MaxHealth: 0 - -Prefab: HarvestableSpawner_8Deadwood tree - TypeID: 8 - MaxHealth: 0 - -Prefab: HarvestableSpawner_77Glowing Willow - TypeID: 77 - MaxHealth: 0 - -Prefab: Prefab_Resource_33Silvermirror - TypeID: 33 - MaxHealth: 5 - -Prefab: HarvestableSpawner_42Wight's Pearls - TypeID: 42 - MaxHealth: 0 - -Prefab: HarvestableSpawner_16Spellbound Oak - TypeID: 16 - MaxHealth: 0 - -Prefab: HarvestableSpawner_25Obsidian Walleye - TypeID: 25 - MaxHealth: 0 - -Prefab: Prefab_Resource_50Haniflower - TypeID: 50 - MaxHealth: 5 - -Prefab: Prefab_Resource_2CopperOre - TypeID: 2 - MaxHealth: 20 - -Prefab: HarvestableSpawner_64Carrots - TypeID: 64 - MaxHealth: 0 - -Prefab: HarvestableSpawner_32Lakesberry - TypeID: 32 - MaxHealth: 0 - -Prefab: HarvestableSpawner_115Malicious Sporecap - TypeID: 115 - MaxHealth: 0 - -Prefab: HarvestableSpawner_88Saltpeter Mine - TypeID: 88 - MaxHealth: 0 - -Prefab: Prefab_Resource_23FuchsiaPerch - TypeID: 23 - MaxHealth: 5 - -Prefab: Prefab_Resource_54GoldenSunflower - TypeID: 54 - MaxHealth: 5 - -Prefab: HarvestableSpawner_58Sunflower - TypeID: 58 - MaxHealth: 0 - -Prefab: HarvestableSpawner_117Ore - TypeID: 117 - MaxHealth: 0 - -Prefab: HarvestableSpawner_1Spruce - TypeID: 1 - MaxHealth: 0 - -Prefab: HarvestableSpawner_79Minigame tree - TypeID: 79 - MaxHealth: 0 - -Prefab: HarvestableSpawner_7Evark tree - TypeID: 7 - MaxHealth: 0 - -Prefab: HarvestableSpawner_81Puppet Flower - TypeID: 81 - MaxHealth: 0 - -Prefab: HarvestableSpawner_6Oak tree - TypeID: 6 - MaxHealth: 0 - -Prefab: Prefab_Resource_14Mageflower - TypeID: 14 - MaxHealth: 5 - -Prefab: Prefab_Resource_7Evark - TypeID: 0 - MaxHealth: 5 - -Prefab: HarvestableSpawner_86Generic mining - TypeID: 86 - MaxHealth: 0 - -Prefab: HarvestableSpawner_85Darkmire Damp Root - TypeID: 85 - MaxHealth: 0 - -Prefab: HarvestableSpawner_110Crystalvein Rose - TypeID: 110 - MaxHealth: 0 - -Prefab: HarvestableSpawner_4Imberite ore - TypeID: 4 - MaxHealth: 0 - -Prefab: Prefab_Resource_16SpellboundOak - TypeID: 16 - MaxHealth: 5 - -Prefab: HarvestableSpawner_59Evening's Cup - TypeID: 59 - MaxHealth: 0 - -Prefab: Prefab_Resource_38Dandelions - TypeID: 38 - MaxHealth: 5 - -Prefab: HarvestableSpawner_101mountain fish2 - TypeID: 101 - MaxHealth: 0 - -Prefab: HarvestableSpawner_115MaliciousSporecap - TypeID: 115 - MaxHealth: 0 - -Prefab: HarvestableSpawner_43Skyfold Flower - TypeID: 43 - MaxHealth: 0 - -Prefab: HarvestableSpawner_67Cotton - TypeID: 67 - MaxHealth: 0 - -Prefab: HarvestableSpawner_84Ranged res ampoule crafting mat - TypeID: 84 - MaxHealth: 0 - -Prefab: HarvestableSpawner_23Fuchsia Perch - TypeID: 23 - MaxHealth: 0 - -Prefab: HarvestableSpawner_84Marshland Feather Reed - TypeID: 84 - MaxHealth: 0 - -Prefab: Prefab_Resource_24GoblinShad - TypeID: 24 - MaxHealth: 5 - -Prefab: HarvestableSpawner_109mountain herb1 - TypeID: 109 - MaxHealth: 0 - -Prefab: HarvestableSpawner_35Red Nymph - TypeID: 35 - MaxHealth: 0 - -Prefab: HarvestableSpawner_80Sunburst Marlin - TypeID: 80 - MaxHealth: 0 - -Prefab: HarvestableSpawner_74Soothing Mallow - TypeID: 74 - MaxHealth: 0 - -Prefab: HarvestableSpawner_60Golden Tulip - TypeID: 60 - MaxHealth: 0 - -Prefab: HarvestableSpawner_114ColdwaterLily - TypeID: 114 - MaxHealth: 0 - -Prefab: HarvestableSpawner_24Goblin Shad - TypeID: 24 - MaxHealth: 0 - -Prefab: HarvestableSpawner_46Cloud Yarrow - TypeID: 46 - MaxHealth: 0 - -Prefab: HarvestableSpawner_113SoulgrowthMushroom - TypeID: 113 - MaxHealth: 0 - -Prefab: HarvestableSpawner_104mountain tree2 - TypeID: 104 - MaxHealth: 0 - -Prefab: Prefab_Resource_62Chili_Pepper_Field - TypeID: 62 - MaxHealth: 5 - -Prefab: Prefab_Resource_67Cotton - TypeID: 67 - MaxHealth: 5 - -Prefab: HarvestableSpawner_111mountain herb3 - TypeID: 111 - MaxHealth: 0 - -Prefab: Prefab_Resource_18Dust - TypeID: 18 - MaxHealth: 5 - -Prefab: HarvestableSpawner_18Dust - TypeID: 18 - MaxHealth: 0 - -Prefab: Prefab_Resource_1Spruce - TypeID: 1 - MaxHealth: 5 - -Prefab: HarvestableSpawner_73Sweetgrass - TypeID: 73 - MaxHealth: 0 - -Prefab: Prefab_Resource_35RedNymph - TypeID: 35 - MaxHealth: 5 - -Prefab: HarvestableSpawner_72MinigameOre - TypeID: 72 - MaxHealth: 0 - -Prefab: HarvestableSpawner_67Northwind Cotton - TypeID: 67 - MaxHealth: 0 - -Prefab: HarvestableSpawner_57Queen's Lily - TypeID: 57 - MaxHealth: 0 - -Prefab: HarvestableSpawner_103mountain tree1 - TypeID: 103 - MaxHealth: 0 - -Prefab: Prefab_Resource_3IronOre - TypeID: 3 - MaxHealth: 20 - -Prefab: HarvestableSpawner_87Generic alchemy - TypeID: 87 - MaxHealth: 0 - -Prefab: Prefab_Resource_31Bloodpetal - TypeID: 31 - MaxHealth: 5 - -Prefab: HarvestableSpawner_1Spruce tree - TypeID: 1 - MaxHealth: 0 - -Prefab: HarvestableSpawner_40Night's Bloom - TypeID: 40 - MaxHealth: 0 - -Prefab: Prefab_Resource_28HorsetailReedBass - TypeID: 28 - MaxHealth: 5 - -Prefab: HarvestableSpawner_11Redberries - TypeID: 11 - MaxHealth: 0 - -Prefab: HarvestableSpawner_20Cavern Puffball - TypeID: 20 - MaxHealth: 0 - -Prefab: HarvestableSpawner_37Ancient's Tears - TypeID: 37 - MaxHealth: 0 - -Prefab: HarvestableSpawner_107mountain Ore2 - TypeID: 107 - MaxHealth: 0 - -Prefab: Prefab_Resource_27RockLobster - TypeID: 27 - MaxHealth: 5 - -Prefab: Prefab_Resource_11RedberryBush - TypeID: 11 - MaxHealth: 5 - -Prefab: HarvestableSpawner_62Chili Peppers - TypeID: 62 - MaxHealth: 0 - -Prefab: HarvestableSpawner_106mountain Ore1 - TypeID: 106 - MaxHealth: 0 - -Prefab: HarvestableSpawner_56Deepforest Daisy - TypeID: 56 - MaxHealth: 0 - -Prefab: HarvestableSpawner_105mountain tree3 - TypeID: 105 - MaxHealth: 0 - -Prefab: HarvestableSpawner_53Drakefire Root - TypeID: 53 - MaxHealth: 0 - -Prefab: HarvestableSpawner_66Pumpkins - TypeID: 66 - MaxHealth: 0 - -Prefab: Prefab_Resource_34SorcerersWeed - TypeID: 34 - MaxHealth: 5 - -Prefab: HarvestableSpawner_112Rye - TypeID: 112 - MaxHealth: 0 - -Prefab: HarvestableSpawner_3Iron ore - TypeID: 3 - MaxHealth: 0 - -Prefab: Prefab_Resource_66Pumpkin_Patch - TypeID: 66 - MaxHealth: 5 - -Prefab: HarvestableSpawner_73MedicinalHerbs - TypeID: 73 - MaxHealth: 0 - -Prefab: HarvestableSpawner_33Silvermirror Iris - TypeID: 33 - MaxHealth: 0 - -Prefab: HarvestableSpawner_69Cabbage - TypeID: 69 - MaxHealth: 0 - -Prefab: HarvestableSpawner_13Arcane Everbloom - TypeID: 13 - MaxHealth: 0 - -Prefab: Prefab_Resource_61Eggplant_Field - TypeID: 61 - MaxHealth: 5 - -Prefab: HarvestableSpawner_48Sorrowleaf - TypeID: 48 - MaxHealth: 0 - -Prefab: Prefab_Resource_63Corn_Field - TypeID: 63 - MaxHealth: 5 - -Prefab: HarvestableSpawner_39Dawnflame Ivy - TypeID: 39 - MaxHealth: 0 - -Prefab: HarvestableSpawner_54Golden Sunflower - TypeID: 54 - MaxHealth: 0 - -Prefab: Prefab_Resource_37AncientsTears - TypeID: 37 - MaxHealth: 5 - -Prefab: HarvestableSpawner_21Charcoal Snapper - TypeID: 21 - MaxHealth: 0 - -Prefab: HarvestableSpawner_82Spider Egg - TypeID: 82 - MaxHealth: 0 - -Prefab: HarvestableSpawner_34Sorcerer's Weed - TypeID: 34 - MaxHealth: 0 - -Prefab: HarvestableSpawner_75Aurora Trout - TypeID: 75 - MaxHealth: 0 - -Prefab: HarvestableSpawner_47Spellspore Cap - TypeID: 47 - MaxHealth: 0 - -Prefab: HarvestableSpawner_109Skyfall Orchid - TypeID: 109 - MaxHealth: 0 - -Prefab: HarvestableSpawner_52Shyflower Orchid - TypeID: 52 - MaxHealth: 0 - -Prefab: HarvestableSpawner_110mountain herb2 - TypeID: 110 - MaxHealth: 0 - -Prefab: HarvestableSpawner_38Dandelions - TypeID: 38 - MaxHealth: 0 - -Prefab: HarvestableSpawner_10Barley - TypeID: 10 - MaxHealth: 0 - -Prefab: HarvestableSpawner_51Royal Daisy - TypeID: 51 - MaxHealth: 0 - -Prefab: Prefab_Resource_20CaveShroom - TypeID: 20 - MaxHealth: 20 - -Prefab: HarvestableSpawner_74Sven Herb 2 - TypeID: 74 - MaxHealth: 0 - -Prefab: HarvestableSpawner_69Potatoes - TypeID: 69 - MaxHealth: 0 - -Prefab: HarvestableSpawner_114Coldwater Lily - TypeID: 114 - MaxHealth: 0 - -Prefab: HarvestableSpawner_36Noblerose - TypeID: 36 - MaxHealth: 0 - -Prefab: Prefab_Resource_10Barley_Field - TypeID: 10 - MaxHealth: 5 - -Prefab: HarvestableSpawner_31Bloodpetal Rose - TypeID: 31 - MaxHealth: 0 - -Prefab: Prefab_Resource_9WildGoopy - TypeID: 9 - MaxHealth: 5 - -Prefab: HarvestableSpawner_83Gravelstem Whiteflower - TypeID: 83 - MaxHealth: 0 - -Prefab: Prefab_Resource_41FallsHydrangea - TypeID: 41 - MaxHealth: 5 - -Prefab: HarvestableSpawner_50Haniflower - TypeID: 50 - MaxHealth: 0 - -====================================================================== -End of resource data diff --git a/resources_output.txt b/resources_output.txt deleted file mode 100644 index 0471527..0000000 --- a/resources_output.txt +++ /dev/null @@ -1,14 +0,0 @@ -Cursebreaker Resources - 10_3.unity Scene -====================================================================== - -Total resources found: 1 - ----------------------------------------------------------------------- - -Resource: HarvestableSpawner_38Dandelions - TypeID: 38 - MaxHealth: 0 - Position: (1746.709717, 44.599632, 299.696503) - -====================================================================== -End of resource data diff --git a/unity-parser/resources_output.txt b/unity-parser/resources_output.txt deleted file mode 100644 index 0ef37e4..0000000 --- a/unity-parser/resources_output.txt +++ /dev/null @@ -1,19 +0,0 @@ -Cursebreaker Resources - 10_3.unity Scene -====================================================================== - -Total resources found: 2 - ----------------------------------------------------------------------- - -Resource: HarvestableSpawner_11Redberries - TypeID: 11 - MaxHealth: 0 - Position: (1769.135864, 32.664658, 150.395081) - -Resource: HarvestableSpawner_38Dandelions - TypeID: 38 - MaxHealth: 0 - Position: (1746.709717, 44.599632, 299.696503) - -====================================================================== -End of resource data diff --git a/unity-parser/src/ecs/builder.rs b/unity-parser/src/ecs/builder.rs index a456707..097286f 100644 --- a/unity-parser/src/ecs/builder.rs +++ b/unity-parser/src/ecs/builder.rs @@ -161,6 +161,8 @@ pub fn build_world_from_documents( // PASS 3: Execute all deferred linking callbacks let entity_map = linking_ctx.into_inner().execute_callbacks(&mut world); + info!("DEBUG (build_world_from_documents): Final scene entity_map size: {}", entity_map.len()); + Ok((world, entity_map)) } @@ -312,9 +314,14 @@ pub fn build_world_from_documents_into( // PASS 3: Execute all deferred linking callbacks let final_entity_map = linking_ctx.into_inner().execute_callbacks(world); + info!("DEBUG (build_world_from_documents_into): Spawned {} entities", spawned_entities.len()); + info!("DEBUG (build_world_from_documents_into): final_entity_map size: {}, entity_map size before extend: {}", final_entity_map.len(), entity_map.len()); + // Update caller's entity_map with new mappings entity_map.extend(final_entity_map); + info!("DEBUG (build_world_from_documents_into): entity_map size after extend: {}", entity_map.len()); + Ok(spawned_entities) } @@ -359,14 +366,30 @@ fn attach_component( let go_ref = yaml_helpers::get_file_ref(yaml, "m_GameObject"); let entity = match go_ref { - Some(r) => linking_ctx - .borrow() - .entity_map() - .get(&r.file_id) - .copied() - .ok_or_else(|| { - Error::reference_error(format!("Unknown GameObject: {}", r.file_id)) - })?, + Some(r) => { + let entity_opt = linking_ctx + .borrow() + .entity_map() + .get(&r.file_id) + .copied(); + + match entity_opt { + Some(e) => { + // Debug logging for Interactable_Resource MonoBehaviours + if doc.class_name == "MonoBehaviour" { + if let Some(script_ref) = yaml_helpers::get_external_ref(yaml, "m_Script") { + if script_ref.guid.as_str() == "d39ddbf1c2c3d1a4baa070e5e76548bd" { + info!("DEBUG: Found GameObject entity {:?} for Interactable_Resource MonoBehaviour (FileID: {})", e, doc.file_id); + } + } + } + e + } + None => { + return Err(Error::reference_error(format!("Unknown GameObject: {}", r.file_id))); + } + } + } None => { // Some components might not have m_GameObject (e.g., standalone assets) warn!( @@ -424,6 +447,11 @@ fn attach_component( if let Some(script_ref) = yaml_helpers::get_external_ref(yaml, "m_Script") { // Resolve GUID to class name if let Some(class_name) = resolver.resolve_class_name(script_ref.guid.as_str()) { + // Debug logging for specific GUID + if script_ref.guid.as_str() == "d39ddbf1c2c3d1a4baa070e5e76548bd" { + info!("DEBUG: Found Interactable_Resource GUID! Resolved to class name: {}", class_name); + } + // Try to find a registered custom component with this class name let mut found_custom = false; for reg in inventory::iter:: { @@ -433,6 +461,7 @@ fn attach_component( if (reg.parse_and_insert)(yaml, &ctx, world, entity) { // Successfully parsed and inserted linking_ctx.borrow_mut().entity_map_mut().insert(doc.file_id, entity); + info!("DEBUG: Successfully inserted component: {}", class_name); } break; } diff --git a/unity-parser/src/model/mod.rs b/unity-parser/src/model/mod.rs index 65d04f4..b84e036 100644 --- a/unity-parser/src/model/mod.rs +++ b/unity-parser/src/model/mod.rs @@ -136,12 +136,12 @@ impl UnityPrefab { /// /// # Example /// ```ignore - /// let mut instance = prefab.instantiate(); + /// let mut instance = prefab.instantiate(None); /// instance.override_value(file_id, "m_Name", "Player1".into())?; /// let entities = instance.spawn_into(&mut world, &mut entity_map)?; /// ``` - pub fn instantiate(&self) -> crate::types::PrefabInstance { - crate::types::PrefabInstance::new(self) + pub fn instantiate(&self, file_id_counter: Option>>) -> crate::types::PrefabInstance { + crate::types::PrefabInstance::new(self, file_id_counter) } } diff --git a/unity-parser/src/types/unity_types/prefab_instance.rs b/unity-parser/src/types/unity_types/prefab_instance.rs index c70a42b..4ac75f2 100644 --- a/unity-parser/src/types/unity_types/prefab_instance.rs +++ b/unity-parser/src/types/unity_types/prefab_instance.rs @@ -8,6 +8,7 @@ use sparsey::{Entity, World}; use std::collections::HashMap; use std::path::PathBuf; use std::sync::Arc; +use std::cell::Cell; /// An instance of a Unity prefab ready for spawning into a scene /// @@ -20,7 +21,7 @@ use std::sync::Arc; /// # Example /// ```ignore /// let prefab = /* load UnityPrefab */; -/// let mut instance = prefab.instantiate(); +/// let mut instance = prefab.instantiate(None); /// instance.override_value(file_id, "m_Name", "Player1".into())?; /// instance.override_value(file_id, "m_LocalPosition.x", 100.0.into())?; /// let entities = instance.spawn_into(&mut world, &mut entity_map)?; @@ -40,7 +41,8 @@ pub struct PrefabInstance { /// Sequential counter for generating new FileIDs /// Starts at i64::MAX and decrements to avoid collisions with scene FileIDs - next_file_id: i64, + /// NOTE: This should be shared across all instances via a reference + next_file_id: Arc>, /// Source prefab path for debugging source_path: PathBuf, @@ -50,15 +52,22 @@ impl PrefabInstance { /// Create a new instance from a Unity prefab /// /// This clones all documents from the prefab and initializes FileID remapping. - pub fn new(prefab: &UnityPrefab) -> Self { + /// + /// # Arguments + /// * `prefab` - The prefab to instantiate + /// * `file_id_counter` - Optional shared FileID counter to ensure uniqueness across instances + pub fn new(prefab: &UnityPrefab, file_id_counter: Option>>) -> Self { // Clone all documents from the prefab let documents = prefab.documents.clone(); + // Use provided counter or create a new one starting at i64::MAX + let next_file_id = file_id_counter.unwrap_or_else(|| Arc::new(Cell::new(i64::MAX))); + let mut instance = Self { documents, file_id_map: HashMap::new(), overrides: HashMap::new(), - next_file_id: i64::MAX, + next_file_id, source_path: prefab.path.clone(), }; @@ -73,9 +82,9 @@ impl PrefabInstance { /// /// Uses a sequential counter starting from i64::MAX and decrementing. /// This avoids collisions with typical scene FileIDs which are positive. - fn generate_file_id(&mut self) -> FileID { - let id = self.next_file_id; - self.next_file_id -= 1; + fn generate_file_id(&self) -> FileID { + let id = self.next_file_id.get(); + self.next_file_id.set(id - 1); FileID::from_i64(id) } @@ -449,6 +458,9 @@ pub struct PrefabResolver<'a> { /// Prefab GUID resolver for nested prefabs prefab_guid_resolver: Option<&'a crate::parser::PrefabGuidResolver>, + + /// Shared FileID counter to ensure uniqueness across all prefab instances + file_id_counter: Arc>, } impl<'a> PrefabResolver<'a> { @@ -463,6 +475,7 @@ impl<'a> PrefabResolver<'a> { instantiation_stack: Vec::new(), guid_resolver: None, prefab_guid_resolver: None, + file_id_counter: Arc::new(Cell::new(i64::MAX)), } } @@ -490,6 +503,7 @@ impl<'a> PrefabResolver<'a> { instantiation_stack: Vec::new(), guid_resolver, prefab_guid_resolver: Some(prefab_guid_resolver), + file_id_counter: Arc::new(Cell::new(i64::MAX)), } } @@ -524,8 +538,8 @@ impl<'a> PrefabResolver<'a> { // 2. Load prefab via load_prefab() let prefab = self.load_prefab(guid)?; - // 3. Create PrefabInstance - let mut instance = prefab.instantiate(); + // 3. Create PrefabInstance with shared FileID counter + let mut instance = prefab.instantiate(Some(self.file_id_counter.clone())); // 4. Apply component.modifications using override_value() for modification in &component.modifications { @@ -605,8 +619,8 @@ impl<'a> PrefabResolver<'a> { // Push to stack self.instantiation_stack.push(prefab_id.clone()); - // Create instance - let instance = prefab.instantiate(); + // Create instance with shared FileID counter + let instance = prefab.instantiate(Some(self.file_id_counter.clone())); // Find nested prefab references let nested_prefabs = self.find_nested_prefabs(&instance)?; @@ -617,8 +631,8 @@ impl<'a> PrefabResolver<'a> { for (_parent_file_id, nested_component) in nested_prefabs { // Load the referenced prefab if let Ok(nested_prefab) = self.load_prefab(&nested_component.prefab_ref.guid) { - // Apply modifications - let mut nested_instance = nested_prefab.instantiate(); + // Apply modifications with shared FileID counter + let mut nested_instance = nested_prefab.instantiate(Some(self.file_id_counter.clone())); for modification in &nested_component.modifications { nested_instance.override_value( modification.target_file_id,