beginning of interaction

This commit is contained in:
LorrensP-2158466
2025-04-05 22:11:24 +02:00
parent 4a9dc86fc0
commit 8fc63fdb50
10 changed files with 3301 additions and 447 deletions

View File

@@ -0,0 +1 @@

8
src/interaction/mod.rs Normal file
View File

@@ -0,0 +1,8 @@
use bevy::prelude::*;
mod objects;
mod ui;
pub fn plugin(app: &mut App) {
app.add_plugins((ui::plugin, objects::plugin));
}

View File

@@ -0,0 +1,28 @@
use bevy::prelude::*;
use crate::{GameState, asset_loading::GltfAssets};
pub fn plugin(app: &mut App) {
app.add_systems(OnEnter(GameState::Playing), spawn);
}
#[derive(Component)]
pub struct Interact;
fn spawn(mut commands: Commands, models: Res<Assets<Gltf>>, gltf_assets: Res<GltfAssets>) {
let hammer = gltf_assets
.library
.get("meshes/library/hammer.glb")
.unwrap();
let hammer = models.get(hammer).unwrap();
let asset = hammer.default_scene.as_ref().unwrap();
// hammer
commands.spawn((
Transform::from_xyz(0.0, 1.0, 0.0).with_scale(Vec3::splat(0.1)),
Interact,
SceneRoot(asset.clone()),
));
//tools
}

78
src/interaction/ui.rs Normal file
View File

@@ -0,0 +1,78 @@
use crate::GameState;
use crate::player::{Player, PlayerAction};
use crate::util::{single, single_mut};
use bevy::{prelude::*, window::PrimaryWindow};
use bevy_egui::{EguiContexts, EguiPlugin, egui};
use std::f32::consts::TAU;
use super::objects::Interact;
pub(super) fn plugin(app: &mut App) {
app.add_plugins(EguiPlugin)
.init_resource::<InteractionOpportunity>()
.add_systems(
Update,
(update_interaction_opportunities, display_interaction_prompt)
.chain()
.run_if(in_state(GameState::Playing)),
);
}
#[derive(Debug, Clone, Eq, PartialEq, Resource, Default)]
struct InteractionOpportunity(Option<Entity>);
fn update_interaction_opportunities(
player_query: Query<&GlobalTransform, With<Player>>,
parents: Query<&Parent>,
target_query: Query<
(Entity, &GlobalTransform),
(Without<Player>, Without<Camera>, With<Interact>),
>,
mut interaction_opportunity: ResMut<InteractionOpportunity>,
) {
interaction_opportunity.0 = None;
let player_transform = single!(player_query);
let (target_entity, target_transform) = single!(target_query);
let player_translation = player_transform.translation();
let target_translation = target_transform.translation();
if player_translation.distance(target_translation) <= 2.0 {
interaction_opportunity.0.replace(target_entity);
}
}
fn is_facing_target(
player: Vec3,
target: Vec3,
camera_transform: Transform,
camera: &Camera,
) -> bool {
let camera_to_player = camera_transform.forward();
let player_to_target = target - player;
let angle = camera_to_player.angle_between(player_to_target);
angle < TAU / 8.
}
fn display_interaction_prompt(
interaction_opportunity: Res<InteractionOpportunity>,
mut egui_contexts: EguiContexts,
action: Query<&PlayerAction, With<Player>>,
primary_windows: Query<&Window, With<PrimaryWindow>>,
) {
let Some(opportunity) = interaction_opportunity.0 else {
return;
};
let window = single!(primary_windows);
egui::Window::new("Interaction")
.collapsible(false)
.title_bar(false)
.auto_sized()
.fixed_pos(egui::Pos2::new(window.width() / 2., window.height() / 2.))
.show(egui_contexts.ctx_mut(), |ui| {
ui.label("E: Pick Up");
});
let action = single!(action);
}