extends Node2D # Dialogue system for Godot 4.x # Handles displaying dialogue with animations and text reveal # Signals signal dialogue_started() signal dialogue_completed() # Configuration @export var text_reveal_speed: float = 0.05 # seconds per character @export var show_animation_duration: float = 0.3 # seconds @export var hide_animation_duration: float = 0.2 # seconds # Private variables @onready var dialogue_box = $PanelContainer @onready var text_label: Label = $PanelContainer/Label var timer: Timer = null var current_text: String = "" var current_duration: float = 0.0 var text_index: int = 0 var is_showing: bool = false var is_revealing: bool = false func _ready(): # Initialize the dialogue system pass func trigger_dialogue(text: String, duration: float = 3.0) -> void: """Trigger dialogue with specified text and duration""" if is_showing: return current_text = text current_duration = duration text_index = 0 is_showing = true is_revealing = false # Show the dialogue box with animation show_dialogue_box() # Start revealing text after a short delay to allow animation to complete await get_tree().create_timer(show_animation_duration) # Start revealing text immediately start_text_reveal() func show_dialogue_box(): """Show dialogue box with animation""" dialogue_box.visible = true # Animate in using Tween var tween = create_tween() tween.set_ease(Tween.EASE_OUT) tween.set_trans(Tween.TRANS_SINE) tween.tween_property(dialogue_box, "modulate:a", 1.0, show_animation_duration) # Emit signal when animation completes await tween.finished emit_signal("dialogue_started") func hide_dialogue_box(): """Hide dialogue box with animation""" # Animate out using Tween var tween = create_tween() tween.set_ease(Tween.EASE_IN) tween.set_trans(Tween.TRANS_SINE) tween.tween_property(dialogue_box, "modulate:a", 0.0, hide_animation_duration) # Wait for animation to complete await tween.finished dialogue_box.visible = false is_showing = false is_revealing = false emit_signal("dialogue_completed") func start_text_reveal(): """Start revealing text character by character""" if is_revealing: return is_revealing = true text_label.text = "" text_index = 0 # If duration is 0 or negative, don't auto-hide if current_duration <= 0: # Just reveal all text immediately text_label.text = current_text is_revealing = false return # Start timer for automatic hiding timer = Timer.new() timer.wait_time = current_duration timer.one_shot = true timer.connect("timeout", self._on_dialogue_timeout) add_child(timer) timer.start() # Start the character-by-character reveal reveal_next_character() func reveal_next_character(): """Reveal the next character in the text""" if text_index >= current_text.length(): # Finished revealing all characters is_revealing = false return # Add the next character to the text label text_label.text += current_text[text_index] text_index += 1 # Schedule next character reveal await get_tree().create_timer(text_reveal_speed).timeout reveal_next_character() func _on_dialogue_timeout(): """Handle dialogue timeout""" if is_showing and not is_revealing: hide_dialogue_box()