Godot Version
4.5.1 still : (
Question
I’ve written up a quick logic for a chest in my 3d dungeon crawler but code that’s only supposed to print once happens multiple times for no apparent reason.
With this code:
extends StaticBody3D
var triggered := false
@onready var player : Player = gamemanager.player
func _process(_delta: float) -> void:
if Input.is_action_just_pressed('use') && player.interact_range.is_colliding() && !triggered:
triggered = true
print("Cmon, do something")
I get this output:
Cmon, do something
Cmon, do something
Cmon, do something
Cmon, do something
Cmon, do something
The logic I had in my head was: have a variable for if it’s triggered so the chest can only be used once and check if the use action was pressed while the player’s interaction range raycast is colliding so that it can make triggered true preventing the line from running again and then printing something so I can tell that it’s running the code since I don’t have what the chest will do programmed yet.
How many chests instances do you have? Maybe 5?
The code here should work as you want it to.
I can only think that triggered is being reset (I assume you would have found that by now) or there is more than one instance of this chest code active.
Do you have 5 of those chests in your scene? When the button is pressed while the raycast is colliding with anything, all chests will print their text once. Because you only check if the raycast is colliding, but not what (which chest) the collider is.
Instead of the chests checking what the player’s raycast is doing, the player should use the raycast to call a function from its collider.
extends StaticBody3D
var triggered := false
func interact() -> void:
if !triggered:
triggered = true
print("Cmon, do something")
#somewhere in the player scene
if Input.is_action_just_pressed('use') && interact_range.is_colliding():
var collider = interact_range.get_collider()
if collider.has_method("interact"):
collider.interact()
2 Likes
The code that spawns it indexes from an array to spawn a thing and when used in enemies as opposed to chests it only spawns once. The code has also printed the text in different amounts on various occasions. It’s happened the five times I’ve shown but also 3 times and 4.
print(get_path(), " says: Cmon, do something")
1 Like
/root/Dungeon Main/Test Corridor/TestChest says: Cmon, do something
/root/Dungeon Main/@Node3D@41/TestChest says: Cmon, do something
/root/Dungeon Main/@Node3D@42/TestChest says: Cmon, do something
/root/Dungeon Main/@Node3D@44/TestChest says: Cmon, do something
the first one is confusing but the others imply that multiple are being added.
This is the code that spawns the chests. I don’t see why it would spawn multiple but also, to quote @Frozen_Fried
This thing is called a bug factory…

so the awaits are likely the issue
extends Marker3D
class_name FeatureSpawner
@export var features : Array[PackedScene]
func _ready() -> void:
var feature_index := randi_range(0, features.size() - 1)
var feature_spawned : Node3D = features[feature_index].instantiate()
if feature_spawned is pure_Enemy:
add_sibling.call_deferred(feature_spawned)
else:
get_parent().add_sibling.call_deferred(feature_spawned)
await get_tree().process_frame
feature_spawned.global_position = global_position
queue_free()
1 Like
Aren’t they always?
Best to get rid of them.
Although you have a problematic collision check that will trigger all of the chests if any of them is colliding player’s interact range:
if Input.is_action_just_pressed('use') && player.interact_range.is_colliding() && !triggered:
Instead you need to check if the colliding chest is equal to the one running the current instance of the script.
1 Like
No idea how but for some reason making it check if the collider is self fixed it.
1 Like