mirror of
https://github.com/kaosat-dev/Blender_bevy_components_workflow.git
synced 2024-11-22 11:50:53 +00:00
chore(): cargo fmt (#21)
This commit is contained in:
parent
a1c32ae1d6
commit
f41a315563
@ -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
|
||||||
|
@ -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),
|
||||||
)
|
);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
|
||||||
)
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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..]
|
||||||
}
|
}
|
||||||
|
|
@ -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 {}
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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()
|
||||||
}
|
});
|
||||||
)
|
|
||||||
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
)
|
),
|
||||||
)
|
);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
|
||||||
)
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>) {
|
||||||
|
@ -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
|
|
||||||
)
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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>());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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![];
|
||||||
|
@ -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)
|
||||||
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
|
||||||
)
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)),
|
||||||
))
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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>()
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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>>();
|
||||||
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
});
|
||||||
)
|
|
||||||
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,4 +25,3 @@ impl Plugin for PhysicsPlugin {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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>());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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,
|
||||||
))
|
),
|
||||||
;
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => ()
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>>();
|
||||||
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user