duplicate fix

This commit is contained in:
2026-01-06 13:27:40 +00:00
parent d294748b88
commit be061cb3a4
3 changed files with 69 additions and 19 deletions

View File

@@ -14,7 +14,10 @@
"Bash(grep:*)", "Bash(grep:*)",
"Bash(wc:*)", "Bash(wc:*)",
"Bash(pgrep:*)", "Bash(pgrep:*)",
"Bash(cargo doc:*)" "Bash(cargo doc:*)",
"Bash(xargs dirname:*)",
"Bash(xargs -I {} find {} -name \"*.cs\")",
"Bash(RUST_LOG=debug cargo run:*)"
], ],
"additionalDirectories": [ "additionalDirectories": [
"/home/connor/repos/CBAssets/" "/home/connor/repos/CBAssets/"

View File

@@ -52,15 +52,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
log::logger().flush(); log::logger().flush();
scene.world scene.world
.query_all::<(&InteractableResource, &unity_parser::Transform, &unity_parser::GameObject)>() .query_all::<(&InteractableResource, &unity_parser::WorldTransform, &unity_parser::GameObject)>()
.for_each(|(resource, transform, object)| { .for_each(|(resource, transform, object)| {
info!(" 📦 Resource: \"{}\"", object.name); info!(" 📦 Resource: \"{}\"", object.name);
info!(" • typeId: {}", resource.type_id); info!(" • typeId: {}", resource.type_id);
info!(" • maxHealth: {}", resource.max_health);
// Extract world position from WorldTransform // Extract world position from WorldTransform
let world_pos = transform.local_position; let world_pos = transform.position();
info!(" Local Position: ({:.2}, {:.2}, {:.2})", world_pos.x, world_pos.y, world_pos.z); info!(" • Position: ({:.2}, {:.2}, {:.2})", world_pos.x, world_pos.y, world_pos.z);
log::logger().flush();
}); });
log::logger().flush(); log::logger().flush();

View File

@@ -383,6 +383,10 @@ pub struct PrefabModification {
/// The FileID of the target object within the nested prefab /// The FileID of the target object within the nested prefab
pub target_file_id: FileID, pub target_file_id: FileID,
/// Optional GUID for cross-file references
/// When present, indicates the target is in a different prefab file
pub target_guid: Option<String>,
/// The property path to modify (dot notation) /// The property path to modify (dot notation)
pub property_path: String, pub property_path: String,
@@ -392,9 +396,25 @@ pub struct PrefabModification {
/// Parse modifications array from Unity YAML /// Parse modifications array from Unity YAML
fn parse_modifications(yaml: &Mapping) -> Option<Vec<PrefabModification>> { fn parse_modifications(yaml: &Mapping) -> Option<Vec<PrefabModification>> {
let mods_array = yaml // First check if m_Modification exists
.get(&Value::String("m_Modification".to_string())) let modification_value = yaml.get(&Value::String("m_Modification".to_string()));
.and_then(|v| v.as_sequence())?;
if modification_value.is_none() {
return Some(Vec::new());
}
// Try to get the m_Modifications.m_Modifications nested structure
let mods_array = if let Some(mod_obj) = modification_value.and_then(|v| v.as_mapping()) {
// Unity sometimes nests it as m_Modification: { m_Modifications: [...] }
mod_obj
.get(&Value::String("m_Modifications".to_string()))
.and_then(|v| v.as_sequence())
} else {
// Or it might be directly an array: m_Modification: [...]
modification_value.and_then(|v| v.as_sequence())
};
let mods_array = mods_array?;
let mut mods = Vec::new(); let mut mods = Vec::new();
for mod_yaml in mods_array { for mod_yaml in mods_array {
@@ -412,12 +432,20 @@ fn parse_modifications(yaml: &Mapping) -> Option<Vec<PrefabModification>> {
/// Parse a single modification entry /// Parse a single modification entry
fn parse_single_modification(yaml: &Mapping) -> Option<PrefabModification> { fn parse_single_modification(yaml: &Mapping) -> Option<PrefabModification> {
// Get target FileID // Get target FileID and optional GUID
let target = yaml let target = yaml
.get(&Value::String("target".to_string())) .get(&Value::String("target".to_string()))
.and_then(|v| v.as_mapping())?; .and_then(|v| v.as_mapping())?;
let target_file_id = yaml_helpers::get_file_ref_from_mapping(target)?.file_id; let target_file_id = yaml_helpers::get_file_ref_from_mapping(target)?.file_id;
// Extract GUID if present (for cross-file references)
// Format: {fileID: N, guid: "...", type: 3}
let target_guid = target
.get(&Value::String("guid".to_string()))
.and_then(|v| v.as_str())
.map(|s| s.to_string());
// Get property path // Get property path
let property_path = yaml let property_path = yaml
.get(&Value::String("propertyPath".to_string())) .get(&Value::String("propertyPath".to_string()))
@@ -431,6 +459,7 @@ fn parse_single_modification(yaml: &Mapping) -> Option<PrefabModification> {
Some(PrefabModification { Some(PrefabModification {
target_file_id, target_file_id,
target_guid,
property_path, property_path,
value, value,
}) })
@@ -542,12 +571,21 @@ impl<'a> PrefabResolver<'a> {
let mut instance = prefab.instantiate(Some(self.file_id_counter.clone())); let mut instance = prefab.instantiate(Some(self.file_id_counter.clone()));
// 4. Apply component.modifications using override_value() // 4. Apply component.modifications using override_value()
// Only apply modifications that target this prefab (matching GUID or no GUID)
for modification in &component.modifications { for modification in &component.modifications {
instance.override_value( // Check if this modification targets this prefab
modification.target_file_id, let should_apply = match &modification.target_guid {
&modification.property_path, Some(target_guid) => target_guid == guid,
modification.value.clone(), None => true, // No GUID means local reference, apply it
)?; };
if should_apply {
instance.override_value(
modification.target_file_id,
&modification.property_path,
modification.value.clone(),
)?;
}
} }
// 5. Spawn the instance // 5. Spawn the instance
@@ -633,12 +671,21 @@ impl<'a> PrefabResolver<'a> {
if let Ok(nested_prefab) = self.load_prefab(&nested_component.prefab_ref.guid) { if let Ok(nested_prefab) = self.load_prefab(&nested_component.prefab_ref.guid) {
// Apply modifications with shared FileID counter // Apply modifications with shared FileID counter
let mut nested_instance = nested_prefab.instantiate(Some(self.file_id_counter.clone())); let mut nested_instance = nested_prefab.instantiate(Some(self.file_id_counter.clone()));
let nested_guid = &nested_component.prefab_ref.guid;
for modification in &nested_component.modifications { for modification in &nested_component.modifications {
nested_instance.override_value( // Only apply modifications that target this nested prefab
modification.target_file_id, let should_apply = match &modification.target_guid {
&modification.property_path, Some(target_guid) => target_guid == nested_guid,
modification.value.clone(), None => true, // No GUID means local reference, apply it
)?; };
if should_apply {
nested_instance.override_value(
modification.target_file_id,
&modification.property_path,
modification.value.clone(),
)?;
}
} }
// Recursively spawn nested prefab // Recursively spawn nested prefab