test billboard

This commit is contained in:
2025-03-12 09:07:18 +01:00
parent 20e68ab39e
commit 17a2ed676b
6 changed files with 67 additions and 0 deletions

10
Cargo.lock generated
View File

@@ -1268,6 +1268,15 @@ dependencies = [
"rectangle-pack", "rectangle-pack",
] ]
[[package]]
name = "bevy_sprite3d"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11512eeb84d4106da2bc9bcd2434a2ab9a32da1ee1794c27a7aa55f1df761268"
dependencies = [
"bevy",
]
[[package]] [[package]]
name = "bevy_state" name = "bevy_state"
version = "0.15.3" version = "0.15.3"
@@ -2808,6 +2817,7 @@ dependencies = [
"bevy-tnua-avian3d", "bevy-tnua-avian3d",
"bevy_asset_loader", "bevy_asset_loader",
"bevy_dolly", "bevy_dolly",
"bevy_sprite3d",
"bevy_trenchbroom", "bevy_trenchbroom",
"nil", "nil",
] ]

View File

@@ -16,3 +16,4 @@ bevy-tnua = "0.21.0"
bevy-tnua-avian3d = "0.2.0" bevy-tnua-avian3d = "0.2.0"
bevy_dolly = { version = "0.0.5", default-features = false } bevy_dolly = { version = "0.0.5", default-features = false }
bevy_asset_loader = "0.22.0" bevy_asset_loader = "0.22.0"
bevy_sprite3d = "4.0.0"

38
src/billboards.rs Normal file
View File

@@ -0,0 +1,38 @@
use bevy::prelude::*;
use bevy_sprite3d::Sprite3dPlugin;
#[derive(Component, Reflect)]
#[reflect(Component)]
pub struct Billboard;
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);
}
fn face_camera(
cam_query: Query<&GlobalTransform, With<Camera>>,
mut query: Query<
(&mut Transform, &Parent, &InheritedVisibility),
(With<Billboard>, Without<Camera>),
>,
parent_transform: Query<&GlobalTransform>,
) {
let cam_transform = cam_query.single();
for (mut transform, parent, visible) in query.iter_mut() {
if !matches!(*visible, InheritedVisibility::VISIBLE) {
continue;
}
let Ok(parent_global) = parent_transform.get(parent.get()) else {
continue;
};
let target = cam_transform.reparented_to(parent_global);
transform.look_at(target.translation, Vec3::Y);
}
}

View File

@@ -1,4 +1,5 @@
mod alien; mod alien;
mod billboards;
mod camera; mod camera;
mod cash; mod cash;
mod gates; mod gates;
@@ -72,6 +73,7 @@ fn main() {
app.add_plugins(gates::plugin); app.add_plugins(gates::plugin);
app.add_plugins(platforms::plugin); app.add_plugins(platforms::plugin);
app.add_plugins(movables::plugin); app.add_plugins(movables::plugin);
app.add_plugins(billboards::plugin);
app.insert_resource(AmbientLight { app.insert_resource(AmbientLight {
color: Color::WHITE, color: Color::WHITE,

0
src/npc.rs Normal file
View File

View File

@@ -3,6 +3,7 @@ use std::{f32::consts::PI, time::Duration};
use crate::{ use crate::{
DebugVisuals, DebugVisuals,
alien::{ALIEN_ASSET_PATH, Animations}, alien::{ALIEN_ASSET_PATH, Animations},
billboards::Billboard,
camera::GameCameraRig, camera::GameCameraRig,
cash::{Cash, CashCollectEvent}, cash::{Cash, CashCollectEvent},
heads_ui::HeadChanged, heads_ui::HeadChanged,
@@ -15,6 +16,7 @@ use bevy::{
window::{CursorGrabMode, PrimaryWindow}, window::{CursorGrabMode, PrimaryWindow},
}; };
use bevy_dolly::prelude::Rig; use bevy_dolly::prelude::Rig;
use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams};
use bevy_tnua::{TnuaUserControlsSystemSet, prelude::*}; use bevy_tnua::{TnuaUserControlsSystemSet, prelude::*};
use bevy_tnua_avian3d::TnuaAvian3dSensorShape; use bevy_tnua_avian3d::TnuaAvian3dSensorShape;
@@ -68,6 +70,7 @@ fn spawn(
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
query: Query<&Transform, With<SpawnPoint>>, query: Query<&Transform, With<SpawnPoint>>,
mut player_spawned: ResMut<PlayerSpawned>, mut player_spawned: ResMut<PlayerSpawned>,
mut sprite_params: Sprite3dParams,
) { ) {
if player_spawned.spawned { if player_spawned.spawned {
return; return;
@@ -81,6 +84,7 @@ fn spawn(
let mesh = asset_server let mesh = asset_server
.load(GltfAssetLabel::Scene(0).from_asset("models/heads/angry demonstrator.glb")); .load(GltfAssetLabel::Scene(0).from_asset("models/heads/angry demonstrator.glb"));
let selector = asset_server.load("ui/selector.png");
commands commands
.spawn(( .spawn((
@@ -109,6 +113,18 @@ fn spawn(
.with_rotation(Quat::from_rotation_y(std::f32::consts::PI)) .with_rotation(Quat::from_rotation_y(std::f32::consts::PI))
.with_scale(Vec3::splat(1.5)), .with_scale(Vec3::splat(1.5)),
SceneRoot(asset_server.load(GltfAssetLabel::Scene(0).from_asset(ALIEN_ASSET_PATH))), SceneRoot(asset_server.load(GltfAssetLabel::Scene(0).from_asset(ALIEN_ASSET_PATH))),
))
.with_child((
Billboard,
Transform::from_translation(Vec3::new(0., 1.5, 0.)),
Sprite3dBuilder {
image: selector,
pixels_per_metre: 40.,
alpha_mode: AlphaMode::Blend,
unlit: true,
..default()
}
.bundle(&mut sprite_params),
)); ));
commands.spawn(( commands.spawn((