split project
This commit is contained in:
17
Cargo.lock
generated
17
Cargo.lock
generated
@@ -23,6 +23,16 @@ version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41e67cd8309bbd06cd603a9e693a784ac2e5d1e955f11286e355089fcab3047c"
|
||||
|
||||
[[package]]
|
||||
name = "cursebreaker-parser"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"inventory",
|
||||
"serde_yaml",
|
||||
"sparsey",
|
||||
"unity-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
@@ -242,6 +252,12 @@ dependencies = [
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "sparsey"
|
||||
version = "0.13.3"
|
||||
@@ -303,6 +319,7 @@ dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
"smallvec",
|
||||
"sparsey",
|
||||
"thiserror",
|
||||
"unity-parser-macros",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[workspace]
|
||||
members = ["unity-parser", "unity-parser-macros"]
|
||||
members = ["unity-parser", "unity-parser-macros", "cursebreaker-parser"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
|
||||
10
cursebreaker-parser/Cargo.toml
Normal file
10
cursebreaker-parser/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "cursebreaker-parser"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
unity-parser = { path = "../unity-parser" }
|
||||
serde_yaml = "0.9"
|
||||
inventory = "0.3"
|
||||
sparsey = "0.13"
|
||||
128
cursebreaker-parser/src/main.rs
Normal file
128
cursebreaker-parser/src/main.rs
Normal file
@@ -0,0 +1,128 @@
|
||||
//! Parse Cursebreaker Resources from 10_3.unity Scene
|
||||
//!
|
||||
//! This example demonstrates:
|
||||
//! 1. Parsing the Cursebreaker Unity project
|
||||
//! 2. Finding Interactable_Resource components
|
||||
//! 3. Extracting typeId and transform positions
|
||||
//! 4. Writing resource data to an output file
|
||||
|
||||
mod types;
|
||||
|
||||
use types::InteractableResource;
|
||||
use unity_parser::UnityFile;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("🎮 Cursebreaker - Resource Parser");
|
||||
println!("{}", "=".repeat(70));
|
||||
println!();
|
||||
|
||||
let scene_path = Path::new("/home/connor/repos/CBAssets/_GameAssets/Scenes/Tiles/10_3.unity");
|
||||
|
||||
// Check if scene exists
|
||||
if !scene_path.exists() {
|
||||
eprintln!("❌ Error: Scene not found at {}", scene_path.display());
|
||||
return Err("Scene file not found".into());
|
||||
}
|
||||
|
||||
println!("📁 Parsing scene: {}", scene_path.display());
|
||||
println!();
|
||||
|
||||
// Parse the scene
|
||||
match UnityFile::from_path(&scene_path) {
|
||||
Ok(UnityFile::Scene(scene)) => {
|
||||
println!("✅ Scene parsed successfully!");
|
||||
println!(" Total entities: {}", scene.entity_map.len());
|
||||
println!();
|
||||
|
||||
// Get views for component types we need
|
||||
let resource_view = scene.world.borrow::<InteractableResource>();
|
||||
let transform_view = scene.world.borrow::<unity_parser::Transform>();
|
||||
let gameobject_view = scene.world.borrow::<unity_parser::GameObject>();
|
||||
|
||||
// Find all entities that have Interactable_Resource
|
||||
let mut found_resources = Vec::new();
|
||||
|
||||
for entity in scene.entity_map.values() {
|
||||
if let Some(resource) = resource_view.get(*entity) {
|
||||
let transform = transform_view.get(*entity);
|
||||
let game_object = gameobject_view.get(*entity);
|
||||
|
||||
let name = game_object
|
||||
.and_then(|go| go.name())
|
||||
.unwrap_or("(unnamed)");
|
||||
|
||||
let position = transform
|
||||
.and_then(|t| t.local_position())
|
||||
.map(|p| (p.x, p.y, p.z));
|
||||
|
||||
found_resources.push((name.to_string(), resource.clone(), position));
|
||||
}
|
||||
}
|
||||
|
||||
println!("🔍 Found {} Interactable_Resource component(s)", found_resources.len());
|
||||
println!();
|
||||
|
||||
if !found_resources.is_empty() {
|
||||
// Display resources in console
|
||||
for (name, resource, position) in &found_resources {
|
||||
println!(" 📦 Resource: \"{}\"", name);
|
||||
println!(" • typeId: {}", resource.type_id);
|
||||
println!(" • maxHealth: {}", resource.max_health);
|
||||
if let Some((x, y, z)) = position {
|
||||
println!(" • Position: ({:.2}, {:.2}, {:.2})", x, y, z);
|
||||
} else {
|
||||
println!(" • Position: (no transform)");
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
||||
// Write to output file
|
||||
let output_path = "resources_output.txt";
|
||||
let mut output_file = File::create(output_path)?;
|
||||
|
||||
writeln!(output_file, "Cursebreaker Resources - 10_3.unity Scene")?;
|
||||
writeln!(output_file, "{}", "=".repeat(70))?;
|
||||
writeln!(output_file)?;
|
||||
writeln!(output_file, "Total resources found: {}", found_resources.len())?;
|
||||
writeln!(output_file)?;
|
||||
writeln!(output_file, "{}", "-".repeat(70))?;
|
||||
writeln!(output_file)?;
|
||||
|
||||
for (name, resource, position) in &found_resources {
|
||||
writeln!(output_file, "Resource: {}", name)?;
|
||||
writeln!(output_file, " TypeID: {}", resource.type_id)?;
|
||||
writeln!(output_file, " MaxHealth: {}", resource.max_health)?;
|
||||
if let Some((x, y, z)) = position {
|
||||
writeln!(output_file, " Position: ({:.6}, {:.6}, {:.6})", x, y, z)?;
|
||||
} else {
|
||||
writeln!(output_file, " Position: N/A")?;
|
||||
}
|
||||
writeln!(output_file)?;
|
||||
}
|
||||
|
||||
writeln!(output_file, "{}", "=".repeat(70))?;
|
||||
writeln!(output_file, "End of resource data")?;
|
||||
|
||||
println!("📝 Resource data written to: {}", output_path);
|
||||
println!();
|
||||
}
|
||||
|
||||
println!("{}", "=".repeat(70));
|
||||
println!("✅ Parsing complete!");
|
||||
println!("{}", "=".repeat(70));
|
||||
}
|
||||
Ok(_) => {
|
||||
eprintln!("❌ Error: File is not a scene");
|
||||
return Err("Not a Unity scene file".into());
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("❌ Parse error: {}", e);
|
||||
return Err(Box::new(e));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
47
cursebreaker-parser/src/types/interactable_resource.rs
Normal file
47
cursebreaker-parser/src/types/interactable_resource.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
/// Interactable_Resource component from Cursebreaker
|
||||
///
|
||||
/// C# definition from Interactable_Resource.cs:
|
||||
/// ```csharp
|
||||
/// public class Interactable_Resource : Interactable
|
||||
/// {
|
||||
/// public int health;
|
||||
/// public int maxHealth;
|
||||
/// public int typeId;
|
||||
/// // ... other fields
|
||||
/// }
|
||||
/// ```
|
||||
use unity_parser::{UnityComponent, ComponentContext, EcsInsertable};
|
||||
use serde_yaml::Mapping;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InteractableResource {
|
||||
pub max_health: i64,
|
||||
pub type_id: i64,
|
||||
}
|
||||
|
||||
impl UnityComponent for InteractableResource {
|
||||
fn parse(yaml: &Mapping, _ctx: &ComponentContext) -> Option<Self> {
|
||||
Some(Self {
|
||||
max_health: unity_parser::yaml_helpers::get_i64(yaml, "maxHealth").unwrap_or(0),
|
||||
type_id: unity_parser::yaml_helpers::get_i64(yaml, "typeId").unwrap_or(0),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl EcsInsertable for InteractableResource {
|
||||
fn insert_into_world(self, world: &mut sparsey::World, entity: sparsey::Entity) {
|
||||
world.insert(entity, (self,));
|
||||
}
|
||||
}
|
||||
|
||||
// Register component with inventory
|
||||
inventory::submit! {
|
||||
unity_parser::ComponentRegistration {
|
||||
type_id: 114,
|
||||
class_name: "Interactable_Resource",
|
||||
parse_and_insert: |yaml, ctx, world, entity| {
|
||||
<InteractableResource as EcsInsertable>::parse_and_insert(yaml, ctx, world, entity)
|
||||
},
|
||||
register: |builder| builder.register::<InteractableResource>(),
|
||||
}
|
||||
}
|
||||
3
cursebreaker-parser/src/types/mod.rs
Normal file
3
cursebreaker-parser/src/types/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
mod interactable_resource;
|
||||
|
||||
pub use interactable_resource::InteractableResource;
|
||||
@@ -5,15 +5,15 @@ Total resources found: 2
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Resource: HarvestableSpawner_2Copper Ore
|
||||
TypeID: 2
|
||||
MaxHealth: 0
|
||||
Position: (1788.727173, 40.725288, 172.017670)
|
||||
|
||||
Resource: HarvestableSpawner_38Dandelions
|
||||
TypeID: 38
|
||||
MaxHealth: 0
|
||||
Position: (1746.709717, 44.599632, 299.696503)
|
||||
|
||||
Resource: HarvestableSpawner_2Copper Ore
|
||||
TypeID: 2
|
||||
MaxHealth: 0
|
||||
Position: (1788.727173, 40.725288, 172.017670)
|
||||
|
||||
======================================================================
|
||||
End of resource data
|
||||
|
||||
@@ -46,6 +46,9 @@ once_cell = "1.19"
|
||||
# Component registry for custom MonoBehaviours
|
||||
inventory = "0.3"
|
||||
|
||||
# Small vector optimization for materials list
|
||||
smallvec = "1.13"
|
||||
|
||||
# Procedural macro for derive(UnityComponent)
|
||||
unity-parser-macros = { path = "../unity-parser-macros" }
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ pub use reference::UnityReference;
|
||||
pub use type_filter::TypeFilter;
|
||||
pub use type_registry::{get_class_name, get_type_id};
|
||||
pub use unity_types::{
|
||||
GameObject, PrefabInstance, PrefabInstanceComponent, PrefabModification, PrefabResolver,
|
||||
RectTransform, Transform,
|
||||
GameObject, MeshFilter, PrefabInstance, PrefabInstanceComponent, PrefabModification,
|
||||
PrefabResolver, RectTransform, Renderer, Transform,
|
||||
};
|
||||
pub use values::{Color, ExternalRef, FileRef, Quaternion, Vector2, Vector3};
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
//! Unity-specific types (GameObjects, Transforms, PrefabInstances)
|
||||
|
||||
pub mod game_object;
|
||||
pub mod mesh_filter;
|
||||
pub mod prefab_instance;
|
||||
pub mod renderer;
|
||||
pub mod transform;
|
||||
|
||||
pub use game_object::GameObject;
|
||||
pub use mesh_filter::MeshFilter;
|
||||
pub use prefab_instance::{
|
||||
PrefabInstance, PrefabInstanceComponent, PrefabModification, PrefabResolver,
|
||||
};
|
||||
pub use renderer::Renderer;
|
||||
pub use transform::{RectTransform, Transform};
|
||||
|
||||
Reference in New Issue
Block a user