Button that cycles through commands?

Godot Version

Godot 4.4

Question

I want to make a button that instantiates a new text label every time it is pressed. However, I only know how to instantiate one text label. How can I code the button so that it cycles through new texts when the same button is pressed?

Here is what the project looks like now. When the button is pressed, a new label appears underneath the first label. I want the new labels to display different text from the label above.

Here is the code of the main scene:

extends Control

@onready var button: Button = $Panel/MarginContainer/VBoxContainer/Button

const TEXTS = preload("res://scenes/texts.tscn")

@onready var dialogue_entries: VBoxContainer = $Panel/MarginContainer/VBoxContainer/ScrollContainer/DialogueEntries

func _on_button_pressed() -> void:
	var entry = TEXTS.instantiate()
	dialogue_entries.add_child(entry)
	entry.set_content("And, on his ample forehead aiming full,")

Here is the code of the text labels:

extends MarginContainer

@onready var richlabel: RichTextLabel = $RichTextLabel


func set_content(text: String) -> void:
	var content = text
	richlabel.text = content
	await get_tree().process_frame

You would need to store the different lines somewhere, ideally an array:

const CONTENTS: Array[String] = [
	"And, on his ample forehead aiming full,",
	"he didn't know what the second line was",
	"..."
]

Then you can access the elements one after another by incrementing a counter each time the button is pressed:

var _next_content_index: int = 0

func _on_button_pressed() -> void:
	var entry = TEXTS.instantiate()
	dialogue_entries.add_child(entry)

	if _next_content_index >= CONTENTS.size():
		print("The last line has already been added!")
		return
	entry.set_content(CONTENTS[_next_content_index])
	_next_content_index += 1

I can’t test anything right now, sorry if there’s a mistake

By the way, the line await get_tree().process_frame doesn’t do anything useful at the end of a function and you can remove it

2 Likes

That worked for me, thank you so much!