From 82555fdad2061fba7b7520e24eecb91a7aeef3c2 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 12 Nov 2023 06:35:49 +0600 Subject: [PATCH] fix: make bar face camera with rotation applied (#26) --- examples/rotation.rs | 167 +++++++++++++++++++++++++++++++++++++++++++ src/plugin.rs | 12 ++++ 2 files changed, 179 insertions(+) create mode 100644 examples/rotation.rs diff --git a/examples/rotation.rs b/examples/rotation.rs new file mode 100644 index 0000000..e40522f --- /dev/null +++ b/examples/rotation.rs @@ -0,0 +1,167 @@ +//! Example with multiple rotating meshes and a moving camera. +//! Bars always face the camera. + +use std::f32::consts::PI; + +use bevy::app::App; +use bevy::asset::Assets; +use bevy::pbr::*; +use bevy::prelude::*; +use bevy::utils::default; +use bevy::DefaultPlugins; +use bevy_inspector_egui::quick::WorldInspectorPlugin; + +use bevy_health_bar3d::prelude::{ + BarBundle, BarHeight, BarOffset, BarWidth, HealthBarPlugin, Percentage, +}; + +#[derive(Component, Reflect)] +struct Health { + max: f32, + current: f32, +} + +impl Percentage for Health { + fn value(&self) -> f32 { + self.current / self.max + } +} + +#[derive(Component)] +struct Jim; + +#[derive(Component)] +struct Tom; + +fn main() { + App::new() + .register_type::() + .add_plugins(( + DefaultPlugins, + WorldInspectorPlugin::new(), + HealthBarPlugin::::default(), + )) + .add_systems(Startup, setup) + .add_systems(Update, (rotate_camera, rotate_jim, rotate_tom)) + .run(); +} + +const TREX_GLTF: &str = "../examples/assets/models/trex.gltf"; + +fn setup( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, + asset_server: Res, +) { + let gltf_path = |id: &str| format!("{TREX_GLTF}#{id}"); + + // Ground + commands.spawn(PbrBundle { + mesh: meshes.add(Mesh::from(shape::Plane { + size: 5.0, + subdivisions: 0, + })), + material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), + ..default() + }); + + let scene = asset_server.load(gltf_path("Scene0")); + + // T-Rex Jim + commands.spawn(( + SceneBundle { + scene: scene.clone(), + transform: Transform { + translation: Vec3::new(-1., 0., 0.), + scale: Vec3::splat(0.04), + ..default() + }, + ..default() + }, + Health { + max: 10., + current: 8., + }, + BarBundle:: { + offset: BarOffset::new(18.), + height: BarHeight::Static(1.), + width: BarWidth::new(10.), + ..default() + }, + Jim, + Name::new("Jim"), + )); + + // T-Rex Tom + commands.spawn(( + SceneBundle { + scene: scene.clone(), + transform: Transform { + translation: Vec3::new(1., 0.75, 0.), + scale: Vec3::splat(0.04), + ..default() + }, + ..default() + }, + Health { + max: 10., + current: 3., + }, + BarBundle:: { + // Have to locate it higher than Jim's so there is no clipping during rotation + offset: BarOffset::new(21.), + height: BarHeight::Static(1.), + width: BarWidth::new(10.), + ..default() + }, + Tom, + Name::new("Tom"), + )); + + // Light + commands.spawn(PointLightBundle { + transform: Transform::from_xyz(4.0, 8.0, 4.0), + point_light: PointLight { + intensity: 1500.0, + shadows_enabled: true, + ..default() + }, + ..default() + }); + + // Camera + commands.spawn(Camera3dBundle { + transform: Transform::from_xyz(0., 3.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y), + ..default() + }); +} + +fn rotate_camera( + mut camera_query: Query<&mut Transform, With>, + mut angle: Local, + time: Res