From 6adfe21ce3d4614f2d83e4944e03aa1846fa1e87 Mon Sep 17 00:00:00 2001 From: Connor Date: Sun, 11 Jan 2026 03:03:39 +0000 Subject: [PATCH] selective parsing of scenes --- cursebreaker-parser/src/bin/scene-parser.rs | 21 ++++++++++----- unity-parser/src/ecs/builder.rs | 6 ++--- unity-parser/src/lib.rs | 2 +- unity-parser/src/model/mod.rs | 29 +++++++++++++++++++++ unity-parser/src/parser/mod.rs | 19 ++++++++++++-- 5 files changed, 65 insertions(+), 12 deletions(-) diff --git a/cursebreaker-parser/src/bin/scene-parser.rs b/cursebreaker-parser/src/bin/scene-parser.rs index 4997bfc..0b7f852 100644 --- a/cursebreaker-parser/src/bin/scene-parser.rs +++ b/cursebreaker-parser/src/bin/scene-parser.rs @@ -2,12 +2,12 @@ //! //! This binary handles: //! - Initializing the Unity project -//! - Parsing Unity scenes -//! - Extracting Interactable_Resource components +//! - Parsing Unity scenes with type filtering +//! - Extracting Interactable_Resource components only //! - Computing world transforms use cursebreaker_parser::InteractableResource; -use unity_parser::UnityProject; +use unity_parser::{UnityProject, TypeFilter}; use std::path::Path; use unity_parser::log::DedupLogger; use log::{info, error, LevelFilter}; @@ -29,14 +29,23 @@ fn main() -> Result<(), Box> { let project = UnityProject::from_path(project_root)?; - // Now parse the scene using the pre-built GUID resolvers + // Create type filter to only parse GameObject, Transform, and InteractableResource MonoBehaviour + info!("🔍 Setting up type filter:"); + info!(" • Unity types: GameObject, Transform"); + info!(" • Custom MonoBehaviours: InteractableResource"); + let type_filter = TypeFilter::new( + vec!["GameObject", "Transform", "PrefabInstance"], + vec!["InteractableResource"] + ); + + // Now parse the scene using the pre-built GUID resolvers with filtering 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) { + // Parse the scene using the project with type filtering + match project.parse_scene_filtered(scene_path, Some(&type_filter)) { Ok(mut scene) => { info!("✅ Scene parsed successfully!"); info!(" Total entities: {}", scene.entity_map.len()); diff --git a/unity-parser/src/ecs/builder.rs b/unity-parser/src/ecs/builder.rs index 438fa0a..4c5a752 100644 --- a/unity-parser/src/ecs/builder.rs +++ b/unity-parser/src/ecs/builder.rs @@ -144,9 +144,9 @@ pub fn build_world_from_documents( &mut world, linking_ctx.borrow_mut().entity_map_mut(), ) { - Ok(spawned) => { - info!("Spawned {} entities from prefab GUID: {}", - spawned.len(), component.prefab_ref.guid); + Ok(_spawned) => { + // info!("Spawned {} entities from prefab GUID: {}", + // spawned.len(), component.prefab_ref.guid); } Err(e) => { // Soft failure - warn but continue diff --git a/unity-parser/src/lib.rs b/unity-parser/src/lib.rs index 38b398e..53067c7 100644 --- a/unity-parser/src/lib.rs +++ b/unity-parser/src/lib.rs @@ -42,7 +42,7 @@ pub use error::{Error, Result}; pub use model::{RawDocument, UnityAsset, UnityFile, UnityPrefab, UnityScene, UnityProject}; pub use parser::{ find_project_root, meta::MetaFile, parse_unity_file, parse_unity_file_filtered, - GuidResolver, PrefabGuidResolver, + parse_scene_with_project_filtered, GuidResolver, PrefabGuidResolver, }; pub use post_processing::{compute_world_transforms, WorldTransform}; pub use property::PropertyValue; diff --git a/unity-parser/src/model/mod.rs b/unity-parser/src/model/mod.rs index b84e036..19609ba 100644 --- a/unity-parser/src/model/mod.rs +++ b/unity-parser/src/model/mod.rs @@ -317,6 +317,35 @@ impl UnityProject { crate::parser::parse_scene_with_project(&path, self) } + /// Parse a Unity scene using the pre-built GUID resolvers with optional type filtering + /// + /// # Arguments + /// + /// * `path` - Path to the scene file (relative to project root or absolute) + /// * `type_filter` - Optional filter for Unity types and MonoBehaviour class names + /// + /// # Example + /// + /// ```no_run + /// # use unity_parser::{UnityProject, TypeFilter}; + /// # let project = UnityProject::from_path("/home/user/repos/CBAssets")?; + /// let filter = TypeFilter::new( + /// vec!["GameObject", "Transform"], + /// vec!["InteractableResource"] + /// ); + /// let scene = project.parse_scene_filtered("_GameAssets/Scenes/Tiles/10_3.unity", Some(&filter))?; + /// println!("Scene has {} entities", scene.entity_map.len()); + /// # Ok::<(), unity_parser::Error>(()) + /// ``` + pub fn parse_scene_filtered( + &self, + path: impl AsRef, + type_filter: Option<&crate::types::TypeFilter> + ) -> crate::Result { + let path = self.resolve_path(path.as_ref()); + crate::parser::parse_scene_with_project_filtered(&path, self, type_filter) + } + /// Parse a Unity prefab using the pre-built GUID resolvers /// /// # Arguments diff --git a/unity-parser/src/parser/mod.rs b/unity-parser/src/parser/mod.rs index c071d1a..62166a4 100644 --- a/unity-parser/src/parser/mod.rs +++ b/unity-parser/src/parser/mod.rs @@ -208,14 +208,29 @@ fn parse_scene(path: &Path, content: &str, type_filter: Option<&TypeFilter>) -> /// * `path` - Path to the scene file /// * `project` - Pre-initialized UnityProject with GUID resolvers pub fn parse_scene_with_project(path: &Path, project: &UnityProject) -> Result { + parse_scene_with_project_filtered(path, project, None) +} + +/// Parse a scene file using pre-built GUID resolvers from a UnityProject with optional type filtering +/// +/// # Arguments +/// +/// * `path` - Path to the scene file +/// * `project` - Pre-initialized UnityProject with GUID resolvers +/// * `type_filter` - Optional filter for Unity types and MonoBehaviour class names +pub fn parse_scene_with_project_filtered( + path: &Path, + project: &UnityProject, + type_filter: Option<&TypeFilter> +) -> Result { // Read the file let content = std::fs::read_to_string(path)?; // Validate Unity header validate_unity_header(&content, path)?; - // Parse raw documents - let raw_documents = parse_raw_documents(&content, None)?; + // Parse raw documents with type filtering + let raw_documents = parse_raw_documents(&content, type_filter)?; // Build ECS world from documents using project's resolvers let (world, entity_map) = crate::ecs::build_world_from_documents(