refactoring
This commit is contained in:
parent
1906366463
commit
d90c2f82a6
|
@ -8,7 +8,7 @@ use bevy::transform::TransformSystem;
|
||||||
use bevy::math::{DVec3, DQuat};
|
use bevy::math::{DVec3, DQuat};
|
||||||
use bevy_xpbd_3d::prelude::*;
|
use bevy_xpbd_3d::prelude::*;
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
use crate::{settings, audio, actor};
|
use crate::{actor, audio, hud, settings};
|
||||||
|
|
||||||
pub struct CameraPlugin;
|
pub struct CameraPlugin;
|
||||||
|
|
||||||
|
@ -334,3 +334,37 @@ fn apply_input_to_player(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the closest world object that the player is looking at
|
||||||
|
pub fn find_closest_target(
|
||||||
|
q_objects: Query<(Entity, &Transform), (With<hud::IsClickable>, Without<hud::IsTargeted>)>,
|
||||||
|
q_camera: Query<&Transform, With<Camera>>,
|
||||||
|
) -> (Option<Entity>, f32)
|
||||||
|
{
|
||||||
|
let mut closest_entity: Option<Entity> = None;
|
||||||
|
let mut closest_distance: f32 = f32::MAX;
|
||||||
|
if let Ok(camtrans) = q_camera.get_single() {
|
||||||
|
let target_vector = (camtrans.rotation * Vec3::new(0.0, 0.0, -1.0))
|
||||||
|
.normalize_or_zero();
|
||||||
|
let field_of_view = 20.0f32.to_radians();
|
||||||
|
let max_angle = field_of_view / 2.0;
|
||||||
|
for (entity, trans) in &q_objects {
|
||||||
|
// Use Transform instead of Position because we're basing this
|
||||||
|
// not on the player mesh but on the camera, which doesn't have a position.
|
||||||
|
let pos_vector = (trans.translation - camtrans.translation)
|
||||||
|
.normalize_or_zero();
|
||||||
|
let cosine_of_angle = target_vector.dot(pos_vector);
|
||||||
|
let angle = cosine_of_angle.acos();
|
||||||
|
if angle <= max_angle {
|
||||||
|
// It's in the field of view!
|
||||||
|
//commands.entity(entity).insert(IsTargeted);
|
||||||
|
let distance = trans.translation.distance(camtrans.translation);
|
||||||
|
if distance < closest_distance {
|
||||||
|
closest_distance = distance;
|
||||||
|
closest_entity = Some(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (closest_entity, closest_distance);
|
||||||
|
}
|
||||||
|
|
33
src/hud.rs
33
src/hud.rs
|
@ -1,4 +1,4 @@
|
||||||
use crate::{actor, audio, chat, nature, settings};
|
use crate::{actor, audio, camera, chat, nature, settings};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin};
|
use bevy::diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin};
|
||||||
use bevy_xpbd_3d::prelude::*;
|
use bevy_xpbd_3d::prelude::*;
|
||||||
|
@ -600,35 +600,8 @@ fn handle_input(
|
||||||
if mouse_input.just_pressed(settings.key_selectobject) {
|
if mouse_input.just_pressed(settings.key_selectobject) {
|
||||||
//ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Switch));
|
//ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Switch));
|
||||||
if q_target.is_empty() {
|
if q_target.is_empty() {
|
||||||
if let Ok(camtrans) = q_camera.get_single() {
|
if let (Some(entity), _dist) = camera::find_closest_target(q_objects, q_camera) {
|
||||||
let mut closest_entity: Option<Entity> = None;
|
commands.entity(entity).insert(IsTargeted);
|
||||||
let mut closest_distance: f32 = f32::MAX;
|
|
||||||
let target_vector = (camtrans.rotation * Vec3::new(0.0, 0.0, -1.0))
|
|
||||||
.normalize_or_zero();
|
|
||||||
let field_of_view = 20.0f32.to_radians();
|
|
||||||
let max_angle = field_of_view / 2.0;
|
|
||||||
let max_cosine_of_angle = max_angle.cos();
|
|
||||||
//let maximum_cosine_of_angle = (field_of_view / 2.0).cos();
|
|
||||||
for (entity, trans) in &q_objects {
|
|
||||||
// Use Transform instead of Position because we're basing this
|
|
||||||
// not on the player mesh but on the camera, which doesn't have a position.
|
|
||||||
let pos_vector = (trans.translation - camtrans.translation)
|
|
||||||
.normalize_or_zero();
|
|
||||||
let cosine_of_angle = target_vector.dot(pos_vector);
|
|
||||||
let angle = cosine_of_angle.acos();
|
|
||||||
if angle <= max_angle {
|
|
||||||
// It's in the field of view!
|
|
||||||
//commands.entity(entity).insert(IsTargeted);
|
|
||||||
let distance = trans.translation.distance(camtrans.translation);
|
|
||||||
if distance < closest_distance {
|
|
||||||
closest_distance = distance;
|
|
||||||
closest_entity = Some(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(entity) = closest_entity {
|
|
||||||
commands.entity(entity).insert(IsTargeted);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in a new issue