2023-10-13 10:53:26 +00:00
use bevy ::{ asset ::ChangeWatcher , gltf ::Gltf , prelude ::* } ;
2023-07-25 20:58:08 +00:00
use bevy_editor_pls ::prelude ::* ;
2023-08-01 23:45:57 +00:00
use bevy_gltf_components ::ComponentsFromGltfPlugin ;
2023-10-13 10:53:26 +00:00
use bevy_rapier3d ::prelude ::* ;
use std ::time ::Duration ;
2023-07-25 20:58:08 +00:00
2023-07-26 21:59:28 +00:00
mod core ;
use crate ::core ::* ;
2023-07-25 20:58:08 +00:00
2023-07-26 21:59:28 +00:00
mod game ;
2023-07-27 13:14:17 +00:00
use game ::* ;
mod test_components ;
use test_components ::* ;
2023-07-25 20:58:08 +00:00
2023-10-13 10:53:26 +00:00
#[ derive(Component, Reflect, Default, Debug) ]
2023-07-25 20:58:08 +00:00
#[ reflect(Component) ]
2023-07-26 21:59:28 +00:00
/// helper marker component
2023-07-25 20:58:08 +00:00
pub struct LoadedMarker ;
#[ derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States) ]
enum AppState {
#[ default ]
Loading ,
Running ,
}
2023-10-13 10:53:26 +00:00
fn main ( ) {
2023-07-25 20:58:08 +00:00
App ::new ( )
2023-10-13 10:53:26 +00:00
. add_plugins ( (
DefaultPlugins . set ( AssetPlugin {
2023-07-25 20:58:08 +00:00
// This tells the AssetServer to watch for changes to assets.
// 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
watch_for_changes : ChangeWatcher ::with_delay ( Duration ::from_millis ( 50 ) ) ,
.. default ( )
2023-10-13 10:53:26 +00:00
} ) ,
// editor
EditorPlugin ::default ( ) ,
// physics
RapierPhysicsPlugin ::< NoUserData > ::default ( ) ,
RapierDebugRenderPlugin ::default ( ) ,
// our custom plugins
ComponentsFromGltfPlugin ,
CorePlugin , // reusable plugins
DemoPlugin , // specific to our game
ComponentsTestPlugin , // Showcases different type of components /structs
) )
. add_state ::< AppState > ( )
. add_systems ( Startup , setup )
. add_systems ( Update , ( spawn_level . run_if ( in_state ( AppState ::Loading ) ) , ) )
. run ( ) ;
2023-07-25 20:58:08 +00:00
}
#[ derive(Resource) ]
2023-08-01 23:45:57 +00:00
struct AssetLoadHelper ( Handle < Scene > ) ;
2023-10-13 10:53:26 +00:00
// 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
2023-07-25 20:58:08 +00:00
// of assets from the spawning
2023-08-01 23:45:57 +00:00
// AssetLoadHelper is also just for the same purpose, you do not need it in a real scenario
2023-10-13 10:53:26 +00:00
// the states here are also for demo purposes only,
fn setup ( mut commands : Commands , asset_server : Res < AssetServer > ) {
let tmp : Handle < Scene > = asset_server . load ( " basic/models/level1.glb#Scene0 " ) ;
2023-08-01 23:45:57 +00:00
commands . insert_resource ( AssetLoadHelper ( tmp ) ) ;
2023-07-25 20:58:08 +00:00
}
fn spawn_level (
mut commands : Commands ,
scene_markers : Query < & LoadedMarker > ,
2023-08-01 23:45:57 +00:00
preloaded_scene : Res < AssetLoadHelper > ,
2023-07-25 20:58:08 +00:00
mut asset_event_reader : EventReader < AssetEvent < Gltf > > ,
mut next_state : ResMut < NextState < AppState > > ,
2023-10-13 10:53:26 +00:00
) {
2023-07-25 20:58:08 +00:00
if let Some ( asset_event ) = asset_event_reader . iter ( ) . next ( ) {
match asset_event {
AssetEvent ::Created { handle : _ } = > {
info! ( " GLTF loaded " ) ;
if scene_markers . is_empty ( ) {
info! ( " spawning scene " ) ;
2023-10-13 10:53:26 +00:00
commands . spawn ( (
SceneBundle {
scene : preloaded_scene . 0. clone ( ) ,
.. default ( )
} ,
LoadedMarker ,
Name ::new ( " Level1 " ) ,
) ) ;
2023-07-25 20:58:08 +00:00
next_state . set ( AppState ::Running ) ;
}
}
2023-10-13 10:53:26 +00:00
_ = > ( ) ,
2023-07-25 20:58:08 +00:00
}
}
}