From 8bfb2ba25e8e87e55fb142d428157b79446093b5 Mon Sep 17 00:00:00 2001 From: Rex Magana Date: Mon, 17 Jun 2024 09:01:21 -0600 Subject: [PATCH 1/4] Migration changes --- Cargo.toml | 6 +++--- examples/farming_sim.rs | 10 +++++----- src/lib.rs | 5 ++++- tests/steps.rs | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 11d90cd..f2ef110 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,13 +15,13 @@ homepage = "https://github.com/zkat/big-brain" [workspace] [dependencies] -bevy = { version = "0.13.2", default-features = false } +bevy = { version = "0.14.0-rc.3", default-features = false } big-brain-derive = { version = "=0.19.0", path = "./derive" } [dev-dependencies] -bevy = { version = "0.13.2", default-features = true } +bevy = { version = "0.14.0-rc.3", default-features = true } rand = { version = "0.8.5", features = ["small_rng"] } -bevy-scene-hook = "10.0.0" +bevy-scene-hook = { git = "https://github.com/stargazing-dino/bevy-scene-hook.git", branch = "update-14.0" } [features] trace = [] diff --git a/examples/farming_sim.rs b/examples/farming_sim.rs index ea7abb1..8dba5c9 100644 --- a/examples/farming_sim.rs +++ b/examples/farming_sim.rs @@ -6,14 +6,14 @@ //! - When not tired, find the farm field and harvest items over time //! - When inventory is full, find the market and sell items for money -use bevy::{log::LogPlugin, prelude::*}; +use bevy::{color::palettes::css, log::LogPlugin, prelude::*}; use bevy_scene_hook::{HookPlugin, HookedSceneBundle, SceneHook}; use big_brain::prelude::*; use big_brain_derive::ActionBuilder; -const DEFAULT_COLOR: Color = Color::BLACK; -const SLEEP_COLOR: Color = Color::RED; -const FARM_COLOR: Color = Color::BLUE; +const DEFAULT_COLOR: Color = Color::Srgba(css::BLACK); +const SLEEP_COLOR: Color = Color::Srgba(css::RED); +const FARM_COLOR: Color = Color::Srgba(css::BLUE); const MAX_DISTANCE: f32 = 0.1; const MAX_INVENTORY_ITEMS: f32 = 20.0; const WORK_NEED_SCORE: f32 = 0.6; @@ -608,7 +608,7 @@ fn main() { // Use `RUST_LOG=big_brain=trace,farming_sim=trace cargo run --example // farming_sim --features=trace` to see extra tracing output. filter: "big_brain=debug,farming_sim=debug".to_string(), - update_subscriber: None, + custom_layer: |_| None, })) .add_plugins(HookPlugin) .add_plugins(BigBrainPlugin::new(PreUpdate)) diff --git a/src/lib.rs b/src/lib.rs index 20aa39e..7ce695d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -202,7 +202,10 @@ pub mod prelude { }; } -use bevy::{ecs::schedule::ScheduleLabel, prelude::*, utils::intern::Interned}; +use bevy::{ + ecs::{intern::Interned, schedule::ScheduleLabel}, + prelude::*, +}; /// Core [`Plugin`] for Big Brain behavior. Required for any of the /// [`Thinker`](thinker::Thinker)-related magic to work. diff --git a/tests/steps.rs b/tests/steps.rs index 51400b5..b0806ff 100644 --- a/tests/steps.rs +++ b/tests/steps.rs @@ -70,7 +70,7 @@ fn exit_action( *state = ActionState::Executing; } if *state == ActionState::Executing { - app_exit_events.send(AppExit); + app_exit_events.send(AppExit::Success); } } } From 8d4bf3add9bd3485ff01aa30d8e1c8df4accb3fa Mon Sep 17 00:00:00 2001 From: Rex Magana Date: Fri, 5 Jul 2024 15:24:46 -0600 Subject: [PATCH 2/4] Remove bevy-scene-hook --- Cargo.toml | 5 +-- examples/farming_sim.rs | 95 ++++++++++++++++++++++++++++++++--------- 2 files changed, 77 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f2ef110..64648a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,13 +15,12 @@ homepage = "https://github.com/zkat/big-brain" [workspace] [dependencies] -bevy = { version = "0.14.0-rc.3", default-features = false } +bevy = { version = "0.14.0", default-features = false } big-brain-derive = { version = "=0.19.0", path = "./derive" } [dev-dependencies] -bevy = { version = "0.14.0-rc.3", default-features = true } +bevy = { version = "0.14.0", default-features = true } rand = { version = "0.8.5", features = ["small_rng"] } -bevy-scene-hook = { git = "https://github.com/stargazing-dino/bevy-scene-hook.git", branch = "update-14.0" } [features] trace = [] diff --git a/examples/farming_sim.rs b/examples/farming_sim.rs index 8dba5c9..75c2e2d 100644 --- a/examples/farming_sim.rs +++ b/examples/farming_sim.rs @@ -6,8 +6,8 @@ //! - When not tired, find the farm field and harvest items over time //! - When inventory is full, find the market and sell items for money +use bevy::scene::SceneInstance; use bevy::{color::palettes::css, log::LogPlugin, prelude::*}; -use bevy_scene_hook::{HookPlugin, HookedSceneBundle, SceneHook}; use big_brain::prelude::*; use big_brain_derive::ActionBuilder; @@ -386,8 +386,10 @@ pub fn move_to_nearest_system( let delta_b = *b - actor_transform.translation; delta_a.length().partial_cmp(&delta_b.length()).unwrap() }) - .unwrap() - .1; + .and_then(|t| Some(t.1)); + let Some(goal_transform) = goal_transform else { + continue; + }; let delta = goal_transform.translation - actor_transform.translation; let distance = delta.xz().length(); @@ -498,24 +500,13 @@ fn init_entities( }, )); - // We use a HookedSceneBundle to attach a SceneHook to the entity. This hook - // will be called when the entity is spawned, and will allow us to insert - // additional components into the spawned entities. + // Loading our scene here. Note we'll still need to add components to different parts + // of the gltf in order to query their positions. We do this through an observer further below. commands.spawn(( Name::new("Town"), - HookedSceneBundle { - scene: SceneBundle { - scene: asset_server.load("models/town.glb#Scene0"), - ..default() - }, - hook: SceneHook::new(|entity, cmds| { - match entity.get::().map(|t| t.as_str()) { - Some("Farm_Marker") => cmds.insert(Field), - Some("Market_Marker") => cmds.insert(Market), - Some("House_Marker") => cmds.insert(House), - _ => cmds, - }; - }), + SceneBundle { + scene: asset_server.load("models/town.glb#Scene0"), + ..default() }, )); @@ -601,6 +592,36 @@ fn init_entities( }); } +// ================================================================================ +// Scene Loading 🏗️ +// ================================================================================ + +// Define a custom event for our scene loading +#[derive(Event)] +struct SceneLoaded { + scene_entity: Entity, +} + +// Define a marker component to indicate what entities we've already processed +#[derive(Component)] +struct SceneProcessed; + +// System to check if a scene has finished loading +fn check_scene_loaded( + mut commands: Commands, + query: Query<(Entity, &SceneInstance), Without>, + scene_spawner: Res, +) { + for (entity, instance) in query.iter() { + if scene_spawner.instance_is_ready(**instance) { + commands.entity(entity).insert(SceneProcessed); + commands.trigger(SceneLoaded { + scene_entity: entity, + }); + } + } +} + fn main() { App::new() .add_plugins(DefaultPlugins.set(LogPlugin { @@ -610,7 +631,41 @@ fn main() { filter: "big_brain=debug,farming_sim=debug".to_string(), custom_layer: |_| None, })) - .add_plugins(HookPlugin) + .add_event::() + .add_systems(Update, check_scene_loaded) + // This observer will attach components to entities in the scene based on their names. + .observe( + |trigger: Trigger, + scene_manager: Res, + scene_query: Query<(Entity, &SceneInstance)>, + other_query: Query<(Entity, &Name)>, + mut commands: Commands| { + let scene_entity = trigger.event().scene_entity; + let (entity, scene_instance) = scene_query.get(scene_entity).unwrap(); + let entities = scene_manager + .iter_instance_entities(**scene_instance) + .chain(std::iter::once(entity)); + + for entity in entities { + if let Ok((entity, name)) = other_query.get(entity) { + let mut entity_commands = commands.entity(entity); + + match name.as_str() { + "Farm_Marker" => { + entity_commands.insert(Field); + } + "Market_Marker" => { + entity_commands.insert(Market); + } + "House_Marker" => { + entity_commands.insert(House); + } + _ => (), + } + } + } + }, + ) .add_plugins(BigBrainPlugin::new(PreUpdate)) .add_systems(Startup, init_entities) .add_systems(Update, (fatigue_system, update_ui)) From 30c22891586892b98b310d4a4596c52b70157270 Mon Sep 17 00:00:00 2001 From: Rex Magana Date: Fri, 5 Jul 2024 15:38:09 -0600 Subject: [PATCH 3/4] pass through scene entities --- examples/farming_sim.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/examples/farming_sim.rs b/examples/farming_sim.rs index 75c2e2d..edcc792 100644 --- a/examples/farming_sim.rs +++ b/examples/farming_sim.rs @@ -599,7 +599,8 @@ fn init_entities( // Define a custom event for our scene loading #[derive(Event)] struct SceneLoaded { - scene_entity: Entity, + /// The entities in this scene + entities: Vec, } // Define a marker component to indicate what entities we've already processed @@ -615,8 +616,12 @@ fn check_scene_loaded( for (entity, instance) in query.iter() { if scene_spawner.instance_is_ready(**instance) { commands.entity(entity).insert(SceneProcessed); + let entities = scene_spawner + .iter_instance_entities(**instance) + .chain(std::iter::once(entity)); + commands.trigger(SceneLoaded { - scene_entity: entity, + entities: entities.collect(), }); } } @@ -636,18 +641,10 @@ fn main() { // This observer will attach components to entities in the scene based on their names. .observe( |trigger: Trigger, - scene_manager: Res, - scene_query: Query<(Entity, &SceneInstance)>, other_query: Query<(Entity, &Name)>, mut commands: Commands| { - let scene_entity = trigger.event().scene_entity; - let (entity, scene_instance) = scene_query.get(scene_entity).unwrap(); - let entities = scene_manager - .iter_instance_entities(**scene_instance) - .chain(std::iter::once(entity)); - - for entity in entities { - if let Ok((entity, name)) = other_query.get(entity) { + for entity in trigger.event().entities.iter() { + if let Ok((entity, name)) = other_query.get(*entity) { let mut entity_commands = commands.entity(entity); match name.as_str() { From c6bc022024a9aa2505fe43a4c3929adbcc3d8e8a Mon Sep 17 00:00:00 2001 From: Rex Magana Date: Fri, 5 Jul 2024 15:48:27 -0600 Subject: [PATCH 4/4] "other_query" -> "query" --- examples/farming_sim.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/farming_sim.rs b/examples/farming_sim.rs index edcc792..4f7e075 100644 --- a/examples/farming_sim.rs +++ b/examples/farming_sim.rs @@ -616,6 +616,7 @@ fn check_scene_loaded( for (entity, instance) in query.iter() { if scene_spawner.instance_is_ready(**instance) { commands.entity(entity).insert(SceneProcessed); + let entities = scene_spawner .iter_instance_entities(**instance) .chain(std::iter::once(entity)); @@ -641,10 +642,10 @@ fn main() { // This observer will attach components to entities in the scene based on their names. .observe( |trigger: Trigger, - other_query: Query<(Entity, &Name)>, + query: Query<(Entity, &Name)>, mut commands: Commands| { for entity in trigger.event().entities.iter() { - if let Ok((entity, name)) = other_query.get(*entity) { + if let Ok((entity, name)) = query.get(*entity) { let mut entity_commands = commands.entity(entity); match name.as_str() {