Add ProximityTrigger

This commit is contained in:
Sofia 2026-08-06 21:45:52 +03:00
parent 6610770fe2
commit 5431788a53
2 changed files with 74 additions and 4 deletions

View File

@ -11,6 +11,9 @@
[sub_resource type="BoxMesh" id="BoxMesh_1cgct"] [sub_resource type="BoxMesh" id="BoxMesh_1cgct"]
material = SubResource("StandardMaterial3D_vwb5y") material = SubResource("StandardMaterial3D_vwb5y")
[sub_resource type="BoxShape3D" id="BoxShape3D_3g557"]
size = Vector3(5, 5, 5)
[node name="two_towers" type="Map" unique_id=590524284 node_paths=PackedStringArray("spawners", "ball_spawner")] [node name="two_towers" type="Map" unique_id=590524284 node_paths=PackedStringArray("spawners", "ball_spawner")]
spawners = [NodePath("two_towers_static/func_godot_map/entity_11_info_spawn_point"), NodePath("two_towers_static/func_godot_map/entity_5_info_spawn_point")] spawners = [NodePath("two_towers_static/func_godot_map/entity_11_info_spawn_point"), NodePath("two_towers_static/func_godot_map/entity_5_info_spawn_point")]
ball_spawner = NodePath("two_towers_static/func_godot_map/entity_1_info_spawn_point") ball_spawner = NodePath("two_towers_static/func_godot_map/entity_1_info_spawn_point")
@ -21,17 +24,23 @@ script = ExtResource("4_y3aqj")
[node name="two_towers_static" parent="." unique_id=86902040 instance=ExtResource("2_l5vmt")] [node name="two_towers_static" parent="." unique_id=86902040 instance=ExtResource("2_l5vmt")]
[node name="triggerable" type="Triggerable" parent="." unique_id=1206596848 node_paths=PackedStringArray("mesh")] [node name="triggerable" type="Triggerable" parent="." unique_id=1206596848 node_paths=PackedStringArray("mesh")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 33.152664, 3.0791912, 0)
script = ExtResource("3_vwb5y") script = ExtResource("3_vwb5y")
mesh = NodePath("mesh_instance_3d") mesh = NodePath("mesh_instance_3d")
[node name="shootable_trigger" type="ShootableTrigger" parent="triggerable" unique_id=306909670] [node name="shootable_trigger" type="ShootableTrigger" parent="triggerable" unique_id=306909670]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 42.184772, 10.981467, 7.8725615)
[node name="collision_shape_3d" type="CollisionShape3D" parent="triggerable/shootable_trigger" unique_id=298869370] [node name="collision_shape_3d" type="CollisionShape3D" parent="triggerable/shootable_trigger" unique_id=298869370]
shape = SubResource("BoxShape3D_1cgct") shape = SubResource("BoxShape3D_1cgct")
[node name="mesh_instance_3d" type="MeshInstance3D" parent="triggerable" unique_id=174590790] [node name="mesh_instance_3d" type="MeshInstance3D" parent="triggerable" unique_id=174590790]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 42.184772, 10.981467, 7.8725615)
mesh = SubResource("BoxMesh_1cgct") mesh = SubResource("BoxMesh_1cgct")
[node name="proximity_trigger" type="ProximityTrigger" parent="triggerable" unique_id=774677471]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.7171593, -2.5604024, 0.8731904)
[node name="collision_shape_3d" type="CollisionShape3D" parent="triggerable/proximity_trigger" unique_id=1090850563]
shape = SubResource("BoxShape3D_3g557")
[connection signal="on_shot" from="triggerable/shootable_trigger" to="triggerable" method="activate" unbinds=2] [connection signal="on_shot" from="triggerable/shootable_trigger" to="triggerable" method="activate" unbinds=2]
[connection signal="on_trigger" from="triggerable/proximity_trigger" to="triggerable" method="activate"]

View File

@ -1,5 +1,7 @@
use std::collections::HashSet;
use godot::{ use godot::{
classes::{Area3D, StaticBody3D}, classes::{Area3D, IArea3D, StaticBody3D},
prelude::*, prelude::*,
}; };
@ -7,7 +9,9 @@ use crate::{
game::Game, game::Game,
map::Map, map::Map,
net::network_manager::NetworkManager, net::network_manager::NetworkManager,
player::{DamageSource, shootable::Shootable}, player::{
DamageSource, local_player::LocalPlayer, remote_player::RemotePlayer, shootable::Shootable,
},
replay::StandaloneReplayManager, replay::StandaloneReplayManager,
}; };
@ -178,3 +182,60 @@ impl Shootable for ShootableTrigger {
} }
} }
} }
#[derive(GodotClass)]
#[class(base=Area3D, init)]
pub struct ProximityTrigger {
colliders_inside: HashSet<Gd<Node3D>>,
base: Base<Area3D>,
}
#[godot_api]
impl IArea3D for ProximityTrigger {
fn ready(&mut self) {
let base = self.base_mut().clone();
base.signals()
.body_entered()
.connect_other(self, Self::on_enter);
base.signals()
.body_exited()
.connect_other(self, Self::on_leave);
}
}
#[godot_api]
impl ProximityTrigger {
#[signal]
pub fn on_trigger(player: u16);
#[signal]
pub fn on_all_left();
fn on_enter(&mut self, node: Gd<Node3D>) {
if NetworkManager::singleton().bind().is_host() {
let was_empty = self.colliders_inside.is_empty();
let player_id = if let Ok(local_player) = node.clone().try_cast::<LocalPlayer>() {
self.colliders_inside.insert(node);
Some(local_player.bind().player_id.unwrap_or(0))
} else if let Ok(remote_player) = node.clone().try_cast::<RemotePlayer>() {
if !remote_player.bind().replay_mode {
self.colliders_inside.insert(node);
}
Some(remote_player.bind().player_id.unwrap_or(0))
} else {
None
};
if was_empty && let Some(player_id) = player_id {
self.signals().on_trigger().emit(player_id);
}
}
}
fn on_leave(&mut self, node: Gd<Node3D>) {
self.colliders_inside.remove(&node);
if self.colliders_inside.is_empty() {
self.signals().on_all_left().emit();
}
}
}