feat: added sound events for enemy awareness
This commit is contained in:
parent
1373656f90
commit
66aede32bd
15 changed files with 234 additions and 16 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#include "player_detector.h"
|
||||
#include "sound_event_patchboard.h"
|
||||
|
||||
String PlayerDetector::sig_awareness_changed{ "awareness_changed" };
|
||||
|
||||
|
|
@ -6,6 +7,17 @@ void PlayerDetector::_bind_methods() {
|
|||
ADD_SIGNAL(MethodInfo(sig_awareness_changed, PropertyInfo(Variant::BOOL, "aware")));
|
||||
}
|
||||
|
||||
// check if there is geometry between detector and player
|
||||
bool PlayerDetector::line_of_sight_exists() const {
|
||||
PhysicsDirectSpaceState3D::RayParameters params{ this->ray_params };
|
||||
params.from = get_global_position();
|
||||
params.to = PlayerBody::get_singleton()->get_global_position();
|
||||
PhysicsDirectSpaceState3D *space{ get_world_3d()->get_direct_space_state() };
|
||||
PhysicsDirectSpaceState3D::RayResult result{};
|
||||
space->intersect_ray(params, result);
|
||||
return result.collider == nullptr;
|
||||
}
|
||||
|
||||
// Check if the player is in a bounded area in front of the detector and unobscured.
|
||||
// As all tests are required to pass, we do them in increasing order of complexity, to minimize unneeded resource use.
|
||||
bool PlayerDetector::check() const {
|
||||
|
|
@ -13,24 +25,18 @@ bool PlayerDetector::check() const {
|
|||
Vector3 const position{ get_global_position() };
|
||||
Vector3 const target{ PlayerBody::get_singleton()->get_global_position() + Vector3{ 0.f, 1.5f, 0.f } };
|
||||
// check if the target is in a view cone
|
||||
if (forward.dot(target - position) < this->min_dot) {
|
||||
if (forward.dot(target - position) < this->min_sight_dot) {
|
||||
return false;
|
||||
}
|
||||
// check if the target is in range
|
||||
if (position.distance_squared_to(target) > this->max_distance * this->max_distance) {
|
||||
if (position.distance_squared_to(target) > this->max_sight_range * this->max_sight_range) {
|
||||
return false;
|
||||
}
|
||||
// check if the target is obscured
|
||||
PhysicsDirectSpaceState3D::RayParameters params{ this->ray_params };
|
||||
params.from = position;
|
||||
params.to = target;
|
||||
PhysicsDirectSpaceState3D *space{ get_world_3d()->get_direct_space_state() };
|
||||
PhysicsDirectSpaceState3D::RayResult result{};
|
||||
space->intersect_ray(params, result);
|
||||
return result.collider == nullptr;
|
||||
return line_of_sight_exists();
|
||||
}
|
||||
|
||||
void PlayerDetector::ready() {
|
||||
SoundEventPatchboard::get_singleton()->connect(SoundEventPatchboard::sig_sound_triggered, callable_mp(this, &self_type::on_player_sound));
|
||||
this->ray_params.exclude.insert(PlayerBody::get_singleton()->get_rid());
|
||||
}
|
||||
|
||||
|
|
@ -46,6 +52,12 @@ void PlayerDetector::process(double delta) {
|
|||
}
|
||||
}
|
||||
|
||||
void PlayerDetector::on_player_sound(Vector3 at, float range) {
|
||||
if (get_global_position().distance_squared_to(at) <= range * range && line_of_sight_exists()) {
|
||||
set_aware_of_player(true);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerDetector::set_aware_of_player(bool value) {
|
||||
emit_signal(sig_awareness_changed, value);
|
||||
this->aware_of_player = value;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue