action buttons work again I guess

main
Elijah Voigt 2 years ago
parent 0e643965f4
commit 50ee319921

BIN
assets/models/FlightHelmet.bin (Stored with Git LFS)

Binary file not shown.

BIN
assets/models/FlightHelmet.gltf (Stored with Git LFS)

Binary file not shown.

BIN
assets/models/materials.blend (Stored with Git LFS)

Binary file not shown.

BIN
assets/models/materials.blend1 (Stored with Git LFS)

Binary file not shown.

@ -1,7 +1,7 @@
( (
resources: {}, resources: {},
entities: { entities: {
4: ( 19: (
components: { components: {
"bevy_transform::components::transform::Transform": ( "bevy_transform::components::transform::Transform": (
translation: ( translation: (
@ -42,20 +42,20 @@
)), )),
"bevy_render::view::visibility::Visibility": Inherited, "bevy_render::view::visibility::Visibility": Inherited,
"bevy_hierarchy::components::children::Children": ([ "bevy_hierarchy::components::children::Children": ([
5, 20,
6, 21,
]), ]),
}, },
), ),
5: ( 20: (
components: { components: {
"bevy_hierarchy::components::parent::Parent": (4), "bevy_hierarchy::components::parent::Parent": (19),
"bevy_asset::handle::Handle<bevy_audio::audio_source::AudioSource>": ( "bevy_asset::handle::Handle<bevy_audio::audio_source::AudioSource>": (
id: AssetPathId(((5718828327369153735), (8823233378563626002))), id: AssetPathId(((5718828327369153735), (8823233378563626002))),
), ),
}, },
), ),
6: ( 21: (
components: { components: {
"bevy_transform::components::transform::Transform": ( "bevy_transform::components::transform::Transform": (
translation: ( translation: (
@ -95,9 +95,9 @@
), ),
)), )),
"bevy_render::view::visibility::Visibility": Inherited, "bevy_render::view::visibility::Visibility": Inherited,
"bevy_hierarchy::components::parent::Parent": (4), "bevy_hierarchy::components::parent::Parent": (19),
"bevy_hierarchy::components::children::Children": ([ "bevy_hierarchy::components::children::Children": ([
16, 22,
]), ]),
"bevy_asset::handle::Handle<bevy_scene::scene::Scene>": ( "bevy_asset::handle::Handle<bevy_scene::scene::Scene>": (
id: AssetPathId(((8329447081204006281), (13531267934229906755))), id: AssetPathId(((8329447081204006281), (13531267934229906755))),

@ -56,6 +56,7 @@ fn main() {
}, },
)) ))
.init_resource::<AssetRegistry>() .init_resource::<AssetRegistry>()
.add_event::<ImportAsset>()
.add_asset::<Monologue>() .add_asset::<Monologue>()
.init_asset_loader::<MonologueLoader>() .init_asset_loader::<MonologueLoader>()
.add_systems(Startup, (initialize_ui, init_texts_ui, welcome_message)) .add_systems(Startup, (initialize_ui, init_texts_ui, welcome_message))
@ -78,7 +79,6 @@ fn main() {
.add_systems( .add_systems(
Update, Update,
( (
import_files,
gltf_ui, gltf_ui,
fonts_ui, fonts_ui,
texts_ui, texts_ui,
@ -87,6 +87,7 @@ fn main() {
sync_monologue_font, sync_monologue_font,
), ),
) )
.add_systems(Update, (import_assets, import_file, import_folder))
.add_systems( .add_systems(
Update, Update,
( (
@ -386,27 +387,6 @@ fn spawn_tab_container<T: Default + Component>(
) )
} }
fn import_files(
mut events: EventReader<FileDragAndDrop>,
server: Res<AssetServer>,
mut registry: ResMut<AssetRegistry>,
) {
events.iter().for_each(|event| match event {
FileDragAndDrop::DroppedFile { path_buf, .. } => {
registry.0.push(
server.load_untyped(
path_buf
.clone()
.into_os_string()
.into_string()
.expect("Path converts to string"),
),
);
}
_ => (),
})
}
use audio::*; use audio::*;
mod audio { mod audio {
@ -499,8 +479,72 @@ mod audio {
use assets::*; use assets::*;
mod assets { mod assets {
use std::path::PathBuf;
use super::*; use super::*;
#[derive(Debug, Event)]
pub enum ImportAsset {
File(PathBuf),
Dir(PathBuf),
}
pub fn import_assets(
mut events: EventReader<FileDragAndDrop>,
mut writer: EventWriter<ImportAsset>,
) {
events.iter().for_each(|event| match event {
FileDragAndDrop::DroppedFile { path_buf, .. } => {
if path_buf.is_file() {
writer.send(ImportAsset::File(path_buf.clone()));
} else if path_buf.is_dir() {
writer.send(ImportAsset::Dir(path_buf.clone()));
} else {
warn!("Could not identify filetype for {:?}", path_buf)
}
}
_ => (),
})
}
pub fn import_file(
mut events: EventReader<ImportAsset>,
server: Res<AssetServer>,
mut registry: ResMut<AssetRegistry>,
) {
events
.iter()
.filter_map(|event| match event {
ImportAsset::File(path) => Some(path),
_ => None,
})
.for_each(|path| {
registry
.0
.push(server.load_untyped(String::from(path.to_string_lossy())));
});
}
pub fn import_folder(
mut events: EventReader<ImportAsset>,
server: Res<AssetServer>,
mut registry: ResMut<AssetRegistry>,
) {
events
.iter()
.filter_map(|event| match event {
ImportAsset::Dir(path) => Some(path),
_ => None,
})
.for_each(|path| {
registry.0.extend(
server
.load_folder(String::from(path.to_string_lossy()))
.expect("Loading assets from folder"),
);
});
}
pub fn get_asset_name<T: Asset>(server: &AssetServer, handle: Handle<T>) -> String { pub fn get_asset_name<T: Asset>(server: &AssetServer, handle: Handle<T>) -> String {
if let Some(asset_path) = server.get_handle_path(handle.clone()) { if let Some(asset_path) = server.get_handle_path(handle.clone()) {
if let Some(stem) = asset_path.path().file_stem() { if let Some(stem) = asset_path.path().file_stem() {
@ -1336,7 +1380,9 @@ mod reset {
mut registry: ResMut<AssetRegistry>, mut registry: ResMut<AssetRegistry>,
mut commands: Commands, mut commands: Commands,
) { ) {
events.iter().for_each(|entity| { events.iter().for_each(|_| {
info!("Clearing assets");
// Clear buttons holding asset references // Clear buttons holding asset references
asset_holders asset_holders
.iter() .iter()

@ -1,33 +1,67 @@
use std::{fs::File, io::Write}; // TODO:
// * Determine where local assets folder needs to be created
use bevy::{audio::PlaybackMode, prelude::*, tasks::IoTaskPool}; // * Create local assets folder
// * Recusrively laod that folder and watch for changes
// * Copy assets into local folder in leue of importing them
// * Check portability by moving binary + folder to new location
use std::{
fs::{DirBuilder, File},
io::Write,
time::Duration,
};
use bevy::{
asset::{Asset, ChangeWatcher},
audio::PlaybackMode,
gltf::Gltf,
prelude::*,
tasks::IoTaskPool,
};
use monologue_trees::{debug::*, ui}; use monologue_trees::{debug::*, ui};
fn main() { fn main() {
App::new() App::new()
.init_resource::<AssetRegistry>() .init_resource::<AssetRegistry>()
.add_plugins(( .add_plugins((
DefaultPlugins.set(WindowPlugin { DefaultPlugins
primary_window: Some(Window { .set(WindowPlugin {
title: "Serialization WTF".into(), primary_window: Some(Window {
resolution: (640., 480.).into(), title: "Serialization WTF".into(),
resolution: (640., 480.).into(),
..default()
}),
..default()
})
.set(AssetPlugin {
asset_folder: "assets".into(),
// Tell the asset server to watch for asset changes on disk:
watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(0)),
..default() ..default()
}), }),
..default()
}),
DebugInfoPlugin, DebugInfoPlugin,
ui::GameUiPlugin { ..default() }, ui::GameUiPlugin { ..default() },
)) ))
.add_systems(Startup, init) .add_systems(Startup, (init, init_assets_dir))
.add_systems( .add_systems(
Update, Update,
( (
export.run_if(interaction_condition::<ExportAction>), export.run_if(interaction_condition::<ExportAction>),
clear.run_if(interaction_condition::<ClearAction>), clear.run_if(interaction_condition::<ClearAction>),
import.run_if(interaction_condition::<ImportAction>), import.run_if(interaction_condition::<ImportAction>),
inspect.run_if(interaction_condition::<InspectAction>),
load.run_if(interaction_condition::<LoadAssetsAction>),
unload.run_if(interaction_condition::<UnloadAssetsAction>),
spawn_level.run_if(interaction_condition::<SpawnLevelAction>),
asset_inspector::<AudioSource>,
asset_inspector::<Scene>,
),
)
.add_systems(
PostUpdate,
(
rehydrate::<Visibility, ComputedVisibility>, rehydrate::<Visibility, ComputedVisibility>,
rehydrate::<Handle<AudioSource>, PlaybackSettings>, rehydrate::<Handle<AudioSource>, PlaybackSettings>,
inspect.run_if(interaction_condition::<InspectAction>),
fallback_camera.run_if(fallback_camera_condition), fallback_camera.run_if(fallback_camera_condition),
), ),
) )
@ -50,38 +84,37 @@ struct ImportAction;
#[derive(Debug, Component)] #[derive(Debug, Component)]
struct InspectAction; struct InspectAction;
#[derive(Debug, Component)]
struct LoadAssetsAction;
#[derive(Debug, Component)]
struct UnloadAssetsAction;
#[derive(Debug, Component)]
struct SpawnLevelAction;
#[derive(Debug, Resource, Default)] #[derive(Debug, Resource, Default)]
struct AssetRegistry { struct AssetRegistry {
handles: Vec<HandleUntyped>, handles: Vec<HandleUntyped>,
} }
fn init(server: Res<AssetServer>, mut commands: Commands, mut registry: ResMut<AssetRegistry>) { fn init_assets_dir() {
IoTaskPool::get()
.spawn(async move {
match DirBuilder::new().create("assets") {
Ok(_) => info!("Created assets directory"),
Err(e) => warn!("Error creating assets directory", e),
}
})
.detach();
}
fn init(mut commands: Commands) {
commands.spawn(( commands.spawn((
Camera2dBundle { ..default() }, Camera2dBundle { ..default() },
UiCameraConfig { show_ui: true }, UiCameraConfig { show_ui: true },
)); ));
let audio_handle: Handle<AudioSource> = server.load("audio/Ambient/Lake Sound 1.ogg");
let scene_handle: Handle<Scene> = server.load("models/materials.glb#Scene0");
commands
.spawn((SpatialBundle { ..default() }, LevelRoot))
.with_children(|parent| {
parent.spawn(AudioSourceBundle {
source: audio_handle.clone(),
settings: PlaybackSettings {
mode: PlaybackMode::Loop,
paused: false,
..default()
},
});
parent.spawn((SceneBundle {
scene: scene_handle.clone(),
..default()
},));
});
registry.handles.push(audio_handle.clone_untyped());
registry.handles.push(scene_handle.clone_untyped());
commands commands
.spawn(( .spawn((
NodeBundle { NodeBundle {
@ -101,6 +134,57 @@ fn init(server: Res<AssetServer>, mut commands: Commands, mut registry: ResMut<A
ui::Select::Action, ui::Select::Action,
)) ))
.with_children(|parent| { .with_children(|parent| {
parent.spawn((
ButtonBundle {
style: Style {
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: "Load Assets".into(),
..default()
},
LoadAssetsAction,
));
parent.spawn((
ButtonBundle {
style: Style {
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: "Dump Assets".into(),
..default()
},
UnloadAssetsAction,
));
parent.spawn((
ButtonBundle {
style: Style {
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(1.0)),
..default()
},
border_color: Color::BLACK.into(),
..default()
},
ui::Title {
text: "Spawn Level".into(),
..default()
},
SpawnLevelAction,
));
parent.spawn(( parent.spawn((
ButtonBundle { ButtonBundle {
style: Style { style: Style {
@ -269,6 +353,8 @@ fn clear(root: Query<Entity, With<LevelRoot>>, mut commands: Commands) {
}); });
} }
// TODO: Figure out how to import the same asset from a differnt source
// How do the plugins do it??
fn import(mut commands: Commands, server: Res<AssetServer>) { fn import(mut commands: Commands, server: Res<AssetServer>) {
info!("Importing level"); info!("Importing level");
@ -295,3 +381,47 @@ fn fallback_camera(
) { ) {
ui_camera.single_mut().is_active = cameras.iter().len() <= 0; ui_camera.single_mut().is_active = cameras.iter().len() <= 0;
} }
fn asset_inspector<T: Asset>(mut events: EventReader<AssetEvent<T>>) {
events.iter().for_each(|event| match event {
AssetEvent::Created { handle } => info!("Asset Created {:?}", handle),
AssetEvent::Modified { handle } => info!("Asset Modified {:?}", handle),
AssetEvent::Removed { handle } => info!("Asset Removed {:?}", handle),
});
}
// OK seems like `load_folder` does not automatically pick up added files
fn load(mut registry: ResMut<AssetRegistry>, server: Res<AssetServer>) {
info!("Loading assets");
registry.handles = server.load_folder("./dynamic").unwrap();
info!("Current files: {:?}", registry.handles);
}
fn unload(mut registry: ResMut<AssetRegistry>, mut gltfs: ResMut<Assets<Gltf>>) {
info!("Unloading asstes");
registry.handles.clear();
// This is required to clear scenes from asset cache
gltfs.clear();
}
fn spawn_level(mut commands: Commands, server: Res<AssetServer>) {
commands
.spawn((SpatialBundle { ..default() }, LevelRoot))
.with_children(|parent| {
parent.spawn(AudioSourceBundle {
source: server.load::<AudioSource, &str>("dynamic/Lake Sound 1.ogg"),
settings: PlaybackSettings {
mode: PlaybackMode::Loop,
paused: false,
..default()
},
});
parent.spawn((SceneBundle {
scene: server.load("dynamic/materials.glb#Scene0"),
..default()
},));
});
}

@ -439,33 +439,39 @@ mod buttons {
) { ) {
events events
.iter() .iter()
.filter(|(_, _, _, &interaction)| interaction == Interaction::Pressed) .for_each(|(entity, parent, active, interaction)| {
.for_each(|(entity, parent, active, _)| {
selects selects
.get(parent.get()) .get(parent.get())
.iter() .iter()
.for_each(|(select, children)| { .for_each(|(select, children)| match interaction {
match active { Interaction::Pressed => {
Some(_) => { match active {
commands.entity(entity).remove::<Active>(); Some(_) => {
commands.entity(entity).remove::<Active>();
}
None => {
commands.entity(entity).insert(Active);
}
} }
None => { match select {
commands.entity(entity).insert(Active); Select::Multi | Select::Action => (),
Select::Single => {
children.iter().filter(|&child| *child != entity).for_each(
|&child| {
commands.entity(child).remove::<Active>();
},
);
}
} }
} }
match select { // A silly hack to get actions to maintain the active tag for 1+ frames
Interaction::None => match select {
Select::Action => { Select::Action => {
commands.entity(entity).remove::<Active>(); commands.entity(entity).remove::<Active>();
} }
Select::Multi => (), _ => (),
Select::Single => { },
children.iter().filter(|&child| *child != entity).for_each( _ => (),
|&child| {
commands.entity(child).remove::<Active>();
},
);
}
}
}); });
}); });
} }

Loading…
Cancel
Save