2023-07-25 20:58:08 +00:00
use std ::time ::Duration ;
use bevy ::{ prelude ::* , asset ::ChangeWatcher , gltf ::Gltf } ;
use bevy_editor_pls ::prelude ::* ;
use bevy_rapier3d ::prelude ::* ;
2023-08-01 23:45:57 +00:00
use bevy_gltf_components ::ComponentsFromGltfPlugin ;
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
#[ derive(Component, Reflect, Default, Debug, ) ]
#[ 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 ,
}
fn main ( ) {
App ::new ( )
. add_plugins ( (
DefaultPlugins . set (
AssetPlugin {
// 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 ( )
}
) ,
// editor
EditorPlugin ::default ( ) ,
// physics
RapierPhysicsPlugin ::< NoUserData > ::default ( ) ,
RapierDebugRenderPlugin ::default ( ) ,
// our custom plugins
2023-08-01 23:45:57 +00:00
ComponentsFromGltfPlugin ,
2023-07-26 21:59:28 +00:00
CorePlugin , // reusable plugins
2023-07-27 13:14:17 +00:00
DemoPlugin , // specific to our game
ComponentsTestPlugin // Showcases different type of components /structs
2023-07-25 20:58:08 +00:00
) )
. add_state ::< AppState > ( )
. add_systems ( Startup , setup )
. add_systems ( Update , (
spawn_level . run_if ( in_state ( AppState ::Loading ) ) ,
) )
. run ( ) ;
}
#[ derive(Resource) ]
2023-08-01 23:45:57 +00:00
struct AssetLoadHelper ( Handle < Scene > ) ;
2023-07-25 20:58:08 +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
// 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-07-25 20:58:08 +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 ( " 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 > > ,
) {
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 " ) ;
commands . spawn (
(
SceneBundle {
scene : preloaded_scene . 0. clone ( ) ,
.. default ( )
} ,
LoadedMarker ,
Name ::new ( " Level1 " )
)
) ;
next_state . set ( AppState ::Running ) ;
}
}
_ = > ( )
}
}
}