Okay, I tested the code and made a few changes, since I had some syntax errors. Here is the code from the test/prototype project:

extends Area
var _is_player_in_area = false
# We will use the node name to detect if the node is the
# player or not. You may need to change this depending
# on how your game is setup and/or project requirements
export (String) var player_node_name = "Player"
# Custom signal (I’m not sure if the syntax here is correct...)
signal on_player_interact
# track if the player has interacted so we do not restart
# the interaction while the dialog is going
var _has_player_interacted = false

func _ready():
	connect("body_entered", self, "_on_body_entered")
	connect("body_exited", self, "_on_body_exited")
	
	connect("on_player_interact", self, "_test_function");

func _process(delta):
	if _is_player_in_area == true and _has_player_interacted == false:
		# In this example, the interact key is E, though you
		# probably want to change this with an action
		if Input.is_key_pressed(KEY_E):
			emit_signal("on_player_interact")
			_has_player_interacted = true
			# Interact prompt UI should, probably, be disabled here.

func _on_body_entered(other):
	if other.name == player_node_name:
		_is_player_in_area = true
		_has_player_interacted = false
		# If you have UI to show (like “press E to interact”)
		# then you could enable it here.

func _on_body_exited(other):
	if _is_player_in_area == true:
		if other.name == player_node_name:
			_is_player_in_area = false
			_has_player_interacted = false

func _test_function():
	print ("Interacted!");

The issue I was having was that the Godot didn't like " and I used the wrong name for the Input function. I was not able to reproduce the signal issue, it just worked, though to be fair I just connected the signal to simple function within the same script.

(Sorry about the delay! I thought I could get to it yesterday, but it didn't work out)

@TwistedTwigleg I will show my Hierarchy , because for some reason I still have an error but I dont know why but when I typed yours over I had the error and I also when I Copy Pasted it I had the error)

Cuz my problem could be because of a wrong tree.

The error that I keep getting is btw: Error calling method from signal 'body_entered': 'Area(NPC.gd)::_on_NPC_body_entered': Method not found.

What if you try to delete and recreate the signal on the NPC node? I wonder if it isn't the NPC node name, from the error it seem like you might have created the signal on it before you renamed the node?

@Megalomaniak I am going to look into that cuz it is strange that it does work on @TwistedTwigleg his side Thanks for the tip

@TwistedTwigleg How does your Project look like ( hierarchy and connections) because in the script there are 3 connections made

I want to know which one is connected to which. Those give me the yellow warning saying they aren't used which they should be.

I also found out that when E is pressed no print is made which says 'interact'

I want to know this because I want to be sure that I am following the right steps and no longer cause a bit of confusion. ?

Here is what my scene looks like:

The reason it looks a little strange is because I slapped it into another prototype project for testing purposes. If you want, I can make a fresh project and upload it here to the forums if that would help.

@TwistedTwigleg Again I have tried to rewrite the code, Copy pasted it and also tried theorising why yours works and mine doesnt and I am really stun by this but I really don't know :/

so yeah maybe it is better if you could send a fresh project

I would be really happy if the trigger system is able to work cuz that gives a huge step into making a dialog system work =)

Try recreating the node structure with the Area node named as Area and the script, thus, named as Area.gd

@Megalomaniak @TwistedTwigleg I will try to test all of this tomorrow

(depends on when you are reading it, so from this post?)

Thanks btw?

@TwistedTwigleg sorry for the long wait had a lot to do yesterday but after a lot of digging through your code and also trying to copy it (word for word in code and build up) I have managed to make this work!

I am really happy that the trigger system finally worked this will make the step to connecting for conversations much easier.

because now I only need to look how to make is an action func like when pressing E start .JSON file instead of the label text. =)

No worries on the delay. I'm glad the sample project was useful! :D

When I get everything done (before some time) I will make a video about this so other don't have to bumb into this so hard like I did for the past 6 months ?

Hi again, I have found a code which controls the writting and control of the text. I have changed it around a bit so I can control the page changing with the SPACEBAR

extends RichTextLabel

var dialog = ["Hey! My name is Benjamin.", "Welcome to the TestStet world"]
var page = 0

func _ready():
	set_bbcode(dialog[page])
	set_visible_characters(0)
	set_process_input(true)

func _input(event):
	if event is InputEventKey and event.get_scancode() == KEY_SPACE && event.is_pressed():
		if get_visible_characters() > get_total_character_count():
			if page < dialog.size()-1:
				page += 1
				set_bbcode(dialog[page])
				set_visible_characters(0)>

func _on_Timer_timeout():
	set_visible_characters(get_visible_characters()+1)

This from a tutorial coding from HeartBeast - Youtube

The label that we have now can be changed into a RichTextLabel which also uses bbcode

I was wondering where (or how) I can place the load function. At first I thought that I could use the

var dialog line to place a load method but I wasn't able to make it happen

My .JSON file uses id's to detect which lines of dialog are going to be loaded

If the file is needed I will be able to sent it

@TwistedTwigleg I have managed to connect the .JSON file with the Trigger Project so it is almost connected like how I want it to be. But the panel is shown before I press the "Interact" button and it causes an error.

I somehow can't seem to connect the 2 properly using the "Interact" button (The E-key) Cuz what I said in the post above this one was that the .JSON file of mine uses id numbers. This is used so when called, it knows which one to use.

name: is meant for the character I will use the line for

text: is just the normal text

next_id: This means that after the line of text(dialogue) is shown, it will go to the next dialog in line, I myself can make a line which uses the dialogue number 13 for instance and force it to choose that route instead of going +1.

if a -1 stands in the line of next_id it means that the conversation stopped and that there is no further route it can take unless changed by developer

(I wrote this in case you or others didn't know what is being said in the code)

Here is the full code I used for connecting this all up with eachother (If th picture is hard to read let me know or try and right-click the image to see it in other tab)

After all of that I just don't know how to make it skip a page and how to connect the interact button with it

Hopefully this helps because I am very very close right now.

PS: The # lines (In the UPDATE UI) were used for the question and answer section but I want to get rid of them and want to use them in a later stage of development.

Sorry about the delay, I meant to get back sooner but things were busy and I forgot :sweat_smile: Sorry!

I glanced through the code quickly, but based on what I have seen, it looks like you can start/connect the dialog with the interact button by calling the start_dialog function. Especially if the trigger and dialog are in the same file, then it should just be a matter of calling the function. As for skipping the text, I'd recommend making a variable that has detected if the dialog text timer has finished, and then if that variable is true, change the dialog to the next page when the interact button is pressed.

For example, I think the following modifications should work:

# we need to know whether the key was just pressed or not. We'll just use a
# simple boolean, though I would recommend changing this to a Input action
# in the future.
var is_interact_key_down = false

# A boolean to track if the dialog is fully visible and can be skipped...
var is_dialog_page_finished = false

func _process(delta):
	if _is_player_in_area == true:
		if Input.is_key_pressed(KEY_E):
			# Key was just pressed!
			if is_interact_key_down == false:
				# Do we need to start the dialog?
				if _has_player_interacted == false:
					StartDialog()
				# Dialog is going...
				else:
					# Is all of the dialog visible?
					if is_dialog_page_finished == true:
						# Move to the next dialog node (HandleNode?)
						HandleNode()
					# If all of the dialog is not finished
					else:
						# Show all of the dialog
						RichTextLabel.set_visible-characters(RichTextLabel.get_total_character_count()+1)
						is_dialog_page_finished = true

# Then when the timer (or whatever you are using) has shown all of the dialog.
# (I'm assuming you are using something like the HeartBeast code snippet)
func _on_Timer_timeout():
	RichTextLabel.set_visible-characters(RichTextLabel.get_total_character_count()+1)
	is_dialog_page_finished = true

Then the rest of the code/functions shouldn't need adjusting. I'd make a backup/copy of the code you currently have before trying the code above, since I have not tested it and wrote the entire thing from memory, but I think it should work. If it doesn't work, I'll take a closer look and see if I can help find a solution.

@TwistedTwigleg No worries about the delay :)

The code might work but I am not really able to see where I need to place it (so for now I cant really tell because it gave me errors)

I have put it in the UPDATE UI method and also in the TRIGGER.gd

I also made a special zone in my project where I test everything so the Trigger project is safe. :)

As a question: Isn't it a possible to connect the StartDialog() inside of the TRIGGER.gd with the Control node because we do have the signal that starts the conversation and will be able to sent the signal to the other code to display the text.

I assumed (not sure why to be honest) that the trigger and dialog were in the same script, in which case what I wrote above may work, but if they are separate, then adjustments will need to be made. Personally, I would keep them separate if possible, as then the triggers are more flexible.

That said, I'm not sure where the best place to put it would be. If the nodes are separate, then I might change it to something like this (untested):

The (new) trigger script:

extends Area
var _is_player_in_area = false

export (String) var player_node_name = "Player"

signal on_player_interact
# New signal for detecting further interactions
signal on_player_continued_interact

var _has_player_interacted = false

func _ready():
	connect("body_entered", self, "_on_body_entered")
	connect("body_exited", self, "_on_body_exited")
	
	# Optional:
	connect("on_player_interact", self, "_test_interact_function")
	connect("on_player_continued_interact", self, "_test_continued_interact_function")

func _process(delta):
	if _is_player_in_area == true:
		if Input.is_key_pressed(KEY_E):
			if _has_player_interacted == false:
				emit_signal("on_player_interact")
				_has_player_interacted = true
			else:
				emit_signal("on_player_continued_interact")

func _on_body_entered(other):
	if other.name == player_node_name:
		_is_player_in_area = true
		_has_player_interacted = false

func _on_body_exited(other):
	if _is_player_in_area == true:
		if other.name == player_node_name:
			_is_player_in_area = false
			_has_player_interacted = false

func _test_interact_function():
	print ("Interaction started!")
func _test_continued_interact_function():
	print ("Interaction continued!")

Then something like this in the dialog script itself:

Note: I am assuming the on_player_interact signal from the trigger is connected to a function called "on_trigger_interact" and on_player_continued_interact is connected to a function called "on_trigger_continued_interact"

var is_dialog_page_finished = false

func _on_trigger_interact():
	StartDialog()
func _on_trigger_continued_interact():
	if is_dialog_page_finished == false:
		RichTextLabel.set_visible_characters(RichTextLabel.get_total_character_count()+1)
		is_dialog_page_finished = true
	else:
		HandleNode()

I'm not totally sure the code will work though...

As a question: Isn't it a possible to connect the StartDialog() inside of the TRIGGER.gd with the Control node because we do have the signal that starts the conversation and will be able to sent the signal to the other code to display the text.

It should be possible. You should be able to connect the on_player_interact signal to start the conversation, either in the Godot editor or through code like get_node("Trigger").connect("on_player_interact", self, "function_name_here").

@TwistedTwigleg Well I came to a point where the dialogue box was hidden but I am not sure if that was done by a mistake or via a wrong input.

for now I only get this error message:

Error calling method from signal 'on_player_interact': 'Control(TESTTextbubble.gd)::on_Trigger_on_player_interact': Method not found. <C Source> core/object.cpp:1238 @ emit_signal() <Stack Trace> TESTTrigger.gd:18 @ process()

the good news is that the project does keep running without shutting down because of an error. and that there is only 1 error message

From what I can gather from the error message, the signal is looking for a function called _on_Trigger_on_player_interact but it does not exist. Maybe try changing the _on_player_interact function to _on_Trigger_on_player_interact and see if that works?