extends Node3D var _label: Label3D = null var _elapsed: float = 0.0 var _lifetime: float = 1.4 var _drift: float = 1.6 static func spawn(parent: Node, text: String, world_pos: Vector3, color: Color = Color(1.0, 0.9, 0.2)) -> void: var popup := Node3D.new() popup.set_script(load("res://scripts/progression/XpPopup.gd")) parent.add_child(popup) popup.global_position = world_pos popup.configure(text, color) func configure(text: String, color: Color) -> void: _label = Label3D.new() _label.text = text _label.font_size = 54 _label.outline_size = 6 _label.modulate = color _label.billboard = BaseMaterial3D.BILLBOARD_ENABLED _label.no_depth_test = true _label.render_priority = 4 _label.pixel_size = 0.008 add_child(_label) func _process(delta: float) -> void: _elapsed += delta var t: float = _elapsed / _lifetime position.y += _drift * delta if _label != null: var alpha: float = 1.0 - clampf(t, 0.0, 1.0) var c: Color = _label.modulate c.a = alpha _label.modulate = c var scale_factor: float = 1.0 + (1.0 - alpha) * 0.4 _label.scale = Vector3.ONE * scale_factor if _elapsed >= _lifetime: queue_free()