75 lines
2.0 KiB
Rust
75 lines
2.0 KiB
Rust
use crate::camera::MainCamera;
|
|
use bevy::prelude::*;
|
|
use bevy_sprite3d::Sprite3dPlugin;
|
|
|
|
#[derive(Component, Reflect, Default, PartialEq, Eq)]
|
|
#[reflect(Component)]
|
|
pub enum Billboard {
|
|
#[default]
|
|
All,
|
|
XZ,
|
|
}
|
|
|
|
pub fn plugin(app: &mut App) {
|
|
if !app.is_plugin_added::<Sprite3dPlugin>() {
|
|
app.add_plugins(Sprite3dPlugin);
|
|
}
|
|
|
|
app.register_type::<Billboard>();
|
|
app.add_systems(Update, (face_camera, face_camera_no_parent));
|
|
}
|
|
|
|
fn face_camera(
|
|
cam_query: Query<&GlobalTransform, With<MainCamera>>,
|
|
mut query: Query<
|
|
(&mut Transform, &ChildOf, &InheritedVisibility, &Billboard),
|
|
Without<MainCamera>,
|
|
>,
|
|
parent_transform: Query<&GlobalTransform>,
|
|
) {
|
|
let Ok(cam_transform) = cam_query.single() else {
|
|
return;
|
|
};
|
|
|
|
for (mut transform, parent, visible, billboard) in query.iter_mut() {
|
|
if !matches!(*visible, InheritedVisibility::VISIBLE) {
|
|
continue;
|
|
}
|
|
|
|
let Ok(parent_global) = parent_transform.get(parent.parent()) else {
|
|
continue;
|
|
};
|
|
|
|
let target = cam_transform.reparented_to(parent_global);
|
|
|
|
let target = match *billboard {
|
|
Billboard::All => target.translation,
|
|
Billboard::XZ => Vec3::new(
|
|
target.translation.x,
|
|
transform.translation.y,
|
|
target.translation.z,
|
|
),
|
|
};
|
|
|
|
transform.look_at(target, Vec3::Y);
|
|
}
|
|
}
|
|
|
|
fn face_camera_no_parent(
|
|
cam_query: Query<&GlobalTransform, With<MainCamera>>,
|
|
mut query: Query<(&mut Transform, &Billboard), (Without<MainCamera>, Without<ChildOf>)>,
|
|
) {
|
|
let Ok(cam_transform) = cam_query.single() else {
|
|
return;
|
|
};
|
|
for (mut transform, billboard) in query.iter_mut() {
|
|
let target = cam_transform.translation();
|
|
let target = match *billboard {
|
|
Billboard::All => cam_transform.translation(),
|
|
Billboard::XZ => Vec3::new(target.x, transform.translation.y, target.z),
|
|
};
|
|
|
|
transform.look_at(target, Vec3::Y);
|
|
}
|
|
}
|