From 17a2ed676b456abba0092ae0f31c58f8c3144943 Mon Sep 17 00:00:00 2001 From: extrawurst Date: Wed, 12 Mar 2025 09:07:18 +0100 Subject: [PATCH] test billboard --- Cargo.lock | 10 ++++++++++ Cargo.toml | 1 + src/billboards.rs | 38 ++++++++++++++++++++++++++++++++++++++ src/main.rs | 2 ++ src/npc.rs | 0 src/player.rs | 16 ++++++++++++++++ 6 files changed, 67 insertions(+) create mode 100644 src/billboards.rs create mode 100644 src/npc.rs diff --git a/Cargo.lock b/Cargo.lock index 58d40d5..e4bcaf1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1268,6 +1268,15 @@ dependencies = [ "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]] name = "bevy_state" version = "0.15.3" @@ -2808,6 +2817,7 @@ dependencies = [ "bevy-tnua-avian3d", "bevy_asset_loader", "bevy_dolly", + "bevy_sprite3d", "bevy_trenchbroom", "nil", ] diff --git a/Cargo.toml b/Cargo.toml index 145ebd4..fc351e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ bevy-tnua = "0.21.0" bevy-tnua-avian3d = "0.2.0" bevy_dolly = { version = "0.0.5", default-features = false } bevy_asset_loader = "0.22.0" +bevy_sprite3d = "4.0.0" diff --git a/src/billboards.rs b/src/billboards.rs new file mode 100644 index 0000000..71b9ed2 --- /dev/null +++ b/src/billboards.rs @@ -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::() { + app.add_plugins(Sprite3dPlugin); + } + + app.register_type::(); + app.add_systems(Update, face_camera); +} + +fn face_camera( + cam_query: Query<&GlobalTransform, With>, + mut query: Query< + (&mut Transform, &Parent, &InheritedVisibility), + (With, Without), + >, + 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); + } +} diff --git a/src/main.rs b/src/main.rs index b007d30..005d04f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod alien; +mod billboards; mod camera; mod cash; mod gates; @@ -72,6 +73,7 @@ fn main() { app.add_plugins(gates::plugin); app.add_plugins(platforms::plugin); app.add_plugins(movables::plugin); + app.add_plugins(billboards::plugin); app.insert_resource(AmbientLight { color: Color::WHITE, diff --git a/src/npc.rs b/src/npc.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/player.rs b/src/player.rs index 50ad00b..56b4e60 100644 --- a/src/player.rs +++ b/src/player.rs @@ -3,6 +3,7 @@ use std::{f32::consts::PI, time::Duration}; use crate::{ DebugVisuals, alien::{ALIEN_ASSET_PATH, Animations}, + billboards::Billboard, camera::GameCameraRig, cash::{Cash, CashCollectEvent}, heads_ui::HeadChanged, @@ -15,6 +16,7 @@ use bevy::{ window::{CursorGrabMode, PrimaryWindow}, }; use bevy_dolly::prelude::Rig; +use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams}; use bevy_tnua::{TnuaUserControlsSystemSet, prelude::*}; use bevy_tnua_avian3d::TnuaAvian3dSensorShape; @@ -68,6 +70,7 @@ fn spawn( asset_server: Res, query: Query<&Transform, With>, mut player_spawned: ResMut, + mut sprite_params: Sprite3dParams, ) { if player_spawned.spawned { return; @@ -81,6 +84,7 @@ fn spawn( let mesh = asset_server .load(GltfAssetLabel::Scene(0).from_asset("models/heads/angry demonstrator.glb")); + let selector = asset_server.load("ui/selector.png"); commands .spawn(( @@ -109,6 +113,18 @@ fn spawn( .with_rotation(Quat::from_rotation_y(std::f32::consts::PI)) .with_scale(Vec3::splat(1.5)), 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((