chore(): cargo fmt (#21)

This commit is contained in:
GitGhillie 2023-10-13 12:53:26 +02:00 committed by GitHub
parent a1c32ae1d6
commit f41a315563
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 1136 additions and 1280 deletions

View File

@ -1,5 +1,5 @@
use bevy::prelude::*;
use bevy::ecs::system::Command; use bevy::ecs::system::Command;
use bevy::prelude::*;
// modified version from https://github.com/bevyengine/bevy/issues/1515, // modified version from https://github.com/bevyengine/bevy/issues/1515,
// more specifically https://gist.github.com/nwtnni/85d6b87ae75337a522166c500c9a8418 // more specifically https://gist.github.com/nwtnni/85d6b87ae75337a522166c500c9a8418

View File

@ -1,5 +1,3 @@
pub mod spawn_from_blueprints; pub mod spawn_from_blueprints;
pub use spawn_from_blueprints::*; pub use spawn_from_blueprints::*;
@ -25,19 +23,18 @@ pub enum GltfBlueprintsSet{
pub struct BluePrintBundle { pub struct BluePrintBundle {
pub blueprint: BlueprintName, pub blueprint: BlueprintName,
pub spawn_here: SpawnHere, pub spawn_here: SpawnHere,
pub transform: TransformBundle pub transform: TransformBundle,
} }
impl Default for BluePrintBundle { impl Default for BluePrintBundle {
fn default() -> Self { fn default() -> Self {
BluePrintBundle { BluePrintBundle {
blueprint: BlueprintName("default".into()), blueprint: BlueprintName("default".into()),
spawn_here: SpawnHere, spawn_here: SpawnHere,
transform: TransformBundle::default() transform: TransformBundle::default(),
} }
} }
} }
#[derive(Clone, Resource)] #[derive(Clone, Resource)]
pub(crate) struct BluePrintsConfig { pub(crate) struct BluePrintsConfig {
pub(crate) library_folder: PathBuf, pub(crate) library_folder: PathBuf,
@ -59,22 +56,23 @@ impl Default for BlueprintsPlugin {
impl Plugin for BlueprintsPlugin { impl Plugin for BlueprintsPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.register_type::<BlueprintName>()
.register_type::<BlueprintName>()
.register_type::<SpawnHere>() .register_type::<SpawnHere>()
.insert_resource(BluePrintsConfig{library_folder: self.library_folder.clone()}) .insert_resource(BluePrintsConfig {
library_folder: self.library_folder.clone(),
})
.configure_sets( .configure_sets(
Update, Update,
(GltfBlueprintsSet::Spawn, GltfBlueprintsSet::AfterSpawn).chain().after(GltfComponentsSet::Injection) (GltfBlueprintsSet::Spawn, GltfBlueprintsSet::AfterSpawn)
.chain()
.after(GltfComponentsSet::Injection),
) )
.add_systems(
.add_systems(Update, Update,
(spawn_from_blueprints) (spawn_from_blueprints)
// .run_if(in_state(AppState::AppRunning).or_else(in_state(AppState::LoadingGame))) // FIXME: how to replace this with a crate compatible version ? // .run_if(in_state(AppState::AppRunning).or_else(in_state(AppState::LoadingGame))) // FIXME: how to replace this with a crate compatible version ?
.in_set(GltfBlueprintsSet::Spawn), .in_set(GltfBlueprintsSet::Spawn),
) )
.add_systems( .add_systems(
Update, Update,
( (
@ -87,7 +85,6 @@ impl Plugin for BlueprintsPlugin {
.chain() .chain()
// .run_if(in_state(AppState::LoadingGame).or_else(in_state(AppState::AppRunning))) // FIXME: how to replace this with a crate compatible version ? // .run_if(in_state(AppState::LoadingGame).or_else(in_state(AppState::AppRunning))) // FIXME: how to replace this with a crate compatible version ?
.in_set(GltfBlueprintsSet::AfterSpawn), .in_set(GltfBlueprintsSet::AfterSpawn),
) );
;
} }
} }

View File

@ -1,6 +1,6 @@
use std::path::Path; use std::path::Path;
use bevy::{prelude::*, gltf::Gltf}; use bevy::{gltf::Gltf, prelude::*};
use crate::BluePrintsConfig; use crate::BluePrintsConfig;
@ -9,12 +9,12 @@ use crate::BluePrintsConfig;
pub struct GameWorldTag; pub struct GameWorldTag;
/// Main component for the blueprints /// Main component for the blueprints
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub struct BlueprintName(pub String); pub struct BlueprintName(pub String);
/// flag component needed to signify the intent to spawn a Blueprint /// flag component needed to signify the intent to spawn a Blueprint
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub struct SpawnHere; pub struct SpawnHere;
@ -22,7 +22,6 @@ pub struct SpawnHere;
/// FlagComponent for spawned entity /// FlagComponent for spawned entity
pub struct Spawned; pub struct Spawned;
#[derive(Component)] #[derive(Component)]
/// helper component, just to transfer some data /// helper component, just to transfer some data
pub(crate) struct Original(pub Entity); pub(crate) struct Original(pub Entity);
@ -34,22 +33,29 @@ pub struct SpawnedRoot;
/// main spawning functions, /// main spawning functions,
/// * also takes into account the already exisiting "override" components, ie "override components" > components from blueprint /// * also takes into account the already exisiting "override" components, ie "override components" > components from blueprint
pub(crate) fn spawn_from_blueprints( pub(crate) fn spawn_from_blueprints(
spawn_placeholders: Query<(Entity, &Name, &BlueprintName, &Transform), (Added<BlueprintName>, Added<SpawnHere>, Without<Spawned>, Without<SpawnedRoot>)>, spawn_placeholders: Query<
(Entity, &Name, &BlueprintName, &Transform),
(
Added<BlueprintName>,
Added<SpawnHere>,
Without<Spawned>,
Without<SpawnedRoot>,
),
>,
mut commands: Commands, mut commands: Commands,
mut game_world: Query<(Entity, &Children), With<GameWorldTag>>, mut game_world: Query<(Entity, &Children), With<GameWorldTag>>,
assets_gltf: Res<Assets<Gltf>>, assets_gltf: Res<Assets<Gltf>>,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
blueprints_config: Res<BluePrintsConfig> blueprints_config: Res<BluePrintsConfig>,
) { ) {
for (entity, name, blupeprint_name, global_transform) in spawn_placeholders.iter() { for (entity, name, blupeprint_name, global_transform) in spawn_placeholders.iter() {
info!("need to spawn {:?}", blupeprint_name.0); info!("need to spawn {:?}", blupeprint_name.0);
let what = &blupeprint_name.0; let what = &blupeprint_name.0;
let model_file_name = format!("{}.glb", &what); let model_file_name = format!("{}.glb", &what);
let model_path = Path::new(&blueprints_config.library_folder) let model_path =
.join(Path::new(model_file_name.as_str())); Path::new(&blueprints_config.library_folder).join(Path::new(model_file_name.as_str()));
info!("attempting to spawn {:?}", model_path); info!("attempting to spawn {:?}", model_path);
let scene: Handle<Gltf> = asset_server.load(model_path); let scene: Handle<Gltf> = asset_server.load(model_path);
@ -58,15 +64,20 @@ pub(crate) fn spawn_from_blueprints(
let world = game_world.single_mut(); let world = game_world.single_mut();
let world = world.1[0]; // FIXME: dangerous hack because our gltf data have a single child like this, but might not always be the case let world = world.1[0]; // FIXME: dangerous hack because our gltf data have a single child like this, but might not always be the case
let gltf = assets_gltf.get(&scene).expect("this gltf should have been loaded"); let gltf = assets_gltf
.get(&scene)
.expect("this gltf should have been loaded");
// WARNING we work under the assumtion that there is ONLY ONE named scene, and that the first one is the right one // WARNING we work under the assumtion that there is ONLY ONE named scene, and that the first one is the right one
let main_scene_name =gltf.named_scenes.keys().nth(0).expect("there should be at least one named scene in the gltf file to spawn"); let main_scene_name = gltf
.named_scenes
.keys()
.nth(0)
.expect("there should be at least one named scene in the gltf file to spawn");
let scene = &gltf.named_scenes[main_scene_name]; let scene = &gltf.named_scenes[main_scene_name];
//spawn_requested_events.send(SpawnRequestedEvent { what: "enemy".into(), position, amount: 1, spawner_id: None }); //spawn_requested_events.send(SpawnRequestedEvent { what: "enemy".into(), position, amount: 1, spawner_id: None });
let child_scene = commands.spawn( let child_scene = commands
( .spawn((
SceneBundle { SceneBundle {
scene: scene.clone(), scene: scene.clone(),
transform: global_transform.clone(), transform: global_transform.clone(),
@ -79,8 +90,9 @@ pub(crate) fn spawn_from_blueprints(
named_animations: gltf.named_animations.clone(), named_animations: gltf.named_animations.clone(),
// animations: gltf.named_animations.values().clone() // animations: gltf.named_animations.values().clone()
},*/ },*/
Original(entity) Original(entity),
)).id(); ))
.id();
commands.entity(world).add_child(child_scene); commands.entity(world).add_child(child_scene);
} }
} }

View File

@ -4,9 +4,8 @@ use bevy::utils::HashMap;
use super::{CloneEntity, SpawnHere}; use super::{CloneEntity, SpawnHere};
use super::{Original, SpawnedRoot}; use super::{Original, SpawnedRoot};
// FIXME: move to more relevant module // FIXME: move to more relevant module
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub struct AnimationHelper { pub struct AnimationHelper {
pub named_animations: HashMap<String, Handle<AnimationClip>>, pub named_animations: HashMap<String, Handle<AnimationClip>>,
@ -16,8 +15,6 @@ pub struct AnimationHelper {
/// FlagComponent for dynamically spawned scenes /// FlagComponent for dynamically spawned scenes
pub(crate) struct SpawnedRootProcessed; pub(crate) struct SpawnedRootProcessed;
/// this system updates the first (and normally only) child of a scene flaged SpawnedRoot /// this system updates the first (and normally only) child of a scene flaged SpawnedRoot
/// - adds a name based on parent component (spawned scene) which is named on the scene name/prefab to be instanciated /// - adds a name based on parent component (spawned scene) which is named on the scene name/prefab to be instanciated
/// - adds the initial physics impulse (FIXME: we would need to add a temporary physics component to those who do not have it) /// - adds the initial physics impulse (FIXME: we would need to add a temporary physics component to those who do not have it)
@ -27,12 +24,15 @@ pub(crate) struct SpawnedRootProcessed;
// it might be due to how we add components to the PARENT item in gltf to components // it might be due to how we add components to the PARENT item in gltf to components
pub(crate) fn update_spawned_root_first_child( pub(crate) fn update_spawned_root_first_child(
// all_children: Query<(Entity, &Children)>, // all_children: Query<(Entity, &Children)>,
unprocessed_entities :Query<(Entity, &Children, &Name, &Parent, &Original ), (With<SpawnedRoot>, Without<SpawnedRootProcessed>)>, unprocessed_entities: Query<
(Entity, &Children, &Name, &Parent, &Original),
(With<SpawnedRoot>, Without<SpawnedRootProcessed>),
>,
mut commands: Commands, mut commands: Commands,
// FIXME: should be done at a more generic gltf level // FIXME: should be done at a more generic gltf level
animation_helpers: Query<&AnimationHelper>, animation_helpers: Query<&AnimationHelper>,
added_animation_helpers : Query<(Entity, &AnimationPlayer), Added<AnimationPlayer>> added_animation_helpers: Query<(Entity, &AnimationPlayer), Added<AnimationPlayer>>,
) { ) {
/* /*
currently we have currently we have
@ -71,7 +71,6 @@ pub(crate) fn update_spawned_root_first_child(
// use this https://rust-random.github.io/book/guide-seeding.html#a-simple-number, blenders seeds are also uInts // use this https://rust-random.github.io/book/guide-seeding.html#a-simple-number, blenders seeds are also uInts
// also this is not something we want every time, this should be a settable parameter when requesting a spawn // also this is not something we want every time, this should be a settable parameter when requesting a spawn
// add missing name of entity, based on the wrapper's name // add missing name of entity, based on the wrapper's name
let name = name.clone().replace("scene_wrapper_", ""); let name = name.clone().replace("scene_wrapper_", "");
@ -85,7 +84,6 @@ pub(crate) fn update_spawned_root_first_child(
// flag the spawned_root as being processed // flag the spawned_root as being processed
commands.entity(scene_instance).insert(SpawnedRootProcessed); commands.entity(scene_instance).insert(SpawnedRootProcessed);
// let original_transforms = // let original_transforms =
// parent is either the world or an entity with a marker (BlueprintName) // parent is either the world or an entity with a marker (BlueprintName)
commands.entity(parent.get()).add_child(*root_entity); commands.entity(parent.get()).add_child(*root_entity);
@ -98,12 +96,11 @@ pub(crate) fn update_spawned_root_first_child(
// println!("WE HAVE SOME ADDED ANIMATION PLAYERS {:?}", matching_animation_helper); // println!("WE HAVE SOME ADDED ANIMATION PLAYERS {:?}", matching_animation_helper);
if let Ok(anim_helper) = matching_animation_helper { if let Ok(anim_helper) = matching_animation_helper {
for (added, _) in added_animation_helpers.iter() { for (added, _) in added_animation_helpers.iter() {
commands.entity(added).insert( commands.entity(added).insert(AnimationHelper {
AnimationHelper{ // TODO: insert this at the ENTITY level, not the scene level // TODO: insert this at the ENTITY level, not the scene level
named_animations: anim_helper.named_animations.clone(), named_animations: anim_helper.named_animations.clone(),
// animations: gltf.named_animations.values().clone() // animations: gltf.named_animations.values().clone()
}, });
);
} }
} }
@ -122,10 +119,11 @@ pub(crate) fn update_spawned_root_first_child(
pub(crate) fn cleanup_scene_instances( pub(crate) fn cleanup_scene_instances(
scene_instances: Query<(Entity, &Children), With<SpawnedRootProcessed>>, scene_instances: Query<(Entity, &Children), With<SpawnedRootProcessed>>,
without_children: Query<Entity, (With<SpawnedRootProcessed>, Without<Children>)>, // if there are not children left, bevy removes Children ? without_children: Query<Entity, (With<SpawnedRootProcessed>, Without<Children>)>, // if there are not children left, bevy removes Children ?
mut commands: Commands mut commands: Commands,
) { ) {
for (entity, children) in scene_instances.iter() { for (entity, children) in scene_instances.iter() {
if children.len() == 0{ // it seems this does not happen ? if children.len() == 0 {
// it seems this does not happen ?
info!("cleaning up emptied spawned scene instance"); info!("cleaning up emptied spawned scene instance");
commands.entity(entity).despawn_recursive(); commands.entity(entity).despawn_recursive();
} }

View File

@ -3,13 +3,13 @@ use core::ops::Deref;
use ron::Value; use ron::Value;
use serde::de::DeserializeSeed; use serde::de::DeserializeSeed;
use bevy::prelude::{ResMut, Assets, info, debug, Name, Parent, warn};
use bevy::ecs::{entity::Entity, reflect::ReflectComponent}; use bevy::ecs::{entity::Entity, reflect::ReflectComponent};
use bevy::gltf::{Gltf, GltfExtras};
use bevy::prelude::{debug, info, warn, Assets, Name, Parent, ResMut};
use bevy::reflect::serde::UntypedReflectDeserializer;
use bevy::reflect::{Reflect, TypeInfo, TypeRegistryInternal};
use bevy::scene::Scene; use bevy::scene::Scene;
use bevy::utils::HashMap; use bevy::utils::HashMap;
use bevy::reflect::serde::UntypedReflectDeserializer;
use bevy::reflect::{TypeRegistryInternal, TypeInfo, Reflect};
use bevy::gltf::{Gltf, GltfExtras};
use super::capitalize_first_letter; use super::capitalize_first_letter;
@ -18,7 +18,7 @@ pub fn gltf_extras_to_components(
gltf: &mut Gltf, gltf: &mut Gltf,
scenes: &mut ResMut<Assets<Scene>>, scenes: &mut ResMut<Assets<Scene>>,
type_registry: impl Deref<Target = TypeRegistryInternal>, type_registry: impl Deref<Target = TypeRegistryInternal>,
gltf_name: &str gltf_name: &str,
) { ) {
let mut added_components = 0; let mut added_components = 0;
for (_name, scene) in &gltf.named_scenes { for (_name, scene) in &gltf.named_scenes {
@ -59,8 +59,6 @@ pub fn gltf_extras_to_components(
updated_components.push(component.clone_value()); updated_components.push(component.clone_value());
} }
entity_components.insert(target_entity, updated_components); entity_components.insert(target_entity, updated_components);
} else { } else {
entity_components.insert(target_entity, reflect_components); entity_components.insert(target_entity, reflect_components);
} }
@ -90,8 +88,7 @@ pub fn gltf_extras_to_components(
.unwrap() // Component was successfully deserialized, it has to be in the registry .unwrap() // Component was successfully deserialized, it has to be in the registry
.data::<ReflectComponent>() .data::<ReflectComponent>()
.unwrap() // Hopefully, the component deserializer ensures those are components .unwrap() // Hopefully, the component deserializer ensures those are components
.insert(&mut entity_mut, &*component) .insert(&mut entity_mut, &*component);
;
// info!("all components {:?}", scene.world.entity(entity).archetype().components()); // info!("all components {:?}", scene.world.entity(entity).archetype().components());
// scene.world.components(). // scene.world.components().
@ -111,7 +108,7 @@ pub fn gltf_extras_to_components(
pub fn ronstring_to_reflect_component( pub fn ronstring_to_reflect_component(
ron_string: &String, ron_string: &String,
type_registry: &TypeRegistryInternal type_registry: &TypeRegistryInternal,
) -> Vec<Box<dyn Reflect>> { ) -> Vec<Box<dyn Reflect>> {
let lookup: HashMap<String, Value> = ron::from_str(ron_string.as_str()).unwrap(); let lookup: HashMap<String, Value> = ron::from_str(ron_string.as_str()).unwrap();
let mut components: Vec<Box<dyn Reflect>> = Vec::new(); let mut components: Vec<Box<dyn Reflect>> = Vec::new();
@ -124,18 +121,20 @@ pub fn gltf_extras_to_components(
Value::String(str) => { Value::String(str) => {
parsed_value = str; parsed_value = str;
} }
_=> { _ => parsed_value = ron::to_string(&value).unwrap().to_string(),
parsed_value = ron::to_string(&value).unwrap().to_string()
}
} }
if let Some(type_registration) = type_registry.get_with_short_name(capitalized_type_name.as_str()) { if let Some(type_registration) =
type_registry.get_with_short_name(capitalized_type_name.as_str())
{
// println!("TYPE INFO {:?}", type_registration.type_info()); // println!("TYPE INFO {:?}", type_registration.type_info());
match type_registration.type_info() { match type_registration.type_info() {
TypeInfo::TupleStruct(info) => { TypeInfo::TupleStruct(info) => {
// we handle tupple strucs with only one field differently, as Blender's custom properties with custom ui (float, int, bool, etc) always give us a tupple struct // we handle tupple strucs with only one field differently, as Blender's custom properties with custom ui (float, int, bool, etc) always give us a tupple struct
if info.field_len() == 1 { if info.field_len() == 1 {
let field = info.field_at(0).expect("we should always have at least one field here"); let field = info
.field_at(0)
.expect("we should always have at least one field here");
let field_name = field.type_name(); let field_name = field.type_name();
// TODO: find a way to cast with typeId instead of this matching // TODO: find a way to cast with typeId instead of this matching
/*match field.type_id(){ /*match field.type_id(){
@ -179,22 +178,28 @@ pub fn gltf_extras_to_components(
} }
"glam::f32::vec3::Vec3" => { "glam::f32::vec3::Vec3" => {
let parsed: Vec<f32> = ron::from_str(&parsed_value).unwrap(); let parsed: Vec<f32> = ron::from_str(&parsed_value).unwrap();
formated = format!("(x:{},y:{},z:{})", parsed[0], parsed[1], parsed[2]); formated =
}, format!("(x:{},y:{},z:{})", parsed[0], parsed[1], parsed[2]);
}
"bevy_render::color::Color" => { "bevy_render::color::Color" => {
let parsed: Vec<f32> = ron::from_str(&parsed_value).unwrap(); let parsed: Vec<f32> = ron::from_str(&parsed_value).unwrap();
if parsed.len() == 3 { if parsed.len() == 3 {
formated = format!("Rgba(red:{},green:{},blue:{}, alpha: 1.0)", parsed[0], parsed[1], parsed[2]); formated = format!(
"Rgba(red:{},green:{},blue:{}, alpha: 1.0)",
parsed[0], parsed[1], parsed[2]
);
} }
if parsed.len() == 4 { if parsed.len() == 4 {
formated = format!("Rgba(red:{},green:{},blue:{}, alpha:{})", parsed[0], parsed[1], parsed[2], parsed[3]); formated = format!(
"Rgba(red:{},green:{},blue:{}, alpha:{})",
parsed[0], parsed[1], parsed[2], parsed[3]
);
} }
} }
_ => {} _ => {}
} }
parsed_value = format!("({formated})"); parsed_value = format!("({formated})");
} }
} }
_ => {} _ => {}
@ -205,7 +210,8 @@ pub fn gltf_extras_to_components(
parsed_value = "()".to_string(); parsed_value = "()".to_string();
} }
let ron_string = format!("{{ \"{}\":{} }}", let ron_string = format!(
"{{ \"{}\":{} }}",
type_registration.type_name(), type_registration.type_name(),
parsed_value parsed_value
); );
@ -220,7 +226,13 @@ pub fn gltf_extras_to_components(
// println!("component data ron string {}", ron_string); // println!("component data ron string {}", ron_string);
let mut deserializer = ron::Deserializer::from_str(ron_string.as_str()).unwrap(); let mut deserializer = ron::Deserializer::from_str(ron_string.as_str()).unwrap();
let reflect_deserializer = UntypedReflectDeserializer::new(type_registry); let reflect_deserializer = UntypedReflectDeserializer::new(type_registry);
let component = reflect_deserializer.deserialize(&mut deserializer).expect(format!("failed to deserialize component {} with value: {:?}", key, value).as_str()); let component = reflect_deserializer.deserialize(&mut deserializer).expect(
format!(
"failed to deserialize component {} with value: {:?}",
key, value
)
.as_str(),
);
components.push(component); components.push(component);
debug!("found type registration for {}", capitalized_type_name); debug!("found type registration for {}", capitalized_type_name);
@ -230,4 +242,3 @@ pub fn gltf_extras_to_components(
} }
components components
} }

View File

@ -7,10 +7,7 @@ pub use gltf_to_components::*;
pub mod process_gltfs; pub mod process_gltfs;
pub use process_gltfs::*; pub use process_gltfs::*;
use bevy::prelude::{ use bevy::prelude::{App, IntoSystemConfigs, Plugin, SystemSet, Update};
App,Plugin, Update, SystemSet, IntoSystemConfigs
};
/// A Bevy plugin for extracting components from gltf files and automatically adding them to the relevant entities /// A Bevy plugin for extracting components from gltf files and automatically adding them to the relevant entities
/// It will automatically run every time you load a gltf file /// It will automatically run every time you load a gltf file
@ -45,30 +42,21 @@ use bevy::prelude::{
///} ///}
/// ``` /// ```
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
/// systemset to order your systems after the component injection when needed /// systemset to order your systems after the component injection when needed
pub enum GltfComponentsSet { pub enum GltfComponentsSet {
Injection, Injection,
} }
#[derive(Default)] #[derive(Default)]
pub struct ComponentsFromGltfPlugin; pub struct ComponentsFromGltfPlugin;
impl Plugin for ComponentsFromGltfPlugin { impl Plugin for ComponentsFromGltfPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.insert_resource(GltfLoadingTracker::new())
.insert_resource(GltfLoadingTracker::new()) .add_systems(Update, (track_new_gltf, process_loaded_scenes))
.add_systems(
.add_systems(Update, ( Update,
track_new_gltf, (process_loaded_scenes).in_set(GltfComponentsSet::Injection),
process_loaded_scenes, );
))
.add_systems(Update,
(process_loaded_scenes)
.in_set(GltfComponentsSet::Injection)
)
;
} }
} }

View File

@ -1,6 +1,6 @@
use bevy::utils::HashSet;
use bevy::{prelude::*, asset::LoadState};
use bevy::gltf::Gltf; use bevy::gltf::Gltf;
use bevy::utils::HashSet;
use bevy::{asset::LoadState, prelude::*};
use super::gltf_extras_to_components; use super::gltf_extras_to_components;
@ -8,14 +8,14 @@ use super::gltf_extras_to_components;
/// component to keep track of gltfs' loading state /// component to keep track of gltfs' loading state
pub struct GltfLoadingTracker { pub struct GltfLoadingTracker {
pub loading_gltfs: HashSet<Handle<Gltf>>, pub loading_gltfs: HashSet<Handle<Gltf>>,
pub loaded_gltfs: HashSet<Handle<Gltf>> pub loaded_gltfs: HashSet<Handle<Gltf>>,
} }
impl GltfLoadingTracker { impl GltfLoadingTracker {
pub fn new() -> GltfLoadingTracker { pub fn new() -> GltfLoadingTracker {
GltfLoadingTracker { GltfLoadingTracker {
loaded_gltfs: HashSet::new(), loaded_gltfs: HashSet::new(),
loading_gltfs: HashSet::new() loading_gltfs: HashSet::new(),
} }
} }
pub fn add_scene(&mut self, handle: Handle<Gltf>) { pub fn add_scene(&mut self, handle: Handle<Gltf>) {
@ -23,7 +23,6 @@ pub struct GltfLoadingTracker{
} }
} }
pub fn track_new_gltf( pub fn track_new_gltf(
mut tracker: ResMut<GltfLoadingTracker>, mut tracker: ResMut<GltfLoadingTracker>,
mut events: EventReader<AssetEvent<Gltf>>, mut events: EventReader<AssetEvent<Gltf>>,
@ -43,12 +42,13 @@ pub struct GltfLoadingTracker{
mut tracker: ResMut<GltfLoadingTracker>, mut tracker: ResMut<GltfLoadingTracker>,
app_type_registry: Res<AppTypeRegistry>, app_type_registry: Res<AppTypeRegistry>,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
) { ) {
let mut loaded_gltfs = Vec::new(); let mut loaded_gltfs = Vec::new();
for gltf in &tracker.loading_gltfs { for gltf in &tracker.loading_gltfs {
info!("checking for loaded gltfs {:?}", asset_server.get_load_state(gltf)); info!(
"checking for loaded gltfs {:?}",
asset_server.get_load_state(gltf)
);
if asset_server.get_load_state(gltf.clone()) == LoadState::Loaded { if asset_server.get_load_state(gltf.clone()) == LoadState::Loaded {
debug!("Adding scene to processing list"); debug!("Adding scene to processing list");
@ -60,14 +60,12 @@ pub struct GltfLoadingTracker{
for gltf_handle in &loaded_gltfs { for gltf_handle in &loaded_gltfs {
if let Some(gltf) = gltfs.get_mut(gltf_handle) { if let Some(gltf) = gltfs.get_mut(gltf_handle) {
// TODO this is a temporary workaround for library management // TODO this is a temporary workaround for library management
if let Some(asset_path) = asset_server.get_handle_path(gltf_handle) { if let Some(asset_path) = asset_server.get_handle_path(gltf_handle) {
let gltf_name = asset_path.path().file_stem().unwrap().to_str().unwrap(); let gltf_name = asset_path.path().file_stem().unwrap().to_str().unwrap();
gltf_extras_to_components(gltf, &mut scenes, &*type_registry, gltf_name); gltf_extras_to_components(gltf, &mut scenes, &*type_registry, gltf_name);
//gltf_extras_to_prefab_infos(gltf, &mut scenes, &*type_registry, gltf_name); //gltf_extras_to_prefab_infos(gltf, &mut scenes, &*type_registry, gltf_name);
} } else {
else {
gltf_extras_to_components(gltf, &mut scenes, &*type_registry, ""); gltf_extras_to_components(gltf, &mut scenes, &*type_registry, "");
} }
} }
@ -75,6 +73,4 @@ pub struct GltfLoadingTracker{
tracker.loaded_gltfs.insert(gltf_handle.clone()); tracker.loaded_gltfs.insert(gltf_handle.clone());
debug!("Done loading scene"); debug!("Done loading scene");
} }
} }

View File

@ -1,4 +1,3 @@
pub fn capitalize_first_letter(s: &str) -> String { pub fn capitalize_first_letter(s: &str) -> String {
s[0..1].to_uppercase() + &s[1..] s[0..1].to_uppercase() + &s[1..]
} }

View File

@ -2,6 +2,4 @@ use bevy::prelude::*;
use bevy_asset_loader::prelude::*; use bevy_asset_loader::prelude::*;
#[derive(AssetCollection, Resource)] #[derive(AssetCollection, Resource)]
pub struct CoreAssets { pub struct CoreAssets {}
}

View File

@ -7,28 +7,29 @@ pub use assets_game::*;
use bevy::prelude::*; use bevy::prelude::*;
use bevy_asset_loader::prelude::*; use bevy_asset_loader::prelude::*;
use crate::state::{AppState}; use crate::state::AppState;
pub struct AssetsPlugin; pub struct AssetsPlugin;
impl Plugin for AssetsPlugin { impl Plugin for AssetsPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app
// load core assets (ie assets needed in the main menu, and everywhere else before loading more assets in game) // load core assets (ie assets needed in the main menu, and everywhere else before loading more assets in game)
.add_loading_state(LoadingState::new(AppState::CoreLoading).continue_to_state(AppState::MenuRunning)) .add_loading_state(
LoadingState::new(AppState::CoreLoading).continue_to_state(AppState::MenuRunning),
)
.add_dynamic_collection_to_loading_state::<_, StandardDynamicAssetCollection>( .add_dynamic_collection_to_loading_state::<_, StandardDynamicAssetCollection>(
AppState::CoreLoading, AppState::CoreLoading,
"advanced/assets_core.assets.ron", "advanced/assets_core.assets.ron",
) )
.add_collection_to_loading_state::<_, CoreAssets>(AppState::CoreLoading) .add_collection_to_loading_state::<_, CoreAssets>(AppState::CoreLoading)
// load game assets // load game assets
.add_loading_state(LoadingState::new(AppState::AppLoading).continue_to_state(AppState::AppRunning)) .add_loading_state(
LoadingState::new(AppState::AppLoading).continue_to_state(AppState::AppRunning),
)
.add_dynamic_collection_to_loading_state::<_, StandardDynamicAssetCollection>( .add_dynamic_collection_to_loading_state::<_, StandardDynamicAssetCollection>(
AppState::AppLoading, AppState::AppLoading,
"advanced/assets_game.assets.ron", "advanced/assets_game.assets.ron",
) )
.add_collection_to_loading_state::<_, GameAssets>(AppState::AppLoading) .add_collection_to_loading_state::<_, GameAssets>(AppState::AppLoading);
;
} }
} }

View File

@ -1,7 +1,6 @@
use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings};
use bevy::core_pipeline::tonemapping::{DebandDither, Tonemapping};
use bevy::prelude::*; use bevy::prelude::*;
use bevy::core_pipeline::bloom::{BloomSettings, BloomCompositeMode};
use bevy::core_pipeline::tonemapping::{Tonemapping, DebandDither};
use super::CameraTrackingOffset; use super::CameraTrackingOffset;
@ -9,26 +8,17 @@ pub fn camera_replace_proxies (
mut commands: Commands, mut commands: Commands,
mut added_cameras: Query<(Entity, &mut Camera), (Added<Camera>, With<CameraTrackingOffset>)>, mut added_cameras: Query<(Entity, &mut Camera), (Added<Camera>, With<CameraTrackingOffset>)>,
) { ) {
for (entity, mut camera) in added_cameras.iter_mut() { for (entity, mut camera) in added_cameras.iter_mut() {
info!("detected added camera, updating proxy"); info!("detected added camera, updating proxy");
camera.hdr = true; camera.hdr = true;
commands.entity(entity) commands
.insert( .entity(entity)
DebandDither::Enabled .insert(DebandDither::Enabled)
) .insert(Tonemapping::BlenderFilmic)
.insert( .insert(BloomSettings {
Tonemapping::BlenderFilmic
)
.insert(
BloomSettings{
intensity: 0.01, intensity: 0.01,
composite_mode: BloomCompositeMode::Additive, composite_mode: BloomCompositeMode::Additive,
..default() ..default()
} });
)
;
} }
} }

View File

@ -1,19 +1,19 @@
use bevy::prelude::*; use bevy::prelude::*;
#[derive(Component, Reflect, Debug)] #[derive(Component, Reflect, Debug)]
#[reflect(Component)] #[reflect(Component)]
/// Component for cameras, with an offset from the Trackable target /// Component for cameras, with an offset from the Trackable target
/// ///
pub struct CameraTracking { pub struct CameraTracking {
pub offset: Vec3 pub offset: Vec3,
} }
impl Default for CameraTracking { impl Default for CameraTracking {
fn default() -> Self { fn default() -> Self {
CameraTracking { offset: Vec3::new(0.0, 6.0, 8.0) } CameraTracking {
offset: Vec3::new(0.0, 6.0, 8.0),
}
} }
} }
#[derive(Component, Reflect, Debug, Deref, DerefMut)] #[derive(Component, Reflect, Debug, Deref, DerefMut)]
#[reflect(Component)] #[reflect(Component)]
@ -31,27 +31,28 @@ impl CameraTrackingOffset {
} }
} }
#[derive(Component, Reflect, Default, Debug)]
#[derive(Component, Reflect, Default, Debug, )]
#[reflect(Component)] #[reflect(Component)]
/// Add this component to an entity if you want it to be tracked by a Camera /// Add this component to an entity if you want it to be tracked by a Camera
pub struct CameraTrackable; pub struct CameraTrackable;
pub fn camera_track( pub fn camera_track(
mut tracking_cameras: Query<(&mut Transform, &CameraTrackingOffset), (With<Camera>, With<CameraTrackingOffset>, Without<CameraTrackable>)>, mut tracking_cameras: Query<
(&mut Transform, &CameraTrackingOffset),
(
With<Camera>,
With<CameraTrackingOffset>,
Without<CameraTrackable>,
),
>,
camera_tracked: Query<&Transform, With<CameraTrackable>>, camera_tracked: Query<&Transform, With<CameraTrackable>>,
) { ) {
for (mut camera_transform, tracking_offset) in tracking_cameras.iter_mut() { for (mut camera_transform, tracking_offset) in tracking_cameras.iter_mut() {
for tracked_transform in camera_tracked.iter() { for tracked_transform in camera_tracked.iter() {
let target_position = tracked_transform.translation + tracking_offset.0; let target_position = tracked_transform.translation + tracking_offset.0;
let eased_position = camera_transform.translation.lerp(target_position, 0.1); let eased_position = camera_transform.translation.lerp(target_position, 0.1);
camera_transform.translation = eased_position; // + tracking.offset;// tracked_transform.translation + tracking.offset; camera_transform.translation = eased_position; // + tracking.offset;// tracked_transform.translation + tracking.offset;
*camera_transform = camera_transform.looking_at(tracked_transform.translation, Vec3::Y); *camera_transform = camera_transform.looking_at(tracked_transform.translation, Vec3::Y);
} }
} }
} }

View File

@ -10,17 +10,15 @@ use bevy_gltf_blueprints::GltfBlueprintsSet;
pub struct CameraPlugin; pub struct CameraPlugin;
impl Plugin for CameraPlugin { impl Plugin for CameraPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.register_type::<CameraTrackable>()
.register_type::<CameraTrackable>()
.register_type::<CameraTracking>() .register_type::<CameraTracking>()
.register_type::<CameraTrackingOffset>() .register_type::<CameraTrackingOffset>()
.add_systems(
.add_systems(Update, Update,
( (
camera_replace_proxies.after(GltfBlueprintsSet::AfterSpawn), camera_replace_proxies.after(GltfBlueprintsSet::AfterSpawn),
camera_track, camera_track,
) ),
) );
;
} }
} }

View File

@ -1,15 +1,13 @@
use bevy::prelude::*; use bevy::prelude::*;
use bevy::pbr::{CascadeShadowConfigBuilder, CascadeShadowConfig}; use bevy::pbr::{CascadeShadowConfig, CascadeShadowConfigBuilder};
// fixme might be too specific to might needs, should it be moved out ? also these are all for lights, not models // fixme might be too specific to might needs, should it be moved out ? also these are all for lights, not models
pub fn lighting_replace_proxies( pub fn lighting_replace_proxies(
mut added_dirights: Query<(Entity, &mut DirectionalLight), Added<DirectionalLight>>, mut added_dirights: Query<(Entity, &mut DirectionalLight), Added<DirectionalLight>>,
mut added_spotlights: Query<&mut SpotLight, Added<SpotLight>>, mut added_spotlights: Query<&mut SpotLight, Added<SpotLight>>,
mut commands: Commands, mut commands: Commands,
) { ) {
for (entity, mut light) in added_dirights.iter_mut() { for (entity, mut light) in added_dirights.iter_mut() {
light.illuminance *= 5.0; light.illuminance *= 5.0;
light.shadows_enabled = true; light.shadows_enabled = true;
@ -19,11 +17,9 @@ pub fn lighting_replace_proxies(
..default() ..default()
} }
.into(); .into();
commands.entity(entity) commands.entity(entity).insert(shadow_config);
.insert(shadow_config);
} }
for mut light in added_spotlights.iter_mut() { for mut light in added_spotlights.iter_mut() {
light.shadows_enabled = true; light.shadows_enabled = true;
} }
} }

View File

@ -1,8 +1,8 @@
mod lighting_replace_proxies; mod lighting_replace_proxies;
use lighting_replace_proxies::*; use lighting_replace_proxies::*;
use bevy::pbr::{DirectionalLightShadowMap, NotShadowCaster};
use bevy::prelude::*; use bevy::prelude::*;
use bevy::pbr::{NotShadowCaster, DirectionalLightShadowMap};
pub struct LightingPlugin; pub struct LightingPlugin;
impl Plugin for LightingPlugin { impl Plugin for LightingPlugin {

View File

@ -22,14 +22,11 @@ use bevy_gltf_blueprints::*;
use rand::Rng; use rand::Rng;
fn spawn_test( fn spawn_test(
keycode: Res<Input<KeyCode>>, keycode: Res<Input<KeyCode>>,
mut commands: Commands, mut commands: Commands,
mut game_world: Query<(Entity, &Children), With<GameWorldTag>>, mut game_world: Query<(Entity, &Children), With<GameWorldTag>>,
) { ) {
if keycode.just_pressed(KeyCode::T) { if keycode.just_pressed(KeyCode::T) {
let world = game_world.single_mut(); let world = game_world.single_mut();
@ -40,17 +37,16 @@ fn spawn_test(
let x: f32 = rng.gen_range(-range..range); let x: f32 = rng.gen_range(-range..range);
let y: f32 = rng.gen_range(-range..range); let y: f32 = rng.gen_range(-range..range);
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let range = 0.8; let range = 0.8;
let vel_x: f32 = rng.gen_range(-range..range); let vel_x: f32 = rng.gen_range(-range..range);
let vel_y: f32 = rng.gen_range(2.0..2.5); let vel_y: f32 = rng.gen_range(2.0..2.5);
let vel_z: f32 = rng.gen_range(-range..range); let vel_z: f32 = rng.gen_range(-range..range);
let name_index: u64 = rng.gen(); let name_index: u64 = rng.gen();
let new_entity = commands.spawn(( let new_entity = commands
.spawn((
BluePrintBundle { BluePrintBundle {
blueprint: BlueprintName("Health_Pickup".to_string()), blueprint: BlueprintName("Health_Pickup".to_string()),
transform: TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)), transform: TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)),
@ -60,12 +56,12 @@ fn spawn_test(
// BlueprintName("Health_Pickup".to_string()), // BlueprintName("Health_Pickup".to_string()),
// SpawnHere, // SpawnHere,
// TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)), // TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)),
Velocity { Velocity {
linvel: Vec3::new(vel_x, vel_y, vel_z), linvel: Vec3::new(vel_x, vel_y, vel_z),
angvel: Vec3::new(0.0, 0.0, 0.0), angvel: Vec3::new(0.0, 0.0, 0.0),
}, },
)).id(); ))
.id();
commands.entity(world).add_child(new_entity); commands.entity(world).add_child(new_entity);
} }
} }
@ -73,22 +69,16 @@ fn spawn_test(
pub struct CorePlugin; pub struct CorePlugin;
impl Plugin for CorePlugin { impl Plugin for CorePlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.add_plugins((
.add_plugins((
LightingPlugin, LightingPlugin,
CameraPlugin, CameraPlugin,
PhysicsPlugin, PhysicsPlugin,
SaveLoadPlugin, SaveLoadPlugin,
BlueprintsPlugin { BlueprintsPlugin {
library_folder: "advanced/models/library".into() library_folder: "advanced/models/library".into(),
} },
)) ))
// just for testing // just for testing
.add_systems( .add_systems(Update, spawn_test);
Update,
spawn_test
)
;
} }
} }

View File

@ -1,4 +1,4 @@
use bevy::prelude::{ResMut, info}; use bevy::prelude::{info, ResMut};
use bevy_rapier3d::prelude::RapierConfiguration; use bevy_rapier3d::prelude::RapierConfiguration;
pub fn pause_physics(mut physics_config: ResMut<RapierConfiguration>) { pub fn pause_physics(mut physics_config: ResMut<RapierConfiguration>) {

View File

@ -6,33 +6,24 @@ pub mod utils;
pub mod controls; pub mod controls;
pub use controls::*; pub use controls::*;
use bevy::prelude::*;
use crate::state::GameState; use crate::state::GameState;
use bevy::prelude::*;
// use super::blueprints::GltfBlueprintsSet; // use super::blueprints::GltfBlueprintsSet;
use bevy_gltf_blueprints::GltfBlueprintsSet; use bevy_gltf_blueprints::GltfBlueprintsSet;
// use crate::Collider; // use crate::Collider;
pub struct PhysicsPlugin; pub struct PhysicsPlugin;
impl Plugin for PhysicsPlugin { impl Plugin for PhysicsPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.register_type::<AutoAABBCollider>()
.register_type::<AutoAABBCollider>()
.register_type::<physics_replace_proxies::Collider>() .register_type::<physics_replace_proxies::Collider>()
// find a way to make serde's stuff serializable // find a way to make serde's stuff serializable
// .register_type::<bevy_rapier3d::dynamics::CoefficientCombineRule>() // .register_type::<bevy_rapier3d::dynamics::CoefficientCombineRule>()
//bevy_rapier3d::dynamics::CoefficientCombineRule //bevy_rapier3d::dynamics::CoefficientCombineRule
.add_systems(Update, physics_replace_proxies.after(GltfBlueprintsSet::AfterSpawn))
.add_systems( .add_systems(
OnEnter(GameState::InGame), Update,
resume_physics physics_replace_proxies.after(GltfBlueprintsSet::AfterSpawn),
) )
.add_systems( .add_systems(OnEnter(GameState::InGame), resume_physics)
OnExit(GameState::InGame), .add_systems(OnExit(GameState::InGame), pause_physics);
pause_physics
)
;
} }
} }

View File

@ -1,11 +1,11 @@
use bevy::prelude::*; use bevy::prelude::*;
// use bevy::render::primitives::Aabb; // use bevy::render::primitives::Aabb;
use bevy_rapier3d::geometry::Collider as RapierCollider; use bevy_rapier3d::geometry::Collider as RapierCollider;
use bevy_rapier3d::prelude::{ComputedColliderShape, ActiveEvents, ActiveCollisionTypes}; use bevy_rapier3d::prelude::{ActiveCollisionTypes, ActiveEvents, ComputedColliderShape};
use super::utils::*; use super::utils::*;
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub enum Collider { pub enum Collider {
Ball(f32), Ball(f32),
@ -15,21 +15,23 @@ pub enum Collider {
Mesh, Mesh,
} }
#[derive(Component, Reflect, Default, Debug)]
#[derive(Component, Reflect, Default, Debug, )]
#[reflect(Component)] #[reflect(Component)]
pub enum AutoAABBCollider { pub enum AutoAABBCollider {
#[default] #[default]
Cuboid, Cuboid,
Ball, Ball,
Capsule Capsule,
} }
// replaces all physics stand-ins with the actual rapier types // replaces all physics stand-ins with the actual rapier types
pub fn physics_replace_proxies( pub fn physics_replace_proxies(
meshes: Res<Assets<Mesh>>, meshes: Res<Assets<Mesh>>,
mesh_handles: Query<&Handle<Mesh>>, mesh_handles: Query<&Handle<Mesh>>,
mut proxy_colliders: Query<(Entity, &Collider, &Name, &mut Visibility), (Without<RapierCollider>, Added<Collider>)>, mut proxy_colliders: Query<
(Entity, &Collider, &Name, &mut Visibility),
(Without<RapierCollider>, Added<Collider>),
>,
// needed for tri meshes // needed for tri meshes
children: Query<&Children>, children: Query<&Children>,
@ -70,15 +72,25 @@ pub fn physics_replace_proxies (
} }
Collider::Mesh => { Collider::Mesh => {
info!("generating collider from proxy: mesh"); info!("generating collider from proxy: mesh");
for (_, collider_mesh) in Mesh::search_in_children(entity, &children, &meshes, &mesh_handles) for (_, collider_mesh) in
Mesh::search_in_children(entity, &children, &meshes, &mesh_handles)
{ {
rapier_collider = RapierCollider::from_bevy_mesh(collider_mesh, &ComputedColliderShape::TriMesh).unwrap(); rapier_collider = RapierCollider::from_bevy_mesh(
commands.entity(entity) collider_mesh,
&ComputedColliderShape::TriMesh,
)
.unwrap();
commands
.entity(entity)
.insert(rapier_collider) .insert(rapier_collider)
// FIXME: this is just for demo purposes !!! // FIXME: this is just for demo purposes !!!
.insert(ActiveCollisionTypes::default() | ActiveCollisionTypes::KINEMATIC_STATIC | ActiveCollisionTypes::STATIC_STATIC | ActiveCollisionTypes::DYNAMIC_STATIC) .insert(
.insert(ActiveEvents::COLLISION_EVENTS) ActiveCollisionTypes::default()
; | ActiveCollisionTypes::KINEMATIC_STATIC
| ActiveCollisionTypes::STATIC_STATIC
| ActiveCollisionTypes::DYNAMIC_STATIC,
)
.insert(ActiveEvents::COLLISION_EVENTS);
// .insert(ActiveEvents::COLLISION_EVENTS) // .insert(ActiveEvents::COLLISION_EVENTS)
// break; // break;
// RapierCollider::convex_hull(points) // RapierCollider::convex_hull(points)

View File

@ -1,16 +1,15 @@
use bevy::prelude::*; use bevy::prelude::*;
pub fn insert_dependant_component<Dependant: Component, Dependency: Component+ std::default::Default>( pub fn insert_dependant_component<
Dependant: Component,
Dependency: Component + std::default::Default,
>(
mut commands: Commands, mut commands: Commands,
entities_without_depency: Query<(Entity, &Name), (With<Dependant>, Without<Dependency>)>, entities_without_depency: Query<(Entity, &Name), (With<Dependant>, Without<Dependency>)>,
) { ) {
for (entity, name) in entities_without_depency.iter() { for (entity, name) in entities_without_depency.iter() {
let name = name.clone().to_string(); let name = name.clone().to_string();
commands.entity(entity) commands.entity(entity).insert(Dependency::default());
.insert(
Dependency::default()
)
;
warn!("found an entity called {} with a {} component but without an {}, please check your assets", name.clone(), std::any::type_name::<Dependant>(), std::any::type_name::<Dependency>()); warn!("found an entity called {} with a {} component but without an {}, please check your assets", name.clone(), std::any::type_name::<Dependant>(), std::any::type_name::<Dependency>());
} }
} }

View File

@ -1,19 +1,19 @@
use bevy::prelude::*; use bevy::prelude::*;
use bevy_gltf_blueprints::{clone_entity::CloneEntity, SpawnHere, GameWorldTag}; use bevy_gltf_blueprints::{clone_entity::CloneEntity, GameWorldTag, SpawnHere};
use crate::{ use crate::{
assets::GameAssets, assets::GameAssets,
state::{InAppRunning, AppState, GameState} state::{AppState, GameState, InAppRunning},
}; };
use super::Saveable; use super::Saveable;
const SCENE_FILE_PATH: &str = "scenes/save.scn.ron"; const SCENE_FILE_PATH: &str = "scenes/save.scn.ron";
#[derive(Component, Debug, )] #[derive(Component, Debug)]
pub struct TempLoadedSceneMarker; pub struct TempLoadedSceneMarker;
#[derive(Component, Debug, )] #[derive(Component, Debug)]
pub struct SaveablesToRemove(Vec<(Entity, Name)>); pub struct SaveablesToRemove(Vec<(Entity, Name)>);
#[derive(Component, Event)] #[derive(Component, Event)]
@ -21,18 +21,14 @@ pub struct LoadRequest {
pub path: String, pub path: String,
} }
pub fn should_load(save_requested_events: EventReader<LoadRequest>) -> bool {
pub fn should_load( return save_requested_events.len() > 0;
save_requested_events: EventReader<LoadRequest>,
) -> bool {
return save_requested_events.len() > 0
} }
pub fn load_prepare( pub fn load_prepare(
mut next_app_state: ResMut<NextState<AppState>>, mut next_app_state: ResMut<NextState<AppState>>,
mut next_game_state: ResMut<NextState<GameState>>, mut next_game_state: ResMut<NextState<GameState>>,
) { ) {
next_app_state.set(AppState::LoadingGame); next_app_state.set(AppState::LoadingGame);
next_game_state.set(GameState::None); next_game_state.set(GameState::None);
info!("--loading: prepare") info!("--loading: prepare")
@ -53,10 +49,7 @@ pub fn _unload_world_old(world: &mut World) {
} }
} }
pub fn unload_world( pub fn unload_world(mut commands: Commands, gameworlds: Query<Entity, With<GameWorldTag>>) {
mut commands: Commands,
gameworlds: Query<Entity, With<GameWorldTag>>
){
for e in gameworlds.iter() { for e in gameworlds.iter() {
info!("--loading: despawn old world/level"); info!("--loading: despawn old world/level");
commands.entity(e).despawn_recursive(); commands.entity(e).despawn_recursive();
@ -78,25 +71,18 @@ pub fn load_world(
}, },
bevy::prelude::Name::from("world"), bevy::prelude::Name::from("world"),
GameWorldTag, GameWorldTag,
InAppRunning InAppRunning,
)); ));
} }
pub fn load_saved_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn((
pub fn load_saved_scene(
mut commands: Commands,
asset_server: Res<AssetServer>
) {
commands.spawn(
(
DynamicSceneBundle { DynamicSceneBundle {
// Scenes are loaded just like any other asset. // Scenes are loaded just like any other asset.
scene: asset_server.load(SCENE_FILE_PATH), scene: asset_server.load(SCENE_FILE_PATH),
..default() ..default()
}, },
TempLoadedSceneMarker TempLoadedSceneMarker,
)); ));
// commands.entity(world).add_child(child_scene); // commands.entity(world).add_child(child_scene);
info!("--loading: loaded saved scene"); info!("--loading: loaded saved scene");
@ -109,7 +95,7 @@ pub fn process_loaded_scene(
mut game_world: Query<(Entity, &Children), With<GameWorldTag>>, mut game_world: Query<(Entity, &Children), With<GameWorldTag>>,
saveables: Query<(Entity, &Name), With<Saveable>>, saveables: Query<(Entity, &Name), With<Saveable>>,
asset_server: Res<AssetServer> asset_server: Res<AssetServer>,
) { ) {
for (loaded_scene, children) in loaded_scene.iter() { for (loaded_scene, children) in loaded_scene.iter() {
info!("--loading: post processing loaded scene"); info!("--loading: post processing loaded scene");
@ -145,10 +131,9 @@ pub fn process_loaded_scene(
let world = game_world.single_mut(); let world = game_world.single_mut();
let world = world.1[0]; let world = world.1[0];
let new_entity = commands.spawn(( let new_entity = commands
bevy::prelude::Name::from(name.clone()), .spawn((bevy::prelude::Name::from(name.clone()), SpawnHere))
SpawnHere, .id();
)).id();
commands.add(CloneEntity { commands.add(CloneEntity {
source: source, source: source,
@ -157,17 +142,11 @@ pub fn process_loaded_scene(
commands.entity(world).add_child(new_entity); commands.entity(world).add_child(new_entity);
info!("copying data from {:?} to {:?}", source, new_entity); info!("copying data from {:?} to {:?}", source, new_entity);
} }
} }
} }
commands.spawn(SaveablesToRemove(entities_to_load.clone())); commands.spawn(SaveablesToRemove(entities_to_load.clone()));
// if an entity is present in the world but NOT in the saved entities , it should be removed from the world // if an entity is present in the world but NOT in the saved entities , it should be removed from the world
// ideally this should be run between spawning of the world/level AND spawn_placeholders // ideally this should be run between spawning of the world/level AND spawn_placeholders
@ -177,7 +156,6 @@ pub fn process_loaded_scene(
asset_server.mark_unused_assets(); asset_server.mark_unused_assets();
asset_server.free_unused_assets(); asset_server.free_unused_assets();
} }
//for saveable in saveables.iter(){ //for saveable in saveables.iter(){
// println!("SAVEABLE BEFORE {:?}", saveable) // println!("SAVEABLE BEFORE {:?}", saveable)
@ -190,10 +168,8 @@ pub fn final_cleanup(
saveables: Query<(Entity, &Name), With<Saveable>>, saveables: Query<(Entity, &Name), With<Saveable>>,
mut next_app_state: ResMut<NextState<AppState>>, mut next_app_state: ResMut<NextState<AppState>>,
mut next_game_state: ResMut<NextState<GameState>>, mut next_game_state: ResMut<NextState<GameState>>,
) { ) {
if let Ok((e, entities_to_load)) = saveables_to_remove.get_single() if let Ok((e, entities_to_load)) = saveables_to_remove.get_single() {
{
info!("saveables to remove {:?}", entities_to_load); info!("saveables to remove {:?}", entities_to_load);
for (e, n) in saveables.iter() { for (e, n) in saveables.iter() {
let mut found = false; let mut found = false;
@ -226,7 +202,6 @@ fn process_loaded_scene_load_alt(
entities: Query<(Entity, &Children), With<TempLoadedSceneMarker>>, entities: Query<(Entity, &Children), With<TempLoadedSceneMarker>>,
named_entities: Query<(Entity, &Name, &Parent)>, // FIXME: very inneficient named_entities: Query<(Entity, &Name, &Parent)>, // FIXME: very inneficient
mut commands: Commands, mut commands: Commands,
) { ) {
for (entity, children) in entities.iter() { for (entity, children) in entities.iter() {
let mut entities_to_load: Vec<(Entity, Name)> = vec![]; let mut entities_to_load: Vec<(Entity, Name)> = vec![];

View File

@ -10,13 +10,11 @@ pub mod loading;
pub use loading::*; pub use loading::*;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::prelude::{App, Plugin, IntoSystemConfigs}; use bevy::prelude::{App, IntoSystemConfigs, Plugin};
use bevy::utils::Uuid; use bevy::utils::Uuid;
use bevy_gltf_blueprints::GltfBlueprintsSet; use bevy_gltf_blueprints::GltfBlueprintsSet;
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub enum LoadingSet { pub enum LoadingSet {
Load, Load,
@ -67,7 +65,6 @@ impl Plugin for SaveLoadPlugin {
) )
// .add_systems(Update, bla) // .add_systems(Update, bla)
; ;
} }
} }

View File

@ -1,17 +1,14 @@
use bevy::prelude::*; use bevy::prelude::*;
use bevy::utils::{Uuid}; use bevy::utils::Uuid;
#[derive(Component, Reflect, Debug, )] #[derive(Component, Reflect, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub struct Saveable { pub struct Saveable {
id: Uuid id: Uuid,
} }
impl Default for Saveable { impl Default for Saveable {
fn default() -> Self { fn default() -> Self {
Saveable{ Saveable { id: Uuid::new_v4() }
id: Uuid::new_v4()
} }
} }
}

View File

@ -1,18 +1,17 @@
use bevy::pbr::{Clusters, VisiblePointLights}; use bevy::pbr::{Clusters, VisiblePointLights};
use bevy::render::camera::CameraRenderGraph; use bevy::render::camera::CameraRenderGraph;
use bevy::render::view::VisibleEntities; use bevy::render::view::VisibleEntities;
use bevy::{prelude::*, gltf::GltfExtras};
use bevy::tasks::IoTaskPool; use bevy::tasks::IoTaskPool;
use bevy::{gltf::GltfExtras, prelude::*};
use bevy_rapier3d::prelude::RigidBody; use bevy_rapier3d::prelude::RigidBody;
use std::io::Write;
use std::fs::File; use std::fs::File;
use std::io::Write;
use crate::core::physics::Collider; use crate::core::physics::Collider;
use crate::game::{Pickable, Player}; use crate::game::{Pickable, Player};
use super::Saveable; use super::Saveable;
const NEW_SCENE_FILE_PATH: &str = "save.scn.ron"; const NEW_SCENE_FILE_PATH: &str = "save.scn.ron";
#[derive(Component, Event)] #[derive(Component, Event)]
@ -20,11 +19,9 @@ pub struct SaveRequest {
pub path: String, pub path: String,
} }
pub fn should_save( pub fn should_save(
// keycode: Res<Input<KeyCode>>, // keycode: Res<Input<KeyCode>>,
save_requested_events: EventReader<SaveRequest>, save_requested_events: EventReader<SaveRequest>,
) -> bool { ) -> bool {
return save_requested_events.len() > 0; return save_requested_events.len() > 0;
@ -60,11 +57,9 @@ pub fn save_game(
.deny::<Visibility>() .deny::<Visibility>()
.deny::<GltfExtras>() .deny::<GltfExtras>()
.deny::<GlobalTransform>() .deny::<GlobalTransform>()
.deny::<Collider>() .deny::<Collider>()
.deny::<RigidBody>() .deny::<RigidBody>()
.deny::<Saveable>() .deny::<Saveable>()
// camera stuff // camera stuff
.deny::<Camera>() .deny::<Camera>()
.deny::<CameraRenderGraph>() .deny::<CameraRenderGraph>()
@ -73,14 +68,12 @@ pub fn save_game(
.deny::<VisibleEntities>() .deny::<VisibleEntities>()
.deny::<VisiblePointLights>() .deny::<VisiblePointLights>()
//.deny::<HasGizmoMarker>() //.deny::<HasGizmoMarker>()
.extract_entities(saveable_entities.into_iter()); .extract_entities(saveable_entities.into_iter());
let dyn_scene = scene_builder.build(); let dyn_scene = scene_builder.build();
let serialized_scene = dyn_scene.serialize_ron(world.resource::<AppTypeRegistry>()).unwrap(); let serialized_scene = dyn_scene
.serialize_ron(world.resource::<AppTypeRegistry>())
.unwrap();
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
IoTaskPool::get() IoTaskPool::get()

View File

@ -1,6 +1,9 @@
use bevy::prelude::*; use bevy::prelude::*;
use crate::{assets::GameAssets, state::{InAppRunning, GameState}}; use crate::{
assets::GameAssets,
state::{GameState, InAppRunning},
};
use bevy_gltf_blueprints::GameWorldTag; use bevy_gltf_blueprints::GameWorldTag;
pub fn setup_game( pub fn setup_game(
@ -8,7 +11,6 @@ pub fn setup_game(
game_assets: Res<GameAssets>, game_assets: Res<GameAssets>,
mut next_game_state: ResMut<NextState<GameState>>, mut next_game_state: ResMut<NextState<GameState>>,
) { ) {
println!("setting up all stuff"); println!("setting up all stuff");
commands.insert_resource(AmbientLight { commands.insert_resource(AmbientLight {
color: Color::WHITE, color: Color::WHITE,
@ -23,7 +25,7 @@ pub fn setup_game(
}, },
bevy::prelude::Name::from("world"), bevy::prelude::Name::from("world"),
GameWorldTag, GameWorldTag,
InAppRunning InAppRunning,
)); ));
next_game_state.set(GameState::InGame) next_game_state.set(GameState::InGame)

View File

@ -1,6 +1,9 @@
use bevy::prelude::*; use bevy::prelude::*;
use crate::{state::{AppState, GameState, InMainMenu}, core::save_load::{LoadRequest, SaveRequest}}; use crate::{
core::save_load::{LoadRequest, SaveRequest},
state::{AppState, GameState, InMainMenu},
};
pub fn setup_main_menu(mut commands: Commands) { pub fn setup_main_menu(mut commands: Commands) {
commands.spawn((Camera2dBundle::default(), InMainMenu)); commands.spawn((Camera2dBundle::default(), InMainMenu));
@ -21,10 +24,9 @@ pub fn setup_main_menu(mut commands: Commands){
left: Val::Px(200.0), left: Val::Px(200.0),
..default() ..default()
}), }),
InMainMenu InMainMenu,
)); ));
commands.spawn(( commands.spawn((
TextBundle::from_section( TextBundle::from_section(
"New Game (press Enter to start, press T once the game is started for demo spawning)", "New Game (press Enter to start, press T once the game is started for demo spawning)",
@ -41,7 +43,7 @@ pub fn setup_main_menu(mut commands: Commands){
left: Val::Px(200.0), left: Val::Px(200.0),
..default() ..default()
}), }),
InMainMenu InMainMenu,
)); ));
/* /*
@ -95,10 +97,8 @@ pub fn main_menu(
mut next_app_state: ResMut<NextState<AppState>>, mut next_app_state: ResMut<NextState<AppState>>,
// mut next_game_state: ResMut<NextState<GameState>>, // mut next_game_state: ResMut<NextState<GameState>>,
mut save_requested_events: EventWriter<SaveRequest>, mut save_requested_events: EventWriter<SaveRequest>,
mut load_requested_events: EventWriter<LoadRequest>, mut load_requested_events: EventWriter<LoadRequest>,
) { ) {
if keycode.just_pressed(KeyCode::Return) { if keycode.just_pressed(KeyCode::Return) {
next_app_state.set(AppState::AppLoading); next_app_state.set(AppState::AppLoading);

View File

@ -7,15 +7,16 @@ pub use in_main_menu::*;
pub mod picking; pub mod picking;
pub use picking::*; pub use picking::*;
use crate::{
insert_dependant_component,
state::{AppState, GameState},
};
use bevy::prelude::*; use bevy::prelude::*;
use bevy_rapier3d::prelude::*; use bevy_rapier3d::prelude::*;
use crate::{insert_dependant_component, state::{AppState, GameState}};
// this file is just for demo purposes, contains various types of components, systems etc // this file is just for demo purposes, contains various types of components, systems etc
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub enum SoundMaterial { pub enum SoundMaterial {
Metal, Metal,
@ -24,35 +25,28 @@ pub enum SoundMaterial{
Cloth, Cloth,
Squishy, Squishy,
#[default] #[default]
None None,
} }
#[derive(Component, Reflect, Default, Debug)]
#[derive(Component, Reflect, Default, Debug, )]
#[reflect(Component)] #[reflect(Component)]
/// Demo marker component /// Demo marker component
pub struct Player; pub struct Player;
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
/// Demo component showing auto injection of components /// Demo component showing auto injection of components
pub struct ShouldBeWithPlayer; pub struct ShouldBeWithPlayer;
#[derive(Component, Reflect, Default, Debug)]
#[derive(Component, Reflect, Default, Debug, )]
#[reflect(Component)] #[reflect(Component)]
/// Demo marker component /// Demo marker component
pub struct Interactible; pub struct Interactible;
fn player_move_demo( fn player_move_demo(
keycode: Res<Input<KeyCode>>, keycode: Res<Input<KeyCode>>,
mut players: Query<&mut Transform, With<Player>>, mut players: Query<&mut Transform, With<Player>>,
) { ) {
let speed = 0.2; let speed = 0.2;
if let Ok(mut player) = players.get_single_mut() { if let Ok(mut player) = players.get_single_mut() {
if keycode.pressed(KeyCode::Left) { if keycode.pressed(KeyCode::Left) {
@ -75,8 +69,7 @@ fn player_move_demo(
pub fn test_collision_events( pub fn test_collision_events(
mut collision_events: EventReader<CollisionEvent>, mut collision_events: EventReader<CollisionEvent>,
mut contact_force_events: EventReader<ContactForceEvent>, mut contact_force_events: EventReader<ContactForceEvent>,
) ) {
{
for collision_event in collision_events.iter() { for collision_event in collision_events.iter() {
println!("collision"); println!("collision");
match collision_event { match collision_event {
@ -85,7 +78,6 @@ pub fn test_collision_events(
} }
CollisionEvent::Stopped(_entity1, _entity2, _) => { CollisionEvent::Stopped(_entity1, _entity2, _) => {
println!("collision ended") println!("collision ended")
} }
} }
} }
@ -95,42 +87,28 @@ pub fn test_collision_events(
} }
} }
pub struct GamePlugin; pub struct GamePlugin;
impl Plugin for GamePlugin { impl Plugin for GamePlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.add_plugins(PickingPlugin)
.add_plugins(PickingPlugin)
.register_type::<Interactible>() .register_type::<Interactible>()
.register_type::<SoundMaterial>() .register_type::<SoundMaterial>()
.register_type::<Player>() .register_type::<Player>()
// little helper utility, to automatically inject components that are dependant on an other component // little helper utility, to automatically inject components that are dependant on an other component
// ie, here an Entity with a Player component should also always have a ShouldBeWithPlayer component // ie, here an Entity with a Player component should also always have a ShouldBeWithPlayer component
// you get a warning if you use this, as I consider this to be stop-gap solution (usually you should have either a bundle, or directly define all needed components) // you get a warning if you use this, as I consider this to be stop-gap solution (usually you should have either a bundle, or directly define all needed components)
.add_systems(Update, ( .add_systems(
Update,
(
// insert_dependant_component::<Player, ShouldBeWithPlayer>, // insert_dependant_component::<Player, ShouldBeWithPlayer>,
player_move_demo, //.run_if(in_state(AppState::Running)), player_move_demo, //.run_if(in_state(AppState::Running)),
// test_collision_events // test_collision_events
) )
.run_if(in_state(GameState::InGame))) .run_if(in_state(GameState::InGame)),
.add_systems(
OnEnter(AppState::MenuRunning),
setup_main_menu
)
.add_systems(
OnExit(AppState::MenuRunning),
teardown_main_menu
) )
.add_systems(OnEnter(AppState::MenuRunning), setup_main_menu)
.add_systems(OnExit(AppState::MenuRunning), teardown_main_menu)
.add_systems(Update, (main_menu)) .add_systems(Update, (main_menu))
.add_systems(OnEnter(AppState::AppRunning), setup_game);
.add_systems(
OnEnter(AppState::AppRunning),
setup_game
)
;
} }
} }

View File

@ -1,8 +1,7 @@
use bevy::prelude::*;
use super::Player; use super::Player;
use bevy::prelude::*;
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub struct Pickable; pub struct Pickable;
@ -11,11 +10,13 @@ pub struct Pickable;
pub fn picking( pub fn picking(
players: Query<&GlobalTransform, With<Player>>, players: Query<&GlobalTransform, With<Player>>,
pickables: Query<(Entity, &GlobalTransform), With<Pickable>>, pickables: Query<(Entity, &GlobalTransform), With<Pickable>>,
mut commands: Commands mut commands: Commands,
) { ) {
for player_transforms in players.iter() { for player_transforms in players.iter() {
for (pickable, pickable_transforms) in pickables.iter() { for (pickable, pickable_transforms) in pickables.iter() {
let distance = player_transforms.translation().distance(pickable_transforms.translation()); let distance = player_transforms
.translation()
.distance(pickable_transforms.translation());
if distance < 2.5 { if distance < 2.5 {
commands.entity(pickable).despawn_recursive(); commands.entity(pickable).despawn_recursive();
} }
@ -26,15 +27,11 @@ pub fn picking(
pub struct PickingPlugin; pub struct PickingPlugin;
impl Plugin for PickingPlugin { impl Plugin for PickingPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.register_type::<Pickable>().add_systems(
.register_type::<Pickable>() Update,
(
.add_systems(Update, (
picking, //.run_if(in_state(AppState::Running)), picking, //.run_if(in_state(AppState::Running)),
)) ),
);
;
} }
} }

View File

@ -1,8 +1,8 @@
use std::time::Duration; use bevy::{asset::ChangeWatcher, gltf::Gltf, prelude::*};
use bevy::{prelude::*, asset::ChangeWatcher, gltf::Gltf};
use bevy_editor_pls::prelude::*; use bevy_editor_pls::prelude::*;
use bevy_rapier3d::prelude::*;
use bevy_gltf_components::ComponentsFromGltfPlugin; use bevy_gltf_components::ComponentsFromGltfPlugin;
use bevy_rapier3d::prelude::*;
use std::time::Duration;
mod core; mod core;
use crate::core::*; use crate::core::*;
@ -19,20 +19,16 @@ use game::*;
mod test_components; mod test_components;
use test_components::*; use test_components::*;
fn main() { fn main() {
App::new() App::new()
.add_plugins(( .add_plugins((
DefaultPlugins.set( DefaultPlugins.set(AssetPlugin {
AssetPlugin {
// This tells the AssetServer to watch for changes to assets. // This tells the AssetServer to watch for changes to assets.
// It enables our scenes to automatically reload in game when we modify their files. // It enables our scenes to automatically reload in game when we modify their files.
// practical in our case to be able to edit the shaders without needing to recompile // practical in our case to be able to edit the shaders without needing to recompile
// watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(50)), : FIXME: breaks scene save/loading // watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(50)), : FIXME: breaks scene save/loading
..default() ..default()
} }),
),
// editor // editor
EditorPlugin::default(), EditorPlugin::default(),
// physics // physics
@ -40,12 +36,11 @@ fn main(){
RapierDebugRenderPlugin::default(), RapierDebugRenderPlugin::default(),
// our custom plugins // our custom plugins
ComponentsFromGltfPlugin, ComponentsFromGltfPlugin,
StatePlugin, StatePlugin,
AssetsPlugin, AssetsPlugin,
CorePlugin, // reusable plugins CorePlugin, // reusable plugins
GamePlugin, // specific to our game GamePlugin, // specific to our game
ComponentsTestPlugin // Showcases different type of components /structs ComponentsTestPlugin, // Showcases different type of components /structs
)) ))
.run(); .run();
} }

View File

@ -1,5 +1,5 @@
use bevy::prelude::*;
use bevy::app::AppExit; use bevy::app::AppExit;
use bevy::prelude::*;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default, States)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default, States)]
pub enum AppState { pub enum AppState {
@ -11,7 +11,7 @@ pub enum AppState{
AppEnding, AppEnding,
// FIXME: not sure // FIXME: not sure
LoadingGame LoadingGame,
} }
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default, States)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default, States)]
@ -25,7 +25,7 @@ pub enum GameState {
InGameOver, InGameOver,
InSaving, InSaving,
InLoading InLoading,
} }
// tag components for all entities within a certain state (for despawning them if needed) , FIXME: seems kinda hack-ish // tag components for all entities within a certain state (for despawning them if needed) , FIXME: seems kinda hack-ish
@ -46,13 +46,9 @@ pub struct InMenu;
#[derive(Component, Default)] #[derive(Component, Default)]
pub struct InGame; pub struct InGame;
pub struct StatePlugin; pub struct StatePlugin;
impl Plugin for StatePlugin { impl Plugin for StatePlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.add_state::<AppState>().add_state::<GameState>();
.add_state::<AppState>()
.add_state::<GameState>()
;
} }
} }

View File

@ -1,7 +1,6 @@
use bevy::prelude::*; use bevy::prelude::*;
#[derive(Component, Reflect, Default, Debug)]
#[derive(Component, Reflect, Default, Debug, )]
#[reflect(Component)] #[reflect(Component)]
struct UnitTest; struct UnitTest;
@ -17,39 +16,39 @@ struct TuppleTestU64(u64);
#[reflect(Component)] #[reflect(Component)]
pub struct TuppleTestStr(String); pub struct TuppleTestStr(String);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleTest2(f32, u64, String); struct TuppleTest2(f32, u64, String);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleTestBool(bool); struct TuppleTestBool(bool);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleVec2(Vec2); struct TuppleVec2(Vec2);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleVec3(Vec3); struct TuppleVec3(Vec3);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleVec(Vec<String>); struct TuppleVec(Vec<String>);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleTestColor(Color); struct TuppleTestColor(Color);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct BasicTest { struct BasicTest {
a: f32, a: f32,
b: u64, b: u64,
c: String c: String,
} }
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub enum EnumTest { pub enum EnumTest {
Metal, Metal,
@ -58,15 +57,13 @@ pub enum EnumTest{
Cloth, Cloth,
Squishy, Squishy,
#[default] #[default]
None None,
} }
pub struct ComponentsTestPlugin; pub struct ComponentsTestPlugin;
impl Plugin for ComponentsTestPlugin { impl Plugin for ComponentsTestPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.register_type::<BasicTest>()
.register_type::<BasicTest>()
.register_type::<UnitTest>() .register_type::<UnitTest>()
.register_type::<TuppleTestF32>() .register_type::<TuppleTestF32>()
.register_type::<TuppleTestU64>() .register_type::<TuppleTestU64>()
@ -77,10 +74,7 @@ impl Plugin for ComponentsTestPlugin {
.register_type::<TuppleVec3>() .register_type::<TuppleVec3>()
.register_type::<EnumTest>() .register_type::<EnumTest>()
.register_type::<TuppleTestColor>() .register_type::<TuppleTestColor>()
.register_type::<TuppleVec>() .register_type::<TuppleVec>()
.register_type::<Vec<String>>() .register_type::<Vec<String>>();
;
} }
} }

View File

@ -1,7 +1,6 @@
use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings};
use bevy::core_pipeline::tonemapping::{DebandDither, Tonemapping};
use bevy::prelude::*; use bevy::prelude::*;
use bevy::core_pipeline::bloom::{BloomSettings, BloomCompositeMode};
use bevy::core_pipeline::tonemapping::{Tonemapping, DebandDither};
use super::CameraTrackingOffset; use super::CameraTrackingOffset;
@ -9,26 +8,17 @@ pub fn camera_replace_proxies (
mut commands: Commands, mut commands: Commands,
mut added_cameras: Query<(Entity, &mut Camera), (Added<Camera>, With<CameraTrackingOffset>)>, mut added_cameras: Query<(Entity, &mut Camera), (Added<Camera>, With<CameraTrackingOffset>)>,
) { ) {
for (entity, mut camera) in added_cameras.iter_mut() { for (entity, mut camera) in added_cameras.iter_mut() {
info!("detected added camera, updating proxy"); info!("detected added camera, updating proxy");
camera.hdr = true; camera.hdr = true;
commands.entity(entity) commands
.insert( .entity(entity)
DebandDither::Enabled .insert(DebandDither::Enabled)
) .insert(Tonemapping::BlenderFilmic)
.insert( .insert(BloomSettings {
Tonemapping::BlenderFilmic
)
.insert(
BloomSettings{
intensity: 0.01, intensity: 0.01,
composite_mode: BloomCompositeMode::Additive, composite_mode: BloomCompositeMode::Additive,
..default() ..default()
} });
)
;
} }
} }

View File

@ -1,19 +1,19 @@
use bevy::prelude::*; use bevy::prelude::*;
#[derive(Component, Reflect, Debug)] #[derive(Component, Reflect, Debug)]
#[reflect(Component)] #[reflect(Component)]
/// Component for cameras, with an offset from the Trackable target /// Component for cameras, with an offset from the Trackable target
/// ///
pub struct CameraTracking { pub struct CameraTracking {
pub offset: Vec3 pub offset: Vec3,
} }
impl Default for CameraTracking { impl Default for CameraTracking {
fn default() -> Self { fn default() -> Self {
CameraTracking { offset: Vec3::new(0.0, 6.0, 8.0) } CameraTracking {
offset: Vec3::new(0.0, 6.0, 8.0),
}
} }
} }
#[derive(Component, Reflect, Debug, Deref, DerefMut)] #[derive(Component, Reflect, Debug, Deref, DerefMut)]
#[reflect(Component)] #[reflect(Component)]
@ -31,27 +31,28 @@ impl CameraTrackingOffset {
} }
} }
#[derive(Component, Reflect, Default, Debug)]
#[derive(Component, Reflect, Default, Debug, )]
#[reflect(Component)] #[reflect(Component)]
/// Add this component to an entity if you want it to be tracked by a Camera /// Add this component to an entity if you want it to be tracked by a Camera
pub struct CameraTrackable; pub struct CameraTrackable;
pub fn camera_track( pub fn camera_track(
mut tracking_cameras: Query<(&mut Transform, &CameraTrackingOffset), (With<Camera>, With<CameraTrackingOffset>, Without<CameraTrackable>)>, mut tracking_cameras: Query<
(&mut Transform, &CameraTrackingOffset),
(
With<Camera>,
With<CameraTrackingOffset>,
Without<CameraTrackable>,
),
>,
camera_tracked: Query<&Transform, With<CameraTrackable>>, camera_tracked: Query<&Transform, With<CameraTrackable>>,
) { ) {
for (mut camera_transform, tracking_offset) in tracking_cameras.iter_mut() { for (mut camera_transform, tracking_offset) in tracking_cameras.iter_mut() {
for tracked_transform in camera_tracked.iter() { for tracked_transform in camera_tracked.iter() {
let target_position = tracked_transform.translation + tracking_offset.0; let target_position = tracked_transform.translation + tracking_offset.0;
let eased_position = camera_transform.translation.lerp(target_position, 0.1); let eased_position = camera_transform.translation.lerp(target_position, 0.1);
camera_transform.translation = eased_position; // + tracking.offset;// tracked_transform.translation + tracking.offset; camera_transform.translation = eased_position; // + tracking.offset;// tracked_transform.translation + tracking.offset;
*camera_transform = camera_transform.looking_at(tracked_transform.translation, Vec3::Y); *camera_transform = camera_transform.looking_at(tracked_transform.translation, Vec3::Y);
} }
} }
} }

View File

@ -9,17 +9,9 @@ use bevy::prelude::*;
pub struct CameraPlugin; pub struct CameraPlugin;
impl Plugin for CameraPlugin { impl Plugin for CameraPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.register_type::<CameraTrackable>()
.register_type::<CameraTrackable>()
.register_type::<CameraTracking>() .register_type::<CameraTracking>()
.register_type::<CameraTrackingOffset>() .register_type::<CameraTrackingOffset>()
.add_systems(Update, (camera_replace_proxies, camera_track));
.add_systems(Update,
(
camera_replace_proxies,
camera_track,
)
)
;
} }
} }

View File

@ -1,15 +1,13 @@
use bevy::prelude::*; use bevy::prelude::*;
use bevy::pbr::{CascadeShadowConfigBuilder, CascadeShadowConfig}; use bevy::pbr::{CascadeShadowConfig, CascadeShadowConfigBuilder};
// fixme might be too specific to might needs, should it be moved out ? also these are all for lights, not models // fixme might be too specific to might needs, should it be moved out ? also these are all for lights, not models
pub fn lighting_replace_proxies( pub fn lighting_replace_proxies(
mut added_dirights: Query<(Entity, &mut DirectionalLight), Added<DirectionalLight>>, mut added_dirights: Query<(Entity, &mut DirectionalLight), Added<DirectionalLight>>,
mut added_spotlights: Query<&mut SpotLight, Added<SpotLight>>, mut added_spotlights: Query<&mut SpotLight, Added<SpotLight>>,
mut commands: Commands, mut commands: Commands,
) { ) {
for (entity, mut light) in added_dirights.iter_mut() { for (entity, mut light) in added_dirights.iter_mut() {
light.illuminance *= 5.0; light.illuminance *= 5.0;
light.shadows_enabled = true; light.shadows_enabled = true;
@ -19,11 +17,9 @@ pub fn lighting_replace_proxies(
..default() ..default()
} }
.into(); .into();
commands.entity(entity) commands.entity(entity).insert(shadow_config);
.insert(shadow_config);
} }
for mut light in added_spotlights.iter_mut() { for mut light in added_spotlights.iter_mut() {
light.shadows_enabled = true; light.shadows_enabled = true;
} }
} }

View File

@ -1,8 +1,8 @@
mod lighting_replace_proxies; mod lighting_replace_proxies;
use lighting_replace_proxies::*; use lighting_replace_proxies::*;
use bevy::pbr::{DirectionalLightShadowMap, NotShadowCaster};
use bevy::prelude::*; use bevy::prelude::*;
use bevy::pbr::{NotShadowCaster, DirectionalLightShadowMap};
pub struct LightingPlugin; pub struct LightingPlugin;
impl Plugin for LightingPlugin { impl Plugin for LightingPlugin {

View File

@ -14,11 +14,6 @@ use bevy::prelude::*;
pub struct CorePlugin; pub struct CorePlugin;
impl Plugin for CorePlugin { impl Plugin for CorePlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.add_plugins((LightingPlugin, CameraPlugin, PhysicsPlugin));
.add_plugins((
LightingPlugin,
CameraPlugin,
PhysicsPlugin
));
} }
} }

View File

@ -25,4 +25,3 @@ impl Plugin for PhysicsPlugin {
; ;
} }
} }

View File

@ -1,11 +1,11 @@
use bevy::prelude::*; use bevy::prelude::*;
// use bevy::render::primitives::Aabb; // use bevy::render::primitives::Aabb;
use bevy_rapier3d::geometry::Collider as RapierCollider; use bevy_rapier3d::geometry::Collider as RapierCollider;
use bevy_rapier3d::prelude::{ComputedColliderShape, ActiveEvents, ActiveCollisionTypes}; use bevy_rapier3d::prelude::{ActiveCollisionTypes, ActiveEvents, ComputedColliderShape};
use super::utils::*; use super::utils::*;
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub enum Collider { pub enum Collider {
Ball(f32), Ball(f32),
@ -15,20 +15,23 @@ pub enum Collider {
Mesh, Mesh,
} }
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub enum AutoAABBCollider { pub enum AutoAABBCollider {
#[default] #[default]
Cuboid, Cuboid,
Ball, Ball,
Capsule Capsule,
} }
// replaces all physics stand-ins with the actual rapier types // replaces all physics stand-ins with the actual rapier types
pub fn physics_replace_proxies( pub fn physics_replace_proxies(
meshes: Res<Assets<Mesh>>, meshes: Res<Assets<Mesh>>,
mesh_handles: Query<&Handle<Mesh>>, mesh_handles: Query<&Handle<Mesh>>,
mut proxy_colliders: Query<(Entity, &Collider, &Name, &mut Visibility), (Without<RapierCollider>, Added<Collider>)>, mut proxy_colliders: Query<
(Entity, &Collider, &Name, &mut Visibility),
(Without<RapierCollider>, Added<Collider>),
>,
// needed for tri meshes // needed for tri meshes
children: Query<&Children>, children: Query<&Children>,
@ -69,15 +72,25 @@ pub fn physics_replace_proxies (
} }
Collider::Mesh => { Collider::Mesh => {
println!("proxy: mesh"); println!("proxy: mesh");
for (_, collider_mesh) in Mesh::search_in_children(entity, &children, &meshes, &mesh_handles) for (_, collider_mesh) in
Mesh::search_in_children(entity, &children, &meshes, &mesh_handles)
{ {
rapier_collider = RapierCollider::from_bevy_mesh(collider_mesh, &ComputedColliderShape::TriMesh).unwrap(); rapier_collider = RapierCollider::from_bevy_mesh(
commands.entity(entity) collider_mesh,
&ComputedColliderShape::TriMesh,
)
.unwrap();
commands
.entity(entity)
.insert(rapier_collider) .insert(rapier_collider)
// FIXME: this is just for demo purposes !!! // FIXME: this is just for demo purposes !!!
.insert(ActiveCollisionTypes::default() | ActiveCollisionTypes::KINEMATIC_STATIC | ActiveCollisionTypes::STATIC_STATIC | ActiveCollisionTypes::DYNAMIC_STATIC) .insert(
.insert(ActiveEvents::COLLISION_EVENTS) ActiveCollisionTypes::default()
; | ActiveCollisionTypes::KINEMATIC_STATIC
| ActiveCollisionTypes::STATIC_STATIC
| ActiveCollisionTypes::DYNAMIC_STATIC,
)
.insert(ActiveEvents::COLLISION_EVENTS);
// .insert(ActiveEvents::COLLISION_EVENTS) // .insert(ActiveEvents::COLLISION_EVENTS)
// break; // break;
// RapierCollider::convex_hull(points) // RapierCollider::convex_hull(points)

View File

@ -1,16 +1,15 @@
use bevy::prelude::*; use bevy::prelude::*;
pub fn insert_dependant_component<Dependant: Component, Dependency: Component+ std::default::Default>( pub fn insert_dependant_component<
Dependant: Component,
Dependency: Component + std::default::Default,
>(
mut commands: Commands, mut commands: Commands,
entities_without_depency: Query<(Entity, &Name), (With<Dependant>, Without<Dependency>)>, entities_without_depency: Query<(Entity, &Name), (With<Dependant>, Without<Dependency>)>,
) { ) {
for (entity, name) in entities_without_depency.iter() { for (entity, name) in entities_without_depency.iter() {
let name = name.clone().to_string(); let name = name.clone().to_string();
commands.entity(entity) commands.entity(entity).insert(Dependency::default());
.insert(
Dependency::default()
)
;
warn!("found an entity called {} with a {} component but without an {}, please check your assets", name.clone(), std::any::type_name::<Dependant>(), std::any::type_name::<Dependency>()); warn!("found an entity called {} with a {} component but without an {}, please check your assets", name.clone(), std::any::type_name::<Dependant>(), std::any::type_name::<Dependency>());
} }
} }

View File

@ -1,10 +1,10 @@
use crate::insert_dependant_component;
use bevy::prelude::*; use bevy::prelude::*;
use bevy_rapier3d::prelude::*; use bevy_rapier3d::prelude::*;
use crate::insert_dependant_component;
// this file is just for demo purposes, contains various types of components, systems etc // this file is just for demo purposes, contains various types of components, systems etc
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub enum SoundMaterial { pub enum SoundMaterial {
Metal, Metal,
@ -13,38 +13,33 @@ pub enum SoundMaterial{
Cloth, Cloth,
Squishy, Squishy,
#[default] #[default]
None None,
} }
#[derive(Component, Reflect, Default, Debug)]
#[derive(Component, Reflect, Default, Debug, )]
#[reflect(Component)] #[reflect(Component)]
/// Demo marker component /// Demo marker component
pub struct Player; pub struct Player;
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
/// Demo component showing auto injection of components /// Demo component showing auto injection of components
pub struct ShouldBeWithPlayer; pub struct ShouldBeWithPlayer;
#[derive(Component, Reflect, Default, Debug)]
#[derive(Component, Reflect, Default, Debug, )]
#[reflect(Component)] #[reflect(Component)]
/// Demo marker component /// Demo marker component
pub struct Interactible; pub struct Interactible;
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
/// Demo marker component /// Demo marker component
pub struct Pickable; pub struct Pickable;
fn player_move_demo( fn player_move_demo(
keycode: Res<Input<KeyCode>>, keycode: Res<Input<KeyCode>>,
mut players: Query<&mut Transform, With<Player>>, mut players: Query<&mut Transform, With<Player>>,
) { ) {
let speed = 0.2; let speed = 0.2;
if let Ok(mut player) = players.get_single_mut() { if let Ok(mut player) = players.get_single_mut() {
if keycode.pressed(KeyCode::Left) { if keycode.pressed(KeyCode::Left) {
@ -67,8 +62,7 @@ fn player_move_demo(
pub fn test_collision_events( pub fn test_collision_events(
mut collision_events: EventReader<CollisionEvent>, mut collision_events: EventReader<CollisionEvent>,
mut contact_force_events: EventReader<ContactForceEvent>, mut contact_force_events: EventReader<ContactForceEvent>,
) ) {
{
for collision_event in collision_events.iter() { for collision_event in collision_events.iter() {
println!("collision"); println!("collision");
match collision_event { match collision_event {
@ -77,7 +71,6 @@ pub fn test_collision_events(
} }
CollisionEvent::Stopped(_entity1, _entity2, _) => { CollisionEvent::Stopped(_entity1, _entity2, _) => {
println!("collision ended") println!("collision ended")
} }
} }
} }
@ -87,23 +80,23 @@ pub fn test_collision_events(
} }
} }
pub struct DemoPlugin; pub struct DemoPlugin;
impl Plugin for DemoPlugin { impl Plugin for DemoPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.register_type::<Interactible>()
.register_type::<Interactible>()
.register_type::<Pickable>() .register_type::<Pickable>()
.register_type::<SoundMaterial>() .register_type::<SoundMaterial>()
.register_type::<Player>() .register_type::<Player>()
// little helper utility, to automatically inject components that are dependant on an other component // little helper utility, to automatically inject components that are dependant on an other component
// ie, here an Entity with a Player component should also always have a ShouldBeWithPlayer component // ie, here an Entity with a Player component should also always have a ShouldBeWithPlayer component
// you get a warning if you use this, as I consider this to be stop-gap solution (usually you should have either a bundle, or directly define all needed components) // you get a warning if you use this, as I consider this to be stop-gap solution (usually you should have either a bundle, or directly define all needed components)
.add_systems(Update, ( .add_systems(
Update,
(
insert_dependant_component::<Player, ShouldBeWithPlayer>, insert_dependant_component::<Player, ShouldBeWithPlayer>,
player_move_demo, //.run_if(in_state(AppState::Running)), player_move_demo, //.run_if(in_state(AppState::Running)),
test_collision_events test_collision_events,
)) ),
; );
} }
} }

View File

@ -1,8 +1,8 @@
use std::time::Duration; use bevy::{asset::ChangeWatcher, gltf::Gltf, prelude::*};
use bevy::{prelude::*, asset::ChangeWatcher, gltf::Gltf};
use bevy_editor_pls::prelude::*; use bevy_editor_pls::prelude::*;
use bevy_rapier3d::prelude::*;
use bevy_gltf_components::ComponentsFromGltfPlugin; use bevy_gltf_components::ComponentsFromGltfPlugin;
use bevy_rapier3d::prelude::*;
use std::time::Duration;
mod core; mod core;
use crate::core::*; use crate::core::*;
@ -13,12 +13,11 @@ use game::*;
mod test_components; mod test_components;
use test_components::*; use test_components::*;
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
/// helper marker component /// helper marker component
pub struct LoadedMarker; pub struct LoadedMarker;
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)] #[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)]
enum AppState { enum AppState {
#[default] #[default]
@ -26,20 +25,16 @@ enum AppState {
Running, Running,
} }
fn main() { fn main() {
App::new() App::new()
.add_plugins(( .add_plugins((
DefaultPlugins.set( DefaultPlugins.set(AssetPlugin {
AssetPlugin {
// This tells the AssetServer to watch for changes to assets. // This tells the AssetServer to watch for changes to assets.
// It enables our scenes to automatically reload in game when we modify their files. // It enables our scenes to automatically reload in game when we modify their files.
// practical in our case to be able to edit the shaders without needing to recompile // practical in our case to be able to edit the shaders without needing to recompile
watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(50)), watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(50)),
..default() ..default()
} }),
),
// editor // editor
EditorPlugin::default(), EditorPlugin::default(),
// physics // physics
@ -49,30 +44,21 @@ fn main(){
ComponentsFromGltfPlugin, ComponentsFromGltfPlugin,
CorePlugin, // reusable plugins CorePlugin, // reusable plugins
DemoPlugin, // specific to our game DemoPlugin, // specific to our game
ComponentsTestPlugin // Showcases different type of components /structs ComponentsTestPlugin, // Showcases different type of components /structs
)) ))
.add_state::<AppState>() .add_state::<AppState>()
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, ( .add_systems(Update, (spawn_level.run_if(in_state(AppState::Loading)),))
spawn_level.run_if(in_state(AppState::Loading)),
))
.run(); .run();
} }
#[derive(Resource)] #[derive(Resource)]
struct AssetLoadHelper(Handle<Scene>); struct AssetLoadHelper(Handle<Scene>);
// we preload the data here, but this is for DEMO PURPOSES ONLY !! Please use https://github.com/NiklasEi/bevy_asset_loader or a similar logic to seperate loading / pre processing // we preload the data here, but this is for DEMO PURPOSES ONLY !! Please use https://github.com/NiklasEi/bevy_asset_loader or a similar logic to seperate loading / pre processing
// of assets from the spawning // of assets from the spawning
// AssetLoadHelper is also just for the same purpose, you do not need it in a real scenario // AssetLoadHelper is also just for the same purpose, you do not need it in a real scenario
// the states here are also for demo purposes only, // the states here are also for demo purposes only,
fn setup( fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
mut commands: Commands,
asset_server: Res<AssetServer>,
) {
let tmp: Handle<Scene> = asset_server.load("basic/models/level1.glb#Scene0"); let tmp: Handle<Scene> = asset_server.load("basic/models/level1.glb#Scene0");
commands.insert_resource(AssetLoadHelper(tmp)); commands.insert_resource(AssetLoadHelper(tmp));
} }
@ -85,27 +71,24 @@ fn spawn_level(
mut asset_event_reader: EventReader<AssetEvent<Gltf>>, mut asset_event_reader: EventReader<AssetEvent<Gltf>>,
mut next_state: ResMut<NextState<AppState>>, mut next_state: ResMut<NextState<AppState>>,
) { ) {
if let Some(asset_event) = asset_event_reader.iter().next() { if let Some(asset_event) = asset_event_reader.iter().next() {
match asset_event { match asset_event {
AssetEvent::Created { handle: _ } => { AssetEvent::Created { handle: _ } => {
info!("GLTF loaded"); info!("GLTF loaded");
if scene_markers.is_empty() { if scene_markers.is_empty() {
info!("spawning scene"); info!("spawning scene");
commands.spawn( commands.spawn((
(
SceneBundle { SceneBundle {
scene: preloaded_scene.0.clone(), scene: preloaded_scene.0.clone(),
..default() ..default()
}, },
LoadedMarker, LoadedMarker,
Name::new("Level1") Name::new("Level1"),
) ));
);
next_state.set(AppState::Running); next_state.set(AppState::Running);
} }
} }
_ => () _ => (),
} }
} }
} }

View File

@ -1,7 +1,6 @@
use bevy::prelude::*; use bevy::prelude::*;
#[derive(Component, Reflect, Default, Debug)]
#[derive(Component, Reflect, Default, Debug, )]
#[reflect(Component)] #[reflect(Component)]
struct UnitTest; struct UnitTest;
@ -17,39 +16,39 @@ struct TuppleTestU64(u64);
#[reflect(Component)] #[reflect(Component)]
pub struct TuppleTestStr(String); pub struct TuppleTestStr(String);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleTest2(f32, u64, String); struct TuppleTest2(f32, u64, String);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleTestBool(bool); struct TuppleTestBool(bool);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleVec2(Vec2); struct TuppleVec2(Vec2);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleVec3(Vec3); struct TuppleVec3(Vec3);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleVec(Vec<String>); struct TuppleVec(Vec<String>);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct TuppleTestColor(Color); struct TuppleTestColor(Color);
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
struct BasicTest { struct BasicTest {
a: f32, a: f32,
b: u64, b: u64,
c: String c: String,
} }
#[derive(Component, Reflect, Default, Debug, )] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
pub enum EnumTest { pub enum EnumTest {
Metal, Metal,
@ -58,15 +57,13 @@ pub enum EnumTest{
Cloth, Cloth,
Squishy, Squishy,
#[default] #[default]
None None,
} }
pub struct ComponentsTestPlugin; pub struct ComponentsTestPlugin;
impl Plugin for ComponentsTestPlugin { impl Plugin for ComponentsTestPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.register_type::<BasicTest>()
.register_type::<BasicTest>()
.register_type::<UnitTest>() .register_type::<UnitTest>()
.register_type::<TuppleTestF32>() .register_type::<TuppleTestF32>()
.register_type::<TuppleTestU64>() .register_type::<TuppleTestU64>()
@ -77,10 +74,7 @@ impl Plugin for ComponentsTestPlugin {
.register_type::<TuppleVec3>() .register_type::<TuppleVec3>()
.register_type::<EnumTest>() .register_type::<EnumTest>()
.register_type::<TuppleTestColor>() .register_type::<TuppleTestColor>()
.register_type::<TuppleVec>() .register_type::<TuppleVec>()
.register_type::<Vec<String>>() .register_type::<Vec<String>>();
;
} }
} }