Hello!

Whenever I instance something in script, I preload the scene file location, and instance from that.

For example:

var objectToInstance = preload("res://instanceScene.tscn")

func instancingFunction():
	var newInstance = objectToInstance.instance()
	# Do anything I need to with the newInstance properties
	get_parent().add_child(newInstance)

What I'm wondering: is it possible to instance from the current class instead? Something like self but that can use the instance() function? Basically, I want to be able to have an object clone itself (or tell other object how to clone it) without an absolute reference to the .tscn file.

  • I haven't used that duplicate() function, but it looks like it would simply be:

    var newCopy: Node = duplicate()
    get_parent().add_child(newCopy)

    Or, if you don't need to refer to the node for some other reason:

    get_parent().add_child(duplicate())

    duplicate() returns a Node, so there's nothing to instance.

    You could also pass flags to duplicate(), if you don't want them all set. Or zero, if you don't want any of them set. For example:

    duplicate(Node.DuplicateFlags.DUPLICATE_SIGNALS + 
            Node.DuplicateFlags.DUPLICATE_GROUPS)

    https://docs.godotengine.org/en/stable/classes/class_node.html#enum-node-duplicateflags

Keep in mind that there's a difference here between instancing a class (as we do in programming) and creating an instance of a scene (what we use preload for). It's good not to confuse the two in Godot. A given class could reference itself, but as it is just a class it is not the same as a scene. lol did that make any sense?

    Erich_L Yes, that is great clarification! Thank you! Even as I wrote it, I was questioning whether I had the terminology right.

    So then, if I can reiterate my understanding: the scene is a blueprint for a node, the node is made from the scene, and the node runs the script attached to it.

    Then my question becomes: is it possible for a script to reference the scene that made the node running it without preloading (or loading) a specific hard-coded scene?

    I know self gives us reference to the name and unique ID of the instance running the script. What I'm hoping to find is something that can instance a new copy of that without having an absolute reference to the scene file. My thinking was that if the script can identify the instance running it, it should be able to identify the scene from which the instance was created?

    I'm not sure if I understand what you want to do.

    When you load/preload a .tscn file, you can save the PackedScene.
    var objectToInstance: PackedScene = preload("res://instanceScene.tscn")
    Then you can create as many instances as you want, without having to load/preload again.

    An arbitrary node may not have been instanced from a .tscn file, but any node can be duplicated:
    https://docs.godotengine.org/en/stable/classes/class_node.html#class-node-method-duplicate

      DaveTheCoder as I was driving to work today I realized I may have been overcomplicating my life.

      Basically, what I want to do is have each enemy in the game create a "respawner" node when it dies that can be triggered to spawn a new copy of the enemy after certain conditions are met. I want to be able to put this function on the base enemy class so that anything inheriting from it will be able to do this automatically.

      I think for my purposes, I can store a reference to the scene when the object is first created, and then use that stored reference for later.

      But I am intrigued by the duplicate function. And it may be what I was asking about.

      To make a new instance of the node running the script, would it basically just be something like:

      var newCopy = duplicate().instance
      get_parent().add_child(newCopy)

      I haven't used that duplicate() function, but it looks like it would simply be:

      var newCopy: Node = duplicate()
      get_parent().add_child(newCopy)

      Or, if you don't need to refer to the node for some other reason:

      get_parent().add_child(duplicate())

      duplicate() returns a Node, so there's nothing to instance.

      You could also pass flags to duplicate(), if you don't want them all set. Or zero, if you don't want any of them set. For example:

      duplicate(Node.DuplicateFlags.DUPLICATE_SIGNALS + 
              Node.DuplicateFlags.DUPLICATE_GROUPS)

      https://docs.godotengine.org/en/stable/classes/class_node.html#enum-node-duplicateflags