line of sight check

This commit is contained in:
2025-04-03 21:07:57 +02:00
parent 5607c60223
commit 64acdd4007

View File

@@ -4,9 +4,11 @@ use crate::{
GameState,
billboards::Billboard,
loading_assets::UIAssets,
physics_layers::GameLayer,
player::{Player, PlayerRig},
tb_entities::EnemySpawn,
};
use avian3d::prelude::*;
use bevy::prelude::*;
use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams};
use ops::sin;
@@ -93,6 +95,7 @@ fn update(
query: Query<(Entity, &Transform), With<EnemySpawn>>,
player_pos: Query<&Transform, With<Player>>,
player_rot: Query<&Transform, With<PlayerRig>>,
spatial_query: SpatialQuery,
) {
let Some(player_pos) = player_pos.iter().next().map(|t| t.translation) else {
return;
@@ -117,6 +120,10 @@ fn update(
let angle = player_forward.angle_between(delta.normalize());
if angle < state.max_angle && distance < target_distance {
if !line_of_sight(&spatial_query, player_pos, delta, distance) {
continue;
}
new_target = Some(e);
target_distance = distance;
}
@@ -139,6 +146,32 @@ fn update(
}
}
fn line_of_sight(
spatial_query: &SpatialQuery<'_, '_>,
player_pos: Vec3,
delta: Vec3,
distance: f32,
) -> bool {
if let Some(_hit) = spatial_query.cast_shape(
&Collider::sphere(0.1),
player_pos + -delta.normalize(),
Quat::default(),
Dir3::new(-delta).unwrap(),
&ShapeCastConfig {
max_distance: distance * 0.98,
compute_contact_on_penetration: false,
ignore_origin_penetration: true,
..Default::default()
},
&SpatialQueryFilter::default().with_mask(LayerMask(GameLayer::Level.to_bits())),
) {
// info!("no line of sight");
return false;
};
true
}
fn move_marker(mut query: Query<&mut Transform, With<Marker>>, time: Res<Time>) {
for mut transform in query.iter_mut() {
transform.translation = Vec3::new(0., 3. + (sin(time.elapsed_secs() * 6.) * 0.2), 0.);