How do I spawn a scene from code?
Set up the scene
Section titled “Set up the scene”The spawning happens in the level. The Marker2D is just a point you can move around in the editor to say where things appear:
LevelNode2D
the script goes here
SpawnerMarker2Dwhere the enemy appears
The thing being spawned is its own saved scene, enemy.tscn:
EnemyCharacterBody2D
Sprite2DSprite2D
CollisionShape2DCollisionShape2D
Load the scene once
Section titled “Load the scene once”At the top of level.gd, load the enemy scene into a constant. This gives you a PackedScene, a recipe you can make as many copies of as you like:
extends Node2D
const ENEMY := preload("res://enemy.tscn")preload() loads the file when the script is parsed, so the path must be a literal string; use load("res://enemy.tscn") instead when you only know the path at runtime.
Create and add an instance
Section titled “Create and add an instance”instantiate() builds a fresh copy of the scene. It exists in memory only until you add_child() it, which is what puts it in the running game:
extends Node2D
const ENEMY := preload("res://enemy.tscn")
func spawn_enemy() -> void: var enemy := ENEMY.instantiate() enemy.position = $Spawner.position add_child(enemy)using Godot;
public partial class Level : Node2D{ private PackedScene _enemyScene = GD.Load<PackedScene>("res://enemy.tscn");
public void SpawnEnemy() { Enemy enemy = _enemyScene.Instantiate<Enemy>(); enemy.Position = GetNode<Marker2D>("Spawner").Position; AddChild(enemy); }}Call spawn_enemy() from a button, a timer, or _ready() to test it. Each call creates a new enemy at the marker. Drag Spawner around in the editor and the spawn point follows.
Where to add it
Section titled “Where to add it”Add the instance to the level, or to a plain container node inside it, not to something that moves. A bullet added as a child of the player drifts along with the player instead of flying straight. If the spawning script lives on a moving node, hand the instance up with get_parent().add_child(enemy), or expose the target so you can pick it in the Inspector:
@export var container: Node2D
func shoot() -> void: var bullet := BULLET.instantiate() bullet.global_position = global_position container.add_child(bullet)