Modular interactive components

This commit is contained in:
Rob Kelly 2025-07-04 13:13:18 -06:00
parent 4ff1699fa5
commit 7d04454737
15 changed files with 152 additions and 101 deletions

View File

@ -234,7 +234,7 @@ font_size = 24
outline_size = 10
[node name="CargoBay" type="Node3D" parent="BeastNav"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12, -12, -60)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12, 0, -60)
[node name="Bulkheads" type="Node3D" parent="BeastNav"]

View File

@ -307,17 +307,12 @@ surface_material_override/0 = SubResource("StandardMaterial3D_xpsdy")
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D"]
shape = SubResource("ConcavePolygonShape3D_nafoa")
[node name="TankInteractor" type="StaticBody3D" parent="."]
unique_name_in_owner = true
[node name="TankInteractBody" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.85, 1.35, 4.5)
collision_layer = 2
collision_mask = 0
script = ExtResource("6_e4hmc")
label = "INTERACTIVE_TANK_LABEL"
verb = "INTERACTIVE_TANK_VERB"
metadata/_custom_type_script = "uid://deg5xd87cy8rg"
[node name="GrunkPumpSFX" type="AudioStreamPlayer3D" parent="TankInteractor"]
[node name="GrunkPumpSFX" type="AudioStreamPlayer3D" parent="TankInteractBody"]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.6)
stream = SubResource("AudioStreamRandomizer_53iah")
@ -325,9 +320,16 @@ volume_db = -4.0
unit_size = 3.0
pitch_scale = 0.7
[node name="CollisionShape3D" type="CollisionShape3D" parent="TankInteractor"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="TankInteractBody"]
shape = SubResource("SphereShape3D_e4hmc")
[node name="TankInteractor" type="Node" parent="TankInteractBody"]
unique_name_in_owner = true
script = ExtResource("6_e4hmc")
label = "INTERACTIVE_TANK_LABEL"
verb = "INTERACTIVE_TANK_VERB"
metadata/_custom_type_script = "uid://deg5xd87cy8rg"
[node name="LiquidOffset" type="Node3D" parent="."]
transform = Transform3D(0.95, 0, 0, 0, 0.95, 0, 0, 0, 0.95, 0, -2.8, 6)
@ -420,6 +422,6 @@ volume_db = -16.0
unit_size = 4.0
bus = &"SFX"
[connection signal="activated" from="TankInteractor" to="." method="deposit_grunk"]
[connection signal="activated" from="TankInteractBody/TankInteractor" to="." method="deposit_grunk"]
[connection signal="body_entered" from="DoorArea" to="DoorArea" method="_on_body_entered"]
[connection signal="body_exited" from="DoorArea" to="DoorArea" method="_on_body_exited"]

View File

@ -251,18 +251,20 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 45, 1.5654, -12)
skeleton = NodePath("../..")
surface_material_override/0 = SubResource("StandardMaterial3D_u3x5h")
[node name="Interactive" type="StaticBody3D" parent="Props/VendingMachine"]
[node name="InteractiveBody" type="StaticBody3D" parent="Props/VendingMachine"]
collision_layer = 2
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="Props/VendingMachine/InteractiveBody"]
shape = SubResource("BoxShape3D_ibd1t")
[node name="Interactive" type="Node" parent="Props/VendingMachine/InteractiveBody"]
script = ExtResource("28_ibd1t")
enabled = true
label = "Vending Machine"
verb = "toggle"
metadata/_custom_type_script = "uid://deg5xd87cy8rg"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Props/VendingMachine/Interactive"]
shape = SubResource("BoxShape3D_ibd1t")
[node name="CleanPodium" type="StaticBody3D" parent="."]
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -4, 1, 0)
@ -280,18 +282,20 @@ text = "Clean"
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.3, 0.25)
mesh = SubResource("SphereMesh_ibd1t")
[node name="Interactive" type="StaticBody3D" parent="CleanPodium/ButtonMesh"]
[node name="InteractiveBody" type="StaticBody3D" parent="CleanPodium/ButtonMesh"]
collision_layer = 2
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="CleanPodium/ButtonMesh/InteractiveBody"]
shape = SubResource("SphereShape3D_mvw32")
[node name="Interactive" type="Node" parent="CleanPodium/ButtonMesh/InteractiveBody"]
script = ExtResource("28_ibd1t")
enabled = true
label = "Level"
verb = "clean all"
metadata/_custom_type_script = "uid://deg5xd87cy8rg"
[node name="CollisionShape3D" type="CollisionShape3D" parent="CleanPodium/ButtonMesh/Interactive"]
shape = SubResource("SphereShape3D_mvw32")
[node name="ResetPodium" type="StaticBody3D" parent="."]
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -4, 1, 1.5)
@ -309,18 +313,20 @@ text = "Reload"
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.3, 0.25)
mesh = SubResource("SphereMesh_ibd1t")
[node name="Interactive" type="StaticBody3D" parent="ResetPodium/ButtonMesh"]
[node name="InteractiveBody" type="StaticBody3D" parent="ResetPodium/ButtonMesh"]
collision_layer = 2
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="ResetPodium/ButtonMesh/InteractiveBody"]
shape = SubResource("SphereShape3D_mvw32")
[node name="Interactive" type="Node" parent="ResetPodium/ButtonMesh/InteractiveBody"]
script = ExtResource("28_ibd1t")
enabled = true
label = "Level"
verb = "reload"
metadata/_custom_type_script = "uid://deg5xd87cy8rg"
[node name="CollisionShape3D" type="CollisionShape3D" parent="ResetPodium/ButtonMesh/Interactive"]
shape = SubResource("SphereShape3D_mvw32")
[node name="GameEnvPodium" type="StaticBody3D" parent="."]
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 5, 1, 0)
@ -340,18 +346,20 @@ Environment
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.3, 0.25)
mesh = SubResource("SphereMesh_ibd1t")
[node name="Interactive" type="StaticBody3D" parent="GameEnvPodium/ButtonMesh"]
[node name="InteractiveBody" type="StaticBody3D" parent="GameEnvPodium/ButtonMesh"]
collision_layer = 2
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="GameEnvPodium/ButtonMesh/InteractiveBody"]
shape = SubResource("SphereShape3D_mvw32")
[node name="Interactive" type="Node" parent="GameEnvPodium/ButtonMesh/InteractiveBody"]
script = ExtResource("28_ibd1t")
enabled = true
label = "Game Environment"
verb = "enable"
metadata/_custom_type_script = "uid://deg5xd87cy8rg"
[node name="CollisionShape3D" type="CollisionShape3D" parent="GameEnvPodium/ButtonMesh/Interactive"]
shape = SubResource("SphereShape3D_mvw32")
[node name="DebugEnvPodium" type="StaticBody3D" parent="."]
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 5, 1, 1.5)
@ -371,18 +379,20 @@ Environment
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.3, 0.25)
mesh = SubResource("SphereMesh_ibd1t")
[node name="Interactive" type="StaticBody3D" parent="DebugEnvPodium/ButtonMesh"]
[node name="InteractiveBody" type="StaticBody3D" parent="DebugEnvPodium/ButtonMesh"]
collision_layer = 2
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="DebugEnvPodium/ButtonMesh/InteractiveBody"]
shape = SubResource("SphereShape3D_mvw32")
[node name="Interactive" type="Node" parent="DebugEnvPodium/ButtonMesh/InteractiveBody"]
script = ExtResource("28_ibd1t")
enabled = true
label = "Debug Environment"
verb = "enable"
metadata/_custom_type_script = "uid://deg5xd87cy8rg"
[node name="CollisionShape3D" type="CollisionShape3D" parent="DebugEnvPodium/ButtonMesh/Interactive"]
shape = SubResource("SphereShape3D_mvw32")
[node name="PostProcessingPodium" type="StaticBody3D" parent="."]
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 5, 1, 3)
@ -401,18 +411,20 @@ Postprocessing"
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.3, 0.25)
mesh = SubResource("SphereMesh_ibd1t")
[node name="Interactive" type="StaticBody3D" parent="PostProcessingPodium/ButtonMesh"]
[node name="InteractiveBody" type="StaticBody3D" parent="PostProcessingPodium/ButtonMesh"]
collision_layer = 2
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="PostProcessingPodium/ButtonMesh/InteractiveBody"]
shape = SubResource("SphereShape3D_mvw32")
[node name="Interactive" type="Node" parent="PostProcessingPodium/ButtonMesh/InteractiveBody"]
script = ExtResource("28_ibd1t")
enabled = true
label = "Post-processing"
verb = "toggle"
metadata/_custom_type_script = "uid://deg5xd87cy8rg"
[node name="CollisionShape3D" type="CollisionShape3D" parent="PostProcessingPodium/ButtonMesh/Interactive"]
shape = SubResource("SphereShape3D_mvw32")
[node name="PostProcessing" parent="." instance=ExtResource("30_qnhar")]
unique_name_in_owner = true
visible = false
@ -423,9 +435,9 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
[connection signal="animation_finished" from="Props/Bulkhead" to="Props/SwitchPodium/OpenSwitch" method="enable"]
[connection signal="activated" from="Props/SwitchPodium/OpenSwitch" to="Props/Bulkhead" method="toggle"]
[connection signal="activated" from="Props/SwitchPodium/OpenSwitch" to="Props/SwitchPodium/OpenSwitch" method="disable"]
[connection signal="activated" from="Props/VendingMachine/Interactive" to="." method="toggle_vending_machine"]
[connection signal="activated" from="CleanPodium/ButtonMesh/Interactive" to="." method="clean_all_props"]
[connection signal="activated" from="ResetPodium/ButtonMesh/Interactive" to="." method="reset_level"]
[connection signal="activated" from="GameEnvPodium/ButtonMesh/Interactive" to="." method="set_game_environment"]
[connection signal="activated" from="DebugEnvPodium/ButtonMesh/Interactive" to="." method="set_debug_environment"]
[connection signal="activated" from="PostProcessingPodium/ButtonMesh/Interactive" to="." method="toggle_postprocessing"]
[connection signal="activated" from="Props/VendingMachine/InteractiveBody/Interactive" to="." method="toggle_vending_machine"]
[connection signal="activated" from="CleanPodium/ButtonMesh/InteractiveBody/Interactive" to="." method="clean_all_props"]
[connection signal="activated" from="ResetPodium/ButtonMesh/InteractiveBody/Interactive" to="." method="reset_level"]
[connection signal="activated" from="GameEnvPodium/ButtonMesh/InteractiveBody/Interactive" to="." method="set_game_environment"]
[connection signal="activated" from="DebugEnvPodium/ButtonMesh/InteractiveBody/Interactive" to="." method="set_debug_environment"]
[connection signal="activated" from="PostProcessingPodium/ButtonMesh/InteractiveBody/Interactive" to="." method="toggle_postprocessing"]

View File

@ -0,0 +1,20 @@
extends RayCast3D
## Component for interacting with Interactive things.
@onready var parent := owner as Player
func _process(_delta: float) -> void:
var collider := self.get_collider()
if not collider:
return
if collider.has_user_signal(Interactive.SELECT_SIGNAL):
collider.emit_signal(Interactive.SELECT_SIGNAL)
if (
parent.activity_enabled
and Input.is_action_just_pressed("interact")
and collider.has_user_signal(Interactive.ACTIVATE_SIGNAL)
):
collider.emit_signal(Interactive.ACTIVATE_SIGNAL)

View File

@ -0,0 +1 @@
uid://hnxv1ii8hm0

View File

@ -45,7 +45,6 @@ var gravity: Vector3 = (
* ProjectSettings.get_setting("physics/3d/default_gravity_vector")
)
var selected_interactive: Interactive
var firing := false
var sneaking := false
@ -56,8 +55,6 @@ var _was_on_floor := false
@onready var camera_pivot: CameraController = %CameraPivot
@onready var cam_rumbler: Rumbler3D = %CamRumbler
@onready var interact_ray: RayCast3D = %InteractRay
@onready var tool_mount: ToolMount = %ToolMount
@onready var point_spray: PointSpray = %PointSpray
@onready var wide_spray: WideSpray = %WideSpray
@ -188,17 +185,7 @@ func _signal_death() -> void:
func _physics_process(delta: float) -> void:
# Will be null if no valid interactor is selected.
var interactive := interact_ray.get_collider() as Interactive
hud.select_interactive(interactive)
if interactive:
interactive.select()
if activity_enabled:
# World interaction
if Input.is_action_just_pressed("interact") and interactive:
interactive.activate()
# Tool selection
if Input.is_action_just_pressed("select_next_tool"):
tool_mount.set_active_relative(1)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=67 format=3 uid="uid://bwe2jdmvinhqd"]
[gd_scene load_steps=68 format=3 uid="uid://bwe2jdmvinhqd"]
[ext_resource type="Script" uid="uid://buwh0g1ga2aka" path="res://src/player/player.gd" id="1_npueo"]
[ext_resource type="Script" uid="uid://cx1yt0drthpw3" path="res://src/player/camera_controller.gd" id="2_veeqv"]
@ -13,6 +13,7 @@
[ext_resource type="PackedScene" uid="uid://cmnokjbv3vuqt" path="res://src/equipment/sticker_pack/sticker_pack.tscn" id="8_xmpm3"]
[ext_resource type="Script" uid="uid://ecrhsueph7at" path="res://src/player/footsteps/footstep_controller.gd" id="9_hja65"]
[ext_resource type="Script" uid="uid://brqa2wbtaspw4" path="res://src/player/footsteps/foot_controller.gd" id="9_l271a"]
[ext_resource type="Script" uid="uid://hnxv1ii8hm0" path="res://src/player/interact_ray.gd" id="10_4ptlo"]
[ext_resource type="AudioStream" uid="uid://di0e1l1l6l3qc" path="res://assets/sfx/footsteps/metal/metal1.wav" id="10_jcdrv"]
[ext_resource type="Script" uid="uid://pkk1qg3bqjhj" path="res://src/player/hold_component.gd" id="11_h0enb"]
[ext_resource type="AudioStream" uid="uid://bv00dudic2mvp" path="res://assets/sfx/footsteps/metal/metal3.wav" id="11_hja65"]
@ -651,6 +652,7 @@ current = true
unique_name_in_owner = true
target_position = Vector3(0, 0, -1.5)
collision_mask = 2
script = ExtResource("10_4ptlo")
[node name="FarLight" type="OmniLight3D" parent="CameraPosition/CameraPivot/TransformedPosition/CamRumbler/Camera3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.1)

View File

@ -1,31 +1,32 @@
class_name Interactive extends StaticBody3D
class_name Interactive extends Node
## Props the player can interact with.
signal activated
signal selected
const SELECT_SIGNAL := "selected"
const ACTIVATE_SIGNAL := "activated"
@export var enabled := false
@export var label := ""
@export var verb := "use"
var _is_selected := false
var _selected_this_frame := false
var controller: Node
var is_selected := false
func _ready() -> void:
controller = get_parent()
controller.add_user_signal(SELECT_SIGNAL)
controller.connect(SELECT_SIGNAL, select)
controller.add_user_signal(ACTIVATE_SIGNAL)
controller.connect(ACTIVATE_SIGNAL, activate)
func select() -> void:
Player.instance.hud.interact_hud.set_interactive(self)
func activate() -> void:
if enabled:
activated.emit()
# TODO: bonk
func select() -> void:
if not _is_selected:
selected.emit()
_is_selected = true
_selected_this_frame = true
func _process(_delta: float) -> void:
if not _selected_this_frame:
_is_selected = false
_selected_this_frame = false

View File

@ -23,17 +23,18 @@ Scanner"
font_size = 96
outline_size = 24
[node name="Interactive" type="StaticBody3D" parent="."]
unique_name_in_owner = true
[node name="InteractiveBody" type="StaticBody3D" parent="."]
collision_layer = 3
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="InteractiveBody"]
shape = SubResource("BoxShape3D_5bfyo")
[node name="Interactive" type="Node" parent="InteractiveBody"]
unique_name_in_owner = true
script = ExtResource("1_ldtbm")
label = "INTERACTIVE_SCANNER_LABEL"
verb = "INTERACTIVE_SCANNER_VERB"
metadata/_custom_type_script = "uid://deg5xd87cy8rg"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Interactive"]
shape = SubResource("BoxShape3D_5bfyo")
[connection signal="activated" from="Interactive" to="." method="_activate"]
[connection signal="selected" from="Interactive" to="." method="_on_interactive_selected"]
[connection signal="activated" from="InteractiveBody/Interactive" to="." method="_activate"]

View File

@ -240,16 +240,19 @@ libraries = {
}
autoplay = "error_blink"
[node name="Interactive" type="StaticBody3D" parent="." index="4"]
unique_name_in_owner = true
[node name="InteractiveBody" type="StaticBody3D" parent="." index="4"]
collision_layer = 2
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="InteractiveBody" index="0"]
shape = SubResource("BoxShape3D_6maql")
[node name="Interactive" type="Node" parent="InteractiveBody" index="1"]
unique_name_in_owner = true
script = ExtResource("10_qw6jt")
label = "INTERACTIVE_SWITCH_LABEL"
verb = "INTERACTIVE_SWITCH_VERB"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Interactive" index="0"]
shape = SubResource("BoxShape3D_6maql")
metadata/_custom_type_script = "uid://deg5xd87cy8rg"
[node name="ActionSFX" type="AudioStreamPlayer3D" parent="." index="5"]
unique_name_in_owner = true
@ -273,6 +276,6 @@ metadata/_custom_type_script = "uid://c5o1d2shq2qig"
shape = SubResource("SphereShape3D_mxsyy")
[connection signal="clear_total_updated" from="StaticBody3D/Gunkable" to="." method="_on_clear_total_updated"]
[connection signal="activated" from="Interactive" to="." method="_activate"]
[connection signal="activated" from="InteractiveBody/Interactive" to="." method="_activate"]
[connection signal="timeout" from="ActionDelay" to="." method="_on_action_delay_timeout"]
[connection signal="timeout" from="ActionDelay" to="WallSwitchGameSoundEmitter" method="emit_sound_here"]

View File

@ -7,10 +7,17 @@ const COLOR_VISIBLE := Color("#ffffffee")
const COLOR_DISABLED := Color("#cccccc44")
const COLOR_INVISIBLE := Color("#ffffff00")
var _current_interactive: Interactive
var _set_this_frame := false
@onready var interact_name: Label = %InteractName
@onready var interact_verb: Label = %InteractVerb
func _ready() -> void:
_to_invisible()
func _transition_color(color: Color) -> void:
create_tween().tween_property(self, "modulate", color, TRANSITION_TIME).set_trans(
Tween.TRANS_CUBIC
@ -18,18 +25,28 @@ func _transition_color(color: Color) -> void:
func _to_visible() -> void:
print_debug("in _to_visible")
_transition_color(COLOR_VISIBLE)
func _to_disabled() -> void:
print_debug("in _to_disabled")
_transition_color(COLOR_DISABLED)
func _to_invisible() -> void:
print_debug("in _to_invisible")
_transition_color(COLOR_INVISIBLE)
func set_prop(prop: Interactive) -> void:
func set_interactive(prop: Interactive) -> void:
if prop != _current_interactive:
_set_new_interactive(prop)
_set_this_frame = true
func _set_new_interactive(prop: Interactive) -> void:
_current_interactive = prop
if prop:
interact_name.text = prop.label
interact_verb.text = prop.verb
@ -39,3 +56,10 @@ func set_prop(prop: Interactive) -> void:
_to_disabled()
else:
_to_invisible()
func _process(_delta: float) -> void:
if not _set_this_frame:
set_interactive(null)
_set_this_frame = false

View File

@ -12,10 +12,6 @@ func _ready() -> void:
World.instance.manager.alert_cleared.connect(_on_clear_alert)
func select_interactive(prop: Interactive) -> void:
interact_hud.set_prop(prop)
func _on_raise_alert(_new_value: int) -> void:
grunk_alert_player.play("grunk_alert")

View File

@ -372,10 +372,10 @@ anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -21.2937
offset_top = -19.1727
offset_right = -21.2937
offset_bottom = -19.1727
offset_left = -18.3489
offset_top = -21.6753
offset_right = -18.3489
offset_bottom = -21.6753
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("4_ud8na")

View File

@ -4,7 +4,7 @@
[ext_resource type="Resource" uid="uid://tgac5tnfx56r" path="res://src/world/world_manager.tres" id="2_5kmgb"]
[ext_resource type="PackedScene" uid="uid://byvjsvavbg5xe" path="res://src/ui/menus/pause_menu/pause_menu.tscn" id="2_6fy3g"]
[ext_resource type="Resource" uid="uid://0i72bf8ip1lx" path="res://src/world/spook_manager.tres" id="3_l0av5"]
[ext_resource type="PackedScene" uid="uid://bov4ok76woyc" path="res://levels/ghost_ship/ghost_ship.tscn" id="4_5kmgb"]
[ext_resource type="PackedScene" uid="uid://dc4tts6342cuj" path="res://levels/prop_test/prop_test.tscn" id="4_5kmgb"]
[ext_resource type="PackedScene" uid="uid://c0uitm5cg88h1" path="res://src/ui/menus/kill_screen/kill_screen.tscn" id="6_l0av5"]
[ext_resource type="PackedScene" uid="uid://brknr57xc2cp0" path="res://src/ui/elements/save_icon/save_icon.tscn" id="7_5kmgb"]

View File

@ -9,17 +9,19 @@ radius = 0.25
[node name="WorldItem" type="MeshInstance3D" groups=["Persistent"]]
script = ExtResource("1_sptcj")
[node name="Interactive" type="StaticBody3D" parent="."]
unique_name_in_owner = true
[node name="InteractiveBody" type="StaticBody3D" parent="."]
collision_layer = 2
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="InteractiveBody"]
unique_name_in_owner = true
shape = SubResource("SphereShape3D_0mein")
[node name="Interactive" type="Node" parent="InteractiveBody"]
unique_name_in_owner = true
script = ExtResource("2_ngll7")
enabled = true
verb = "INTERACTIVE_WORLDITEM_VERB"
metadata/_custom_type_script = "uid://deg5xd87cy8rg"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Interactive"]
unique_name_in_owner = true
shape = SubResource("SphereShape3D_0mein")
[connection signal="activated" from="Interactive" to="." method="_on_interactive_activated"]
[connection signal="activated" from="InteractiveBody/Interactive" to="." method="_on_interactive_activated"]