Trigger character animations and visual effects during dialogue using metadata
This example demonstrates how to use metadata to trigger animations, hide specific options, and create dynamic visual effects during dialogue. This builds on the metadata handling pattern to create more immersive dialogue experiences.
extends DialogueEngineenum { DEFAULT_TOPIC = 0, # this is the branch used by default unless set_branch_id() is used WATCH_THE_STORM, GO_BACK_TO_SLEEP, KEEP_WORKING,}func _setup() -> void: var entry: DialogueEntry = add_text_entry("The storm rages right outside the window. I should...") var option_id_1: int = entry.add_option("Wait for storm to finish.") var option_id_2: int = entry.add_option("Go back to sleep.") var option_id_3: int = entry.add_option("Get back to work.") var option_id_4: int = entry.add_option("Hidden option -- this should not be shown on the UI") entry.set_metadata("dont_show_options", [option_id_4]) entry.set_metadata("auto_choose", option_id_4) var option_id_2_entry: DialogueEntry = add_text_entry("That's right, sleep is for the strong 💪.", GO_BACK_TO_SLEEP) entry.set_option_goto_id(option_id_2, option_id_2_entry.get_id()) var option_id_3_entry: DialogueEntry = add_text_entry("That's right, let's get back to work 🫡", KEEP_WORKING) entry.set_option_goto_id(option_id_3, option_id_3_entry.get_id()) var option_id_4_entry: DialogueEntry = add_text_entry("I think I'll enjoy watching the storm for a bit...", WATCH_THE_STORM) entry.set_option_goto_id(option_id_4, option_id_4_entry.get_id()) # Join branches into the default topic (i.e. branch id 0) var default_topic: DialogueEntry = add_text_entry("Some time passes...") entry.set_option_goto_id(option_id_1, default_topic.get_id()) option_id_2_entry.set_goto_id(default_topic.get_id()) option_id_3_entry.set_goto_id(default_topic.get_id()) option_id_4_entry.set_goto_id(default_topic.get_id()) add_text_entry("<Press 'Space' or 'Enter' to quit>")
var option_id_1: int = entry.add_option("Wait for storm to finish.")var option_id_2: int = entry.add_option("Go back to sleep.")var option_id_3: int = entry.add_option("Get back to work.")var option_id_4: int = entry.add_option("Hidden option -- this should not be shown on the UI")
All four options are added to the entry, but option 4 will be hidden from the player.
var option_id_2_entry: DialogueEntry = add_text_entry("That's right, sleep is for the strong 💪.", GO_BACK_TO_SLEEP)entry.set_option_goto_id(option_id_2, option_id_2_entry.get_id())var option_id_3_entry: DialogueEntry = add_text_entry("That's right, let's get back to work 🫡", KEEP_WORKING)entry.set_option_goto_id(option_id_3, option_id_3_entry.get_id())var option_id_4_entry: DialogueEntry = add_text_entry("I think I'll enjoy watching the storm for a bit...", WATCH_THE_STORM)entry.set_option_goto_id(option_id_4, option_id_4_entry.get_id())
Even though option 4 is hidden, it still needs a valid goto ID since it can be auto-selected.
var dont_show_options: Array = p_dialogue_entry.get_metadata("dont_show_options", [])for option_id: int in range(0, p_dialogue_entry.get_option_count()): if option_id in dont_show_options: continue # Create button for this option
The UI checks the dont_show_options metadata and skips creating buttons for those option IDs.
Let’s extend this to include actual character animations:
func _setup() -> void: var entry: DialogueEntry = add_text_entry("*looks at the window nervously*") \ .set_metadata("character", "Player") \ .set_metadata("animation", "look_window") \ .set_metadata("emotion", "nervous") var option_id_1: int = entry.add_option("Take a deep breath") var option_id_2: int = entry.add_option("Ignore the storm") var calm_entry: DialogueEntry = add_text_entry("*breathes deeply and relaxes*", CALM_BRANCH) \ .set_metadata("animation", "breathe") \ .set_metadata("emotion", "calm") entry.set_option_goto_id(option_id_1, calm_entry.get_id()) var ignore_entry: DialogueEntry = add_text_entry("*turns away from the window*", IGNORE_BRANCH) \ .set_metadata("animation", "turn_away") \ .set_metadata("emotion", "determined") entry.set_option_goto_id(option_id_2, ignore_entry.get_id())
func __on_dialogue_continued(entry: DialogueEntry) -> void: if entry.has_metadata("animation"): var anim_name = entry.get_metadata("animation") character_animator.play(anim_name) if entry.has_metadata("sfx"): var sfx = entry.get_metadata("sfx") audio_player.stream = load("res://sfx/" + sfx + ".ogg") audio_player.play() # Wait for animation to finish before showing text if entry.get_metadata("animation_wait", false): var duration = entry.get_metadata("animation_duration", 1.0) await get_tree().create_timer(duration).timeout # Now show the dialogue text dialogue_label.text = entry.get_text()