extends Node2D class_name Spawner @export var scene: PackedScene var buffer: int = 0 @export var buffer_cap: int @onready var area: Area2D = $Area @export var spawn_position_range_x: float @export_range(0, 90) var spawn_rotation_range: float @onready var rng: RandomNumberGenerator = RandomNumberGenerator.new() @export_flags_2d_physics var overlapping_bodies_collision_mask: int @export_range(0, 16) var overlapping_body_count_limit: int signal spawned(what: Node2D) func spawn(): buffer += 1 if buffer > buffer_cap: buffer = buffer_cap func _count_overlapping_bodies() -> int: var overlapping_bodies = area.get_overlapping_bodies() var overlapping_body_count = 0 for overlapping_body in overlapping_bodies: if overlapping_body.collision_layer & overlapping_bodies_collision_mask: overlapping_body_count += 1 return overlapping_body_count func _select_spawn_position() -> Vector2: return Vector2(rng.randf_range(-spawn_position_range_x, +spawn_position_range_x), 0) func _select_spawn_rotation() -> float: return rng.randf_range(-spawn_rotation_range, spawn_rotation_range) func _do_spawn(): if _count_overlapping_bodies() > overlapping_body_count_limit: return var scene_instant = scene.instantiate() scene_instant.position = _select_spawn_position() scene_instant.rotation_degrees = _select_spawn_rotation() add_child(scene_instant) emit_signal("spawned", scene_instant) buffer -= 1 func _physics_process(_delta): if buffer > 0: _do_spawn()