//! - Simple 3D Scene with a character (sphere). //! - Can be moved around with WASD/arrow keys. //! - A health bar and character name is anchored to the character in world-space. //! - The health starts at 10 and decreases by 1 every second. The health should be stored and //! managed in Bevy ECS. When reaching 0 HP, the character should be despawned together with UI. use bevy::prelude::*; use colorgrad::{self, Gradient}; use haalka::prelude::*; fn main() { App::new() .add_plugins(( DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { position: WindowPosition::Centered(MonitorSelection::Primary), ..default() }), ..default() }), HaalkaPlugin, )) .add_systems(PreStartup, setup) .add_systems(Startup, ui_root) .add_systems( Update, ( movement, sync_tracking_healthbar_position, decay, sync_health_mutable, despawn_when_dead, ) .chain() .run_if(any_with_component::), ) .add_systems(Update, spawn_player.run_if(on_event::())) .insert_resource(StyleDataResource::default()) .insert_resource(HealthTickTimer(Timer::from_seconds( HEALTH_TICK_RATE, TimerMode::Repeating, ))) .insert_resource(HealthOptionMutable(default())) .add_event::() .run(); } const SPEED: f32 = 10.0; const RADIUS: f32 = 0.5; const MINI: (f32, f32) = (200., 30.); const MAXI: (f32, f32) = (500., 60.); const NAME: &str = "avi"; const CAMERA_POSITION: Vec3 = Vec3::new(8., 10.5, 8.); const PLAYER_POSITION: Vec3 = Vec3::new(0., RADIUS, 0.); const PLAYER_HEALTH: u32 = 10; const HEALTH_TICK_RATE: f32 = 1.; #[derive(Clone, Copy, Default, PartialEq)] struct StyleData { left: f32, top: f32, scale: f32, } #[derive(Resource, Default)] struct StyleDataResource(Mutable); #[derive(Component)] struct Health(u32); #[derive(Component)] struct HealthMutable(Mutable); fn sync_health_mutable(health_query: Query<(&Health, &HealthMutable), Changed>) { if let Ok((health, health_mutable)) = health_query.get_single() { health_mutable.0.set(health.0); } } #[derive(Component)] struct Player; fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, mut spawn_player: EventWriter, ) { commands.spawn(PbrBundle { mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)), material: materials.add(Color::srgb_u8(87, 108, 50)), ..default() }); commands.spawn(PointLightBundle { point_light: PointLight { shadows_enabled: true, intensity: 1_500_000., range: 100., ..default() }, transform: Transform::from_xyz(0., 8., 0.), ..default() }); commands.spawn(Camera3dBundle { transform: Transform::from_translation(CAMERA_POSITION).looking_at(Vec3::ZERO, Vec3::Y), ..default() }); spawn_player.send_default(); } fn movement( keys: Res>, camera: Query<&Transform, (With, Without)>, mut player: Query<&mut Transform, With>, time: Res