line of sight check
This commit is contained in:
@@ -4,9 +4,11 @@ use crate::{
|
|||||||
GameState,
|
GameState,
|
||||||
billboards::Billboard,
|
billboards::Billboard,
|
||||||
loading_assets::UIAssets,
|
loading_assets::UIAssets,
|
||||||
|
physics_layers::GameLayer,
|
||||||
player::{Player, PlayerRig},
|
player::{Player, PlayerRig},
|
||||||
tb_entities::EnemySpawn,
|
tb_entities::EnemySpawn,
|
||||||
};
|
};
|
||||||
|
use avian3d::prelude::*;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams};
|
use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams};
|
||||||
use ops::sin;
|
use ops::sin;
|
||||||
@@ -93,6 +95,7 @@ fn update(
|
|||||||
query: Query<(Entity, &Transform), With<EnemySpawn>>,
|
query: Query<(Entity, &Transform), With<EnemySpawn>>,
|
||||||
player_pos: Query<&Transform, With<Player>>,
|
player_pos: Query<&Transform, With<Player>>,
|
||||||
player_rot: Query<&Transform, With<PlayerRig>>,
|
player_rot: Query<&Transform, With<PlayerRig>>,
|
||||||
|
spatial_query: SpatialQuery,
|
||||||
) {
|
) {
|
||||||
let Some(player_pos) = player_pos.iter().next().map(|t| t.translation) else {
|
let Some(player_pos) = player_pos.iter().next().map(|t| t.translation) else {
|
||||||
return;
|
return;
|
||||||
@@ -117,6 +120,10 @@ fn update(
|
|||||||
let angle = player_forward.angle_between(delta.normalize());
|
let angle = player_forward.angle_between(delta.normalize());
|
||||||
|
|
||||||
if angle < state.max_angle && distance < target_distance {
|
if angle < state.max_angle && distance < target_distance {
|
||||||
|
if !line_of_sight(&spatial_query, player_pos, delta, distance) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
new_target = Some(e);
|
new_target = Some(e);
|
||||||
target_distance = distance;
|
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>) {
|
fn move_marker(mut query: Query<&mut Transform, With<Marker>>, time: Res<Time>) {
|
||||||
for mut transform in query.iter_mut() {
|
for mut transform in query.iter_mut() {
|
||||||
transform.translation = Vec3::new(0., 3. + (sin(time.elapsed_secs() * 6.) * 0.2), 0.);
|
transform.translation = Vec3::new(0., 3. + (sin(time.elapsed_secs() * 6.) * 0.2), 0.);
|
||||||
|
|||||||
Reference in New Issue
Block a user