Hello, I’m still fairly new to Godot so apologies if my code is a bit obtuse. My problem is rather simple but I can’t manage to search up the solution without getting diverted to tutorials and extraneous search results.
Simply put, I have a top down 2D game. I kill a slime and it drops a random amount of items called “Goo”. When I walk over the item drops they are deleted and an integer in my player script it iterated to count how many I have. I plan to replace this with a more formal inventory system eventually.
Anyway that all works, my problem is when I walk over more than one item at once all items are deleted like they should be, except my player script only records a single item. If I very slowly pick up one item then the next, it will work and record two pickups. I believe I’m simply picking them up too fast and because I don’t know how to make functions interact outside of their own scripts I can’t work out how to make sure the amount is consistently recorded.
If anyone could help me I would really appreciate it. Also if there’s some massive flaw in the way I’m doing my code in general please let me know, thanks.
Think the problem here is you have two separated detections for basically the same thing, this looks ask for trouble because if the items area detect first, you’ll delete the item before player area do the work, you even risk get a “Invalid property error” if the item deletes itself while player detect it. The correct in this case is only player detect the items and activate the item self delete later.
First, disconect the area_entered signal in the goo scene
Remove the collision_shape_2d variable
Remove the goo variable
Remove the item function
Remove the _on_area_entered function
Do the following code:
# In goo.gd
func _ready() -> void:
# Instead of use a function, use groups to differ which areas you're
# detecting, also, i strongly recommend you not rely in the node
# names to do checking, because if you have a node called Goo and
# add another node with the same name, the engine will rename
# the last one to Goo2 and that can break you code
add_to_group("item")
add_to_group("goo")
func item_picked() -> void:
# Disable the area for not be detected more than one time
set_deferred("monitorable", false)
# Hide the node
visible = false
item_pickup_sound.play()
await item_pickup_sound.finished
queue_free()
In player.gd
func _on_hitbox_area_entered(area: Area2D) -> void:
# Check if the area is part of the item group, and after check if is part
# of the goo group
if area.is_in_group("item"):
if area.is_in_group("goo"):
# Call the function in the item picked and let the item
# handle their self deletion
area.item_picked()
item_count += 1
print("Inventory: ") + str(item_count) + " Goo")
Oh my god thank you! I had no idea that groups were a thing and the only tutorial I found told me to do the method detection even though I thought that looked super bloated. Also I had no clue that you could trigger non-local functions just by referencing whatever area/body you lock on to that contains the other script!
This was so incredibly helpful for multiple different things, thanks!