NPC Dialogue keeps playing wrong text on speech progression

I’ve been making a dialogue system for two NPC’s in my game, a Quest npc and a default npc that gives no quest. Each NPC contains a Greeting dialogue line and a quest response dialogue line.
image
Each NPC has their own MouseButton1Click functions in an If statement checking if they are a quest of default NPC

dialougeGui.Quest.MouseButton1Click:Connect(function()
			if prompt.Name == "GetQuest" then
				print("Writting Quest Text")
				player.PlayerGui.ScreenGui.Click:Play()
				dialougeGui.Quest.Visible = false
				WriteLine(dialougeGui.Text, config.Lines.Quest.Value)
			end
			
		end)

Although the dialogue that plays after you press the Quest button, it merges both NPC’s dialogue despite them being under different proximity prompt If statements.

Both If Statments.

if prompt.Name == "GetQuest" then
		prompt.Enabled = false
		local char = player.Character
		local cam = workspace.CurrentCamera
		local dialougeGui = player.PlayerGui.ScreenGui.Dialouge
		dialougeGui.Visible = true
		
		--prompt.Parent.Parent.Head.Status.Enabled = false
		
		local config = prompt.Parent.Parent.Dialouge
		
		for i,v in pairs(char:GetDescendants()) do
			if v:IsA("BasePart") or v:IsA("Decal") then 
				v.Transparency = 1 
			end
		end

		
		dialougeGui.BackgroundColor = config.QuestColor.Value
		dialougeGui.Title.BackgroundColor = config.QuestColor.Value
		
		dialougeGui.Title.Text = prompt.Parent.Parent.Name
		
		dialougeGui.Quest.Text = config.QuestName.Value
		
		cam.CameraType = Enum.CameraType.Scriptable
		cam.CFrame = CFrame.new(prompt.Parent.Parent.CamPart.Position) * CFrame.Angles(math.rad(prompt.Parent.Parent.CamPart.Orientation.X), math.rad(prompt.Parent.Parent.CamPart.Orientation.Y), math.rad(prompt.Parent.Parent.CamPart.Orientation.Z))
		
		WriteLine(dialougeGui.Text, config.Lines.Greeting.Value)
		
		dialougeGui.Exit.MouseButton1Click:Connect(function()
			player.PlayerGui.ScreenGui.Click:Play()
			prompt.Enabled = true
			cam.CameraType = Enum.CameraType.Custom
			dialougeGui.Visible = false
			dialougeGui.Quest.Visible = true
			dialougeGui.Text.Text = ""
			for i,v in pairs(char:GetDescendants()) do
				if v:IsA("BasePart") or v:IsA("Decal") then 
					if v.Name == "HumanoidRootPart" then
						v.Transparency = 1
					else
						v.Transparency = 0
					end
					
				
				end
			end
		end)
		dialougeGui.Quest.MouseButton1Click:Connect(function()
			if prompt.Name == "GetQuest" then
				print("Writting Quest Text")
				player.PlayerGui.ScreenGui.Click:Play()
				dialougeGui.Quest.Visible = false
				WriteLine(dialougeGui.Text, config.Lines.Quest.Value)
			end
			
		end)
		
	end
	if prompt.Name == "TalkToNPC" then
		prompt.Enabled = false
		local char = player.Character
		local cam = workspace.CurrentCamera
		local dialougeGui = player.PlayerGui.ScreenGui.Dialouge
		dialougeGui.Visible = true


		local config = prompt.Parent.Parent.Dialouge

		for i,v in pairs(char:GetDescendants()) do
			if v:IsA("BasePart") or v:IsA("Decal") then 
				v.Transparency = 1 
			end
		end

		dialougeGui.BackgroundColor = config.QuestColor.Value
		dialougeGui.Title.BackgroundColor = config.QuestColor.Value

		dialougeGui.Title.Text = prompt.Parent.Parent.Name

		dialougeGui.Quest.Text = config.QuestName.Value

		cam.CameraType = Enum.CameraType.Scriptable
		cam.CFrame = CFrame.new(prompt.Parent.Parent.CamPart.Position) * CFrame.Angles(math.rad(prompt.Parent.Parent.CamPart.Orientation.X), math.rad(prompt.Parent.Parent.CamPart.Orientation.Y), math.rad(prompt.Parent.Parent.CamPart.Orientation.Z))

		WriteLine(dialougeGui.Text, config.Lines.Greeting.Value)

		dialougeGui.Exit.MouseButton1Click:Connect(function()
			player.PlayerGui.ScreenGui.Click:Play()
			prompt.Enabled = true
			cam.CameraType = Enum.CameraType.Custom
			dialougeGui.Visible = false
			dialougeGui.Quest.Visible = true
			
			dialougeGui.Text.Text = ""

			for i,v in pairs(char:GetDescendants()) do
				if v:IsA("BasePart") or v:IsA("Decal") then 
					if v.Name == "HumanoidRootPart" then
						v.Transparency = 1
					else
						v.Transparency = 0
					end
				end
			end
		end)
		
		dialougeGui.Quest.MouseButton1Click:Connect(function()
			if prompt.Name == "TalkToNPC" then
				print("Writting Speech Text")
				player.PlayerGui.ScreenGui.Click:Play()
				dialougeGui.Quest.Visible = false
				WriteLine(dialougeGui.Text, config.Lines.Quest.Value)
				
			end
		end)
	end
end)

Been at this for hours, Thanks! :slight_smile:

1 Like

Please don’t use screenshots when showing the code (your font size is too small, and the code has to be rewritten by anyone willing to reproduce the issue since they can’t simply select then Ctrl+C and Ctrl+V to Studio). Copy the code to your post and surround the paragraph with two ```'s.

Example:

```
local ExampleVar = 1
print(ExampleVar)
–Instantly better.
```

Code above will be rendered like this:

local ExampleVar = 1
print(ExampleVar)
--Instantly better.
2 Likes

Sorry about that, the original post has been updated. :slight_smile:

I think is needed to show WriteLine() function too, and the function that holds both if statements of the dialogue, to find the issue easily

The function that holds both if statements is a simple proximity prompt trigger function. The Writeline function displays the text character by character (this can be replaced by just adding the text to a gui element) , my issue being that dialogue from both npcs merges into one text box at the same.
Basically meaning that both MouseButton functions are being called at the same time despite being under different if statements

If you are using the same button in GUI, to trigger a function:

dialougeGui.Quest.MouseButton1Click:Connect()

The next time the prompt event triggers, it choose a different statement, and connect again the same button to a different function that will call the other dialogue.
Meaning you have 2 functions connected to the same button at the same time, when pushing it, calling both dialogues.

I think you should disconnect the connection of each statement when its not used, or keep the connection as a variable accesable from outside the scope function, and save a new connection there replacing the old one.

Thats what I think without testing the whole system

Do you mind providing an example?

Apologies for not posting the full system, I will make sure to do that as soon as I can.

This is a basic example, showing a connection of a button that would disconnect and connect again with different parameters each time a differentDialogue is received by PromptHandler()

local GuiButtonConnection

local function PromptHandler(differentDialogue)
	if differentDialogue == "dialogue1" then
		GuiButtonConnection:Disconnect()
		GuiButtonConnection = gui.Button.Activated:Connect(function()
			-- calling other function in here with params dialogue1
		end)
	elseif differentDialogue == "dialogue2" then
		GuiButtonConnection:Disconnect()
		GuiButtonConnection = gui.Button.Activated:Connect(function()
			-- calling other function in here with params dialogue2
		end)
	end
end

I see where this is going but I need some things cleared up (again my fault for not posting the full system, will do when I can) so does GuiButtonConnecion represent The button MouseButton function? I also assume The activated function plays the dialogue and continues the code?

Yup, GuiButtonConnection is a variable that holds the connection made with the button.Activated event, I used Activated instead of MouseButton1 event, cause I like it more, and works exactly the same is an event called when a button is pressed.

So, GuiButtonConnecion holds a connection that can be disconnected at any time, causing the Activated event to be deleted, the button wont trigger anything until you connect it again, saving it again in the GuiButtonConnecion variable.

But Im not saying thats the best way to do it, you could only connect the button once, never do it again when the prompt is called.

That unique connection of the button, will send a variable to other writeLine function, that variable is the only one that changes when the prompt is called. I’ll give you a small example

Ah, thanks for clearing things up, I am starting to understand. As you said an example would be excellent

1 Like
local currentDialogue -- current dialogue to display

local function WriteLine(currentDialogue)
	print(currentDialogue)
end

-- The button connected once, using the currentDialogue variable
gui.Button.Activated:Connect(function()
	WriteLine(currentDialogue)
end)

-- The handler setting the currentDialogue variable to the current dialogue to use
local function PromptHappens(differentDialogue)
	if differentDialogue == "dialogue1" then
		currentDialogue = "dialogue1"
	elseif differentDialogue == "dialogue2" then
		currentDialogue = "dialogue2"
	end
end
1 Like

It works! Thanks for clearing things up for me :slight_smile:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.