I have an item drop problem. When an enemy dies, it will drop an item. But since the item is the child of the enemy, when the enemy queue_free, the item is also lost. I tried the code get_parent().get_parent().add_child() still doesn't work. Although the game is still running, it gives an error as shown in the attached image. Obviously the item is no longer a child of the enemy, now it is a child of the World, but it still gives an error. And if using the signal method, using World to create items when the enemy dies, then I don't know how to code when World creates items right where the enemy is killed. How does the World know where Enemy is, when the enemy is constantly moving? And what is the easiest and most effective way? If anyone has had this problem like me and fixed it or someone knows how to fix it, please show me the code. I sincerely thank you very much.!
Drop items when Enemy die.
You generally want to add items, like loot or stuff that spawns, onto the game layer. This would be the node in your game where the level is (that same layer that the player is walking inside). One way to do this is to have a main script on the level or on the top node, which has a function spawn_item()
or whatever that creates the item. It can take parameters so it can spawn different items. Then when the enemy dies, it calls that function, or emits a signal. For example.
# when the enemy dies
get_node("/root/Game/Level").spawn_item("Sword", global_position)
This would assume the top node in your game is called "Game" and has a child called "Level" and the "Level" has the script with the spawn_item()
function. Then in that script, you could do something like:
func spawn_item(item_type, item_position):
if item_type == "Sword":
var sword = SwordAsset.instance()
sword.global_position = item_position
add_child(sword)
sorry, I just tried your way, it still gives me the same error.Besides, your way is not different from mine, because I used the method: get_parent().get_parent().add_child() it has the same effect as yours, but much simpler.Basically, my way and your way have one thing in common, which is to make Node_Item a child of World or of a parent higher than Enemy. But it still gives the same error. Engine recommends we use (Call_defered) something. But I don't know how to use it. Also do you have any other more efficient way?Maybe you have never encountered this case before, Cyber? I find this case quite basic, and every game must have this item drop problem.But no one seems to ask?
Can you post some of your code? I think that error happens when something is freed or deleted, but there is still code running. The call_deferred
is a way to call a function at a later time, usually the next frame.
call_deferred("area_set_shape_disabled", true)
Here's a picture of Enemy's code. Queue_free Enemy_node of course, because it's dead. But I'm wondering why item_node is already a child of the World node but why is it still giving that error. It seemed so simple, yet so complicated.
Hello. Not sure how you set up your code but if you follow this tutorial should help:
https://www.davidepesce.com/2019/12/09/godot-tutorial-12-picking-and-using-items/
see "Dropping a potion after enemy death"
Gowydot Here's a link update: https://www.davidepesce.com/?p=1877
This tip helped me even in Godot 4. The useful command is:
get_tree().root.get_node("Root").call_deferred("add_child", potion)
Thank you!