#Instantiating Dialogue Resources on instantiated Door events

1 messages · Page 1 of 1 (latest)

strange stag
#

Hi,
I'm using Dialogue Manager 3 by Nathan Hoad and have set up some dialogues with NPCs, which are all working great.

My next step was to add dialogue events to the doors of a house.

To do this, I used a TileMap layer, marked a tile with a door, and placed that door on each of my four houses. At the same position, I spawn a Node2D called ActionableDoor, which includes a StaticBody2D for collision so that my player can’t walk through it. Also at the same position, I spawn a DialogueComponent (which has an Area2D) to detect interaction when I press ui_accept. This DialogueComponent has a script for handling the dialogue logic.

I have four doors in the world and identified them using tilemap coordinates. In my World or GameManager code, I assign a different DialogueResource to each door, so that each one has a unique conversation.

My problem:
Spawning the ActionableDoor works fine — it shows up with both its Area2D and StaticBody2D. But for some reason, after spawning a DialogueComponent onto the doors, the dialogue resources won’t load, even though I’m using the correct path.

Additional info: I use @export to set a dialogue_resource for the NPCs but the Node itself has an <empty> resource which I thought would cause the issue. After setting a default resource the problem still persists.

Here's my debug output when starting the scene:

Test dialogue_res_1:<DialogueResource titles="Start,Start2">
Dialog set for door at:(35, 30)  <null>
Children of door:[StaticBody2D:<StaticBody2D#...>, DialogueComponent:<Area2D#...>]
Dialogue resource for this door:<null>
Setting dialogue for door at:(35, 30)

... (same for other doors) ...

Starting dialogue attempt
Starting dialogue with resource: <null>

I'll attach my scripts in the next messages since they're too long for one post.

#

dialogue_component.gd:

extends Area2D
class_name DialogueComponent

@export var dialogue_resource: DialogueResource
@export var start_title := "Start"

var player_in_range := false
var dialogue_running := false

func _ready():
    connect("body_entered", Callable(self, "_on_body_entered"))
    connect("body_exited", Callable(self, "_on_body_exited"))

func _process(delta):
    if player_in_range and Input.is_action_just_pressed("ui_accept") and not dialogue_running:
        print("Starting dialogue attempt")
        start_dialogue()

func _on_body_entered(body):
    if body.name == "Player":
        player_in_range = true

func _on_body_exited(body):
    if body.name == "Player":
        player_in_range = false

func start_dialogue():
    print("Starting dialogue with resource: ", dialogue_resource)
    if dialogue_resource:
        dialogue_running = true
        print("Dialogue started with:", dialogue_resource)
        DialogueManager.show_dialogue_balloon(dialogue_resource, start_title)

        if not DialogueManager.dialogue_ended.is_connected(_on_dialogue_ended):
            DialogueManager.dialogue_ended.connect(_on_dialogue_ended)
    else:
        push_warning("Dialogue resource not assigned!")

func _on_dialogue_ended(resource):
    dialogue_running = false
#

game_manager.gd (1/2):

extends Node2D
class_name GameManager

@onready var door_marker_tilemap := get_node("/root/World/DoorMarkerLayer")
@onready var door_scene := preload("res://Scenes/actionable_door.tscn")
@onready var sound_component_scene := preload("res://Scenes/sound_component.tscn")
@onready var dialogue_component_scene := preload("res://Scenes/dialogue_component.tscn")

@onready var dialogue_res_1 := preload("res://dialoguefiles/resource/door.dialogue")
@onready var dialogue_res_2 := preload("res://dialoguefiles/resource/door_2.dialogue")
@onready var dialogue_res_3 := preload("res://dialoguefiles/resource/door_3.dialogue")
@onready var dialogue_res_4 := preload("res://dialoguefiles/resource/door_4.dialogue")
@onready var dialogue_res_5 := preload("res://dialoguefiles/resource/door_5.dialogue")

var door_dialogue_map: Dictionary = {
    Vector2i(35, 30): dialogue_res_1,
    Vector2i(53, 24): dialogue_res_2,
    Vector2i(40, 16): dialogue_res_3,
    Vector2i(19, 45): dialogue_res_4,
}
#

game_manager.gd (2/2):

var sound_component: Node = null

func _ready():
    print("Test dialogue_res_1:", dialogue_res_1)

    # Instantiate the sound component and start background music
    sound_component = sound_component_scene.instantiate()
    add_child(sound_component)
    sound_component.play_background_music()

    # Create doors with dialogues
    for position in door_marker_tilemap.get_used_cells():
        var world_position = door_marker_tilemap.map_to_local(position)
        var door_instance = door_scene.instantiate()
        door_instance.position = world_position

        if door_dialogue_map.has(position):
            var dialogue_component = dialogue_component_scene.instantiate()
            door_instance.add_child(dialogue_component)

            # Wait one frame before assigning the resource
            await get_tree().process_frame
            dialogue_component.dialogue_resource = door_dialogue_map[position]

            print("Dialogue set for door at:", position, " → ", dialogue_component.dialogue_resource)
            print("Children of door:", door_instance.get_children())
            print("Dialogue resource of this door:", dialogue_component.dialogue_resource)
            print("Setting dialogue for door at:", position)

            var label = Label.new()
            if dialogue_component.dialogue_resource != null:
                label.text = "Dialogue: " + str(dialogue_component.dialogue_resource.resource_path)
            else:
                label.text = "Dialogue: null"
            label.position = Vector2(0, -20)
            door_instance.add_child(label)
        else:
            print("No dialogue for door at:", position)

        add_child(door_instance)