From 66aede32bde0d35fb87ce2d63e03f3e7b6dea098 Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 4 Aug 2025 17:00:23 +0200 Subject: [PATCH] feat: added sound events for enemy awareness --- modules/wave_survival/hitscan_muzzle.cpp | 14 ++++++ modules/wave_survival/hitscan_muzzle.h | 4 ++ modules/wave_survival/muzzle_effect.cpp | 5 ++ modules/wave_survival/muzzle_effect.h | 14 ++++++ modules/wave_survival/player_detector.cpp | 32 +++++++++---- modules/wave_survival/player_detector.h | 11 ++++- modules/wave_survival/register_types.cpp | 9 ++++ modules/wave_survival/sound_event_node.cpp | 44 ++++++++++++++++++ modules/wave_survival/sound_event_node.h | 26 +++++++++++ .../wave_survival/sound_event_patchboard.cpp | 27 +++++++++++ .../wave_survival/sound_event_patchboard.h | 22 +++++++++ project/assets/models/weapons/revolver.blend | Bin 2278127 -> 2278127 bytes project/assets/models/weapons/revolver.blend1 | Bin 2276687 -> 2278127 bytes project/objects/weapons/revolver.tscn | 21 ++++++++- project/objects/weapons/rifle.tscn | 21 ++++++++- 15 files changed, 234 insertions(+), 16 deletions(-) create mode 100644 modules/wave_survival/muzzle_effect.cpp create mode 100644 modules/wave_survival/muzzle_effect.h create mode 100644 modules/wave_survival/sound_event_node.cpp create mode 100644 modules/wave_survival/sound_event_node.h create mode 100644 modules/wave_survival/sound_event_patchboard.cpp create mode 100644 modules/wave_survival/sound_event_patchboard.h diff --git a/modules/wave_survival/hitscan_muzzle.cpp b/modules/wave_survival/hitscan_muzzle.cpp index 54518ceb..df255f5a 100644 --- a/modules/wave_survival/hitscan_muzzle.cpp +++ b/modules/wave_survival/hitscan_muzzle.cpp @@ -2,6 +2,7 @@ #include "health_status.h" #include "hitbox.h" #include "macros.h" +#include "muzzle_effect.h" #include "scene/resources/packed_scene.h" void HitscanMuzzle::_bind_methods() { @@ -9,6 +10,7 @@ void HitscanMuzzle::_bind_methods() { BIND_PROPERTY(Variant::FLOAT, spread); BIND_PROPERTY(Variant::INT, damage); BIND_PROPERTY(Variant::INT, ray_count); + BIND_HPROPERTY(Variant::OBJECT, muzzle_effect, PROPERTY_HINT_NODE_TYPE, "MuzzleEffect"); } void HitscanMuzzle::instantiate_impact_effect() { @@ -45,6 +47,7 @@ void HitscanMuzzle::ready() { } else { print_error("HitscanMuzzle::ready: impact effect is invalid"); } + set_enabled(false); } @@ -62,6 +65,9 @@ void HitscanMuzzle::_notification(int what) { } void HitscanMuzzle::shoot() { + if (this->muzzle_effect != nullptr) { + this->muzzle_effect->GDVIRTUAL_CALL(trigger); + } for (int i{ this->ray_count }; i > 0; --i) { set_transform(this->home_transform); rotate_object_local(Vector3(0.f, 1.f, 0.f), Math::random(-Math::PI, Math::PI)); @@ -95,3 +101,11 @@ void HitscanMuzzle::set_ray_count(int amount) { int HitscanMuzzle::get_ray_count() const { return this->ray_count; } + +void HitscanMuzzle::set_muzzle_effect(MuzzleEffect *effect) { + this->muzzle_effect = effect; +} + +MuzzleEffect *HitscanMuzzle::get_muzzle_effect() const { + return this->muzzle_effect; +} diff --git a/modules/wave_survival/hitscan_muzzle.h b/modules/wave_survival/hitscan_muzzle.h index 357dd3f4..ac040a73 100644 --- a/modules/wave_survival/hitscan_muzzle.h +++ b/modules/wave_survival/hitscan_muzzle.h @@ -2,6 +2,7 @@ #define HITSCAN_MUZZLE_H #include "scene/3d/physics/ray_cast_3d.h" +class MuzzleEffect; class HitscanMuzzle : public RayCast3D { GDCLASS(HitscanMuzzle, RayCast3D); @@ -21,11 +22,14 @@ public: int get_damage() const; void set_ray_count(int amount); int get_ray_count() const; + void set_muzzle_effect(MuzzleEffect *effect); + MuzzleEffect *get_muzzle_effect() const; private: float spread{ 0.001f }; int damage{ 1 }; int ray_count{ 1 }; + MuzzleEffect *muzzle_effect{ nullptr }; Transform3D home_transform{}; Ref impact_effect{}; diff --git a/modules/wave_survival/muzzle_effect.cpp b/modules/wave_survival/muzzle_effect.cpp new file mode 100644 index 00000000..e7306c8a --- /dev/null +++ b/modules/wave_survival/muzzle_effect.cpp @@ -0,0 +1,5 @@ +#include "muzzle_effect.h" + +void MuzzleEffect::_bind_methods() { + GDVIRTUAL_BIND(trigger); +} diff --git a/modules/wave_survival/muzzle_effect.h b/modules/wave_survival/muzzle_effect.h new file mode 100644 index 00000000..fd257f96 --- /dev/null +++ b/modules/wave_survival/muzzle_effect.h @@ -0,0 +1,14 @@ +#ifndef MUZZLE_EFFECT_H +#define MUZZLE_EFFECT_H + +#include "scene/3d/node_3d.h" + +class MuzzleEffect : public Node3D { + GDCLASS(MuzzleEffect, Node3D); + static void _bind_methods(); + +public: + GDVIRTUAL0_REQUIRED(trigger); +}; + +#endif // !MUZZLE_EFFECT_H diff --git a/modules/wave_survival/player_detector.cpp b/modules/wave_survival/player_detector.cpp index 831e2502..5e005e2f 100644 --- a/modules/wave_survival/player_detector.cpp +++ b/modules/wave_survival/player_detector.cpp @@ -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; diff --git a/modules/wave_survival/player_detector.h b/modules/wave_survival/player_detector.h index 839e5b87..c21dd6f3 100644 --- a/modules/wave_survival/player_detector.h +++ b/modules/wave_survival/player_detector.h @@ -7,9 +7,11 @@ class PlayerDetector : public Node3D { GDCLASS(PlayerDetector, Node3D); static void _bind_methods(); + bool line_of_sight_exists() const; bool check() const; void ready(); void process(double delta); + void on_player_sound(Vector3 at, float range); void set_aware_of_player(bool value); protected: @@ -20,10 +22,15 @@ public: private: bool aware_of_player{ false }; - float max_distance{ 100.f }; - float min_dot{ 0.1f }; + + float max_hearing_range{ 40.f }; + + float max_sight_range{ 100.f }; + float min_sight_dot{ 0.1f }; + double query_time{ 0.3 }; double query_timer{ 0.0 }; + PhysicsDirectSpaceState3D::RayParameters ray_params{}; public: diff --git a/modules/wave_survival/register_types.cpp b/modules/wave_survival/register_types.cpp index 7f8dc63d..c9c8304e 100644 --- a/modules/wave_survival/register_types.cpp +++ b/modules/wave_survival/register_types.cpp @@ -8,6 +8,7 @@ #include "wave_survival/hitbox.h" #include "wave_survival/hitscan_muzzle.h" #include "wave_survival/interactable.h" +#include "wave_survival/muzzle_effect.h" #include "wave_survival/npc_unit.h" #include "wave_survival/patrol_path.h" #include "wave_survival/player_body.h" @@ -15,6 +16,8 @@ #include "wave_survival/player_detector.h" #include "wave_survival/player_input.h" #include "wave_survival/player_interactor.h" +#include "wave_survival/sound_event_node.h" +#include "wave_survival/sound_event_patchboard.h" #include "wave_survival/state.h" #include "wave_survival/state_machine.h" #include "wave_survival/weapon_base.h" @@ -49,6 +52,12 @@ void initialize_wave_survival_module(ModuleInitializationLevel p_level) { GDREGISTER_CLASS(PlayerInteractor); GDREGISTER_CLASS(Interactable); GDREGISTER_CLASS(Revolver); + GDREGISTER_CLASS(SoundEventPatchboard); + GDREGISTER_CLASS(SoundEventNode); + GDREGISTER_CLASS(MuzzleEffect); + + memnew(SoundEventPatchboard); + Engine::get_singleton()->add_singleton(Engine::Singleton("SoundEventPatchboard", SoundEventPatchboard::get_singleton())); } void uninitialize_wave_survival_module(ModuleInitializationLevel p_level) { diff --git a/modules/wave_survival/sound_event_node.cpp b/modules/wave_survival/sound_event_node.cpp new file mode 100644 index 00000000..45ef167c --- /dev/null +++ b/modules/wave_survival/sound_event_node.cpp @@ -0,0 +1,44 @@ +#include "sound_event_node.h" +#include "macros.h" +#include "sound_event_patchboard.h" + +void SoundEventNode::_bind_methods() { + ClassDB::bind_method(D_METHOD("trigger_event"), &self_type::trigger_event); + BIND_PROPERTY(Variant::BOOL, trigger_on_ready); +} + +void SoundEventNode::ready() { + if (this->trigger_on_ready) { + trigger_event(); + } +} + +void SoundEventNode::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + + if (what == NOTIFICATION_READY) { + ready(); + } +} + +void SoundEventNode::trigger_event() { + SoundEventPatchboard::get_singleton()->trigger_sound(get_global_position(), this->range); +} + +void SoundEventNode::set_trigger_on_ready(bool value) { + this->trigger_on_ready = value; +} + +bool SoundEventNode::get_trigger_on_ready() const { + return this->trigger_on_ready; +} + +void SoundEventNode::set_range(float value) { + this->range = value; +} + +float SoundEventNode::get_range() const { + return this->range; +} diff --git a/modules/wave_survival/sound_event_node.h b/modules/wave_survival/sound_event_node.h new file mode 100644 index 00000000..417dbd40 --- /dev/null +++ b/modules/wave_survival/sound_event_node.h @@ -0,0 +1,26 @@ +#ifndef SOUND_EVENT_NODE_H +#define SOUND_EVENT_NODE_H + +#include "scene/3d/node_3d.h" + +class SoundEventNode : public Node3D { + GDCLASS(SoundEventNode, Node3D); + static void _bind_methods(); + void ready(); + +protected: + void _notification(int what); + +public: + void trigger_event(); + void set_trigger_on_ready(bool value); + bool get_trigger_on_ready() const; + void set_range(float value); + float get_range() const; + +private: + float range{ 20.f }; + bool trigger_on_ready{ true }; +}; + +#endif // !SOUND_EVENT_NODE_H diff --git a/modules/wave_survival/sound_event_patchboard.cpp b/modules/wave_survival/sound_event_patchboard.cpp new file mode 100644 index 00000000..0fd2beb5 --- /dev/null +++ b/modules/wave_survival/sound_event_patchboard.cpp @@ -0,0 +1,27 @@ +#include "sound_event_patchboard.h" + +SoundEventPatchboard *SoundEventPatchboard::singleton_instance{ nullptr }; +String const SoundEventPatchboard::sig_sound_triggered{ "sound_triggered" }; + +void SoundEventPatchboard::_bind_methods() { + ClassDB::bind_method(D_METHOD("trigger_sound", "at", "range"), &self_type::trigger_sound); + ADD_SIGNAL(MethodInfo(sig_sound_triggered, PropertyInfo(Variant::VECTOR3, "at"), PropertyInfo(Variant::FLOAT, "range"))); +} + +SoundEventPatchboard::SoundEventPatchboard() { + singleton_instance = this; +} + +SoundEventPatchboard::~SoundEventPatchboard() { + if (singleton_instance == this) { + singleton_instance = nullptr; + } +} + +SoundEventPatchboard *SoundEventPatchboard::get_singleton() { + return singleton_instance; +} + +void SoundEventPatchboard::trigger_sound(Vector3 at, float range) { + emit_signal(sig_sound_triggered, at, range); +} diff --git a/modules/wave_survival/sound_event_patchboard.h b/modules/wave_survival/sound_event_patchboard.h new file mode 100644 index 00000000..1709edfa --- /dev/null +++ b/modules/wave_survival/sound_event_patchboard.h @@ -0,0 +1,22 @@ +#ifndef SOUND_EVENT_PATCHBOARD_H +#define SOUND_EVENT_PATCHBOARD_H + +#include "core/object/class_db.h" +#include "core/object/object.h" + +class SoundEventPatchboard : public Object { + GDCLASS(SoundEventPatchboard, Object); + static void _bind_methods(); + static SoundEventPatchboard *singleton_instance; + +public: + SoundEventPatchboard(); + virtual ~SoundEventPatchboard(); + static SoundEventPatchboard *get_singleton(); + void trigger_sound(Vector3 at, float range); + +public: + static String const sig_sound_triggered; +}; + +#endif // !SOUND_EVENT_PATCHBOARD_H diff --git a/project/assets/models/weapons/revolver.blend b/project/assets/models/weapons/revolver.blend index 734841e9d3d463f5ff4dba1d00dd5cac8232b85d..20ba1ca03129922acb5992bceccafbdd9110ef7e 100644 GIT binary patch delta 657 zcmaFg+RgYLh$oaX`@cK8v0~apVMYcJ;OKI?s8!Fv&{38us6AP6QnJvCkN?ktL=g1m zX_NR^Wtv$T7~V30H9>R+?Kjs3s^f6*yg2#5^b{VS|G(HkG7>G}g3}Xk@`*IN%-HTS zgE1qe{@mT9eHYu+>{3_JMB7FXKmhKt)~Ziu%7@y%y&Z#B)TvG+ZuwGYIf@F{Lz z-u^kZxr#IPGcYvR9|h`<1M2zp|MeE2bi-w!S)D-rhCn?aege?kY@k^#5d95qja~LB z`XB64<$HkUHPqXm@1DDF8S4VO6{=yxJ1107*66QR5>a<8$yxy0lx_WyaezVKaZ8(u%xCO@3n ze#@VvRhKg(4n1D7`{0ugQI0qNyB~_16yj9*Y^UQZw}^ue8KytF!z{FY&tJwDjM|L4 z=j?cYect!uyu|(sN{stg-(3L?5|FnG3?^7TxNB#3$Juh9&*|vt8x+{Wrm8aCpKkMj zIb^w|5*uTC1QQbwGXpUT5VLNNU}8I^GWo%Mb~aI9geIg;4{Q>Xo1U`Jm5DNjZFc6CXu_zFW0kJp`O8~JX5K95EG!V-Gu`CeF S0kJ#~D*&N;4D{+WDWdJ2#4$CYd#35k|)!Rd)N`9zvsW^8wv z!I+U!ubh&x|IWqpwjqfZ>_AGg4_&i+{4l}pV@;wxi2roe=`DV#74{Q%mG1-bKW2yQ z?ayZ1Yt=VnKLbO9y$Dc$5>U_g|MRy1r5hdq&H4e;pPtU#YUF{ZsK9c9M08`+<(wKOvuYEB}Uf z_Sbfo+W{S6ce8o&-uRsrdzbv5Y7caTePNLL{)Pp!>>gx&Hx5vkxOt*$gsngOE8A1{ zj9?F_S8X`hyfOTcgtDJw%76DmotA4ISL%c~*|>Tg%wm}S=nk{c_C0?YUodJ@p zBNGra12GE_vu^ieWV@m|(Se;!l#ziUA$59SlbGD}gguNN+o!6totVjZy*=(A8xXSt zF$WNH0x=g5a|1CC5c6)2JIHtD`Sb-#nK-r^t>pj1#CUzX{u=(0mz+#YAm;$%Y5K)W z!o}_K(*%H65Qv3G diff --git a/project/assets/models/weapons/revolver.blend1 b/project/assets/models/weapons/revolver.blend1 index 35415d089ea8dabd87f7b09c19f9f0b8ef816b9a..ba75f7fe3c5d97dfc428133620f3dd4def2a30c4 100644 GIT binary patch delta 44805 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