Godot Version
Godot 4.3
Question
Beginner here and probably a simple solution to this problem but cannot figure it out. I have a singleton “DialogueManager”:
extends Node
@onready var text_box_scene = preload("res://Dialogue/textbox.tscn")
var dialog_lines: Array[String] = []
var current_line_index = 0
var text_box
var text_box_position: Vector2
var is_dialogue_active = false
var can_advance_line = false
signal speaking_finished
func start_dialog(position: Vector2, lines: Array[String]):
if is_dialogue_active:
return
#var window_size = get_window().get_size_with_decorations()
dialog_lines = lines
text_box_position = position
#text_box_position.x -= (38/2)
_show_text_box()
is_dialogue_active = true
func _show_text_box():
text_box = text_box_scene.instantiate()
text_box.finished_displaying.connect(_on_text_box_finished_displaying)
get_tree().root.add_child(text_box)
text_box.position = text_box_position
#text_box.position = text_box_position
text_box.display_text(dialog_lines[current_line_index])
can_advance_line = false
func _on_text_box_finished_displaying():
can_advance_line = true
func _unhandled_input(event):
if (
event.is_action_pressed("advance_dialog") &&
is_dialogue_active &&
can_advance_line
):
text_box.queue_free()
current_line_index += 1
if current_line_index >= dialog_lines.size():
is_dialogue_active = false
current_line_index = 0
speaking_finished.emit()
return
_show_text_box()
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
Most of that shouldn’t be relevant but the important part is the signal “speaking_finished”.
Then I have my player which I want to be able to access that “speaking_finished”.
extends CharacterBody2D
const SPEED = 110.0
const JUMP_VELOCITY = 0
var talking = false
const lines: Array[String] = [
"Howdy, there. I'm cowboy chameleon.",
"This is test dialogue."
]
@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D
@onready var collision_shape: CollisionShape2D = $CollisionShape2D
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("interact"):
talking = true
DialogueManager.start_dialog(collision_shape.global_position, lines)
func _on_speaking_finished():
talking = false
func _physics_process(delta: float) -> void:
# Add the gravity.
DialogueManager.speaking_finished.connect(_on_speaking_finished())
if not is_on_floor():
velocity += get_gravity() * delta
# Handle jump.
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
var direction := Input.get_axis("move_left", "move_right")
if talking:
animated_sprite.play("talk")
else:
if direction > 0:
animated_sprite.flip_h = false
elif direction < 0:
animated_sprite.flip_h = true
# Play walk animation
if direction == 0:
animated_sprite.play("idle")
else:
animated_sprite.play("walk")
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
# Flips the sprite to face the right direction
if direction > 0:
animated_sprite.flip_h = false
elif direction < 0:
animated_sprite.flip_h = true
# Play walk animation
if direction == 0:
animated_sprite.play("idle")
else:
animated_sprite.play("walk")
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
I can access the DialogueManager and call start_dialogue fine but I want to connect the signal so that the Player class is informed when the dialogue is finished. I get the following error when running the code as this:
Invalid type in function ‘connect’ in base ‘Signal’. Cannot convert argument 1 from Nil to Callable.
I’ve tried placing this line elsewhere in the player, instantiating a dialogue manager within the player and using that and a number of other things but cannot get it to work. Sorry if this is some obvious mistake on my part, thanks for reading