I do an enemy when it died it dropped an item. But because that item is also a child node of that enemy. So when the enemy dies and queue_free it, the item will also be queue_free without the player being able to collect it. So someone help me to handle this situation. I have to do what I want to do. Thank you! Please help!

is this 2d or 3d? What I would do is either have a main or an autoload with preloaded scenes that were the items that they hold, then instance them and add them to the main scene at the location of the enemy before he queue_free.

That way I never knew how to use. So far I just created and get_parent.add_child. But when Parent queue.free, the child also lost. So what do you mean the onready var or autoload code? Please HELP, Master !

Yeah, that way didn't work for me either. Once you queue_free the script is destroyed also. First of all you need to load your scene in an autoload or the main scene:

var axe = preload("res://axe.tscn")

This would be the item you want to drop and it's on the main scene script Then you want a function that takes a Vector3 which is the translation of the enemy.

func add_axe(tran):
	var instance = axe.instance()
	add_child(instance)
	instance.translation = tran

That's for 3d. If it's 2d, you give it a position instead and set the position. I've never done it in 2d, but should be the same. So then before you queue_free, call that function on the main script and give it the position or translation of the enemy. I have instanced, but I haven't actually tried this but it should work.

As long as the Ax scene is a child of the Enemy node, when the Enemy is deleted, the Ax will also be deleted. Is there a way to make it so that when Enemy is deleted, the Ax generated from Enemy is not deleted? (in 2D, not 3D)

Let me know if you get it to work. It didn't work for me. As soon as I did a remove_child, the variable became a null. If you don't remove it, the add_child is ignored because it can't have two parents. You might be able to instantiate it in the enemy script, add it as a child, remove it, and then instantiate it again and add it to the parent.

Is the dropped item instantiated when the enemy is instantiated or just when the enemy dies? If the latter, it wouldn't ever have to be a child of the enemy, you could do something like get_tree().get_root().add_child(instance) from the beginning.

In this case I would not add the new item to the parent, I would keep all items on a node called... "floor" ... yeah that makes sense to me, a node called floor that maybe also has your floor. It doesn't even have to be your floor, just have those items get "childed" to a single easy to find node. You'll need a reference to this node in a global script or another way to find this "floor" node. If your enemy is also on the floor, you could have the item go to the enemy's parent (the floor).

I remember you can use call_defer() like

first, preload the item scene: var item = preload(res://item.tscn)

then add this to the enemy scipt in death function: item.instance() get_tree().get_node("root").call_defer(add_child, item) #add item child to root.. item.position = position #..at enemy position

I probably got syntax wrong (sorry) but that's the idea

I'm sorry after trying the methods you mentioned, none of them worked. But I see that Godot has a suggestion, it seems the call_defered structure is usable. but if you use the normal way, Godot has this suggestion. So can someone please help me how to code ok?

This is all you should need: world scene:

onready var box = preload("res://box.tscn")

func _ready():
	drop_box(Vector2(100,100))

func drop_box(position):
	var box_instance = box.instance()
	add_child(box_instance)
	box_instance.global_position = position

I just tried it. You don't need call_deferred or any of that. I tried it with a sprite, but an area shouldn't matter.

A box is a good idea because you can add variables for items in the box in a script. You can add those in the argument like drop_box(position, item1,item2,item3) Then when you instance: box_instance.item1 = item1

But I want the box to drop right on the enemy's corpse when the enemy dies. So it must be created from the enemy. Why from World node?

@Odin said: But I want the box to drop right on the enemy's corpse when the enemy dies. So it must be created from the enemy. Why from World node?

When the enemy dies, you call the function or send a signal from the enemy. Like get_parent().drop_box(my_position) right before you call q free.

Hihi..sorry I'm bad at coding.

Just a thought. Try sending a signal from the enemy to world node with its X and Y (and Z if it's 3D) as its arguments. The world, in turn, creates the object at the coordinates given to it by the enemy.

@Nerdzmasterz not just the x, y, z but as an array holding a vector for coordinates and a meta tag for type of item dropped, quantity etc.?

7 months later