Function keeps on doubling up

im currently working on a dialogue system, i had no bugs before and ive been trying to work on a system so u can skip through the typewriter animation so u can go through dialogue quicker

the issue is that basically the system works fine at the start, but after you pick your first dialogue choice, the functions seem to stack so it once you go onto the second part of the dialogue, it automatically skips the animation aswell.

(Messyish) Dialogue Script

local player = game:GetService('Players').LocalPlayer
local dialogue = require(game.ReplicatedStorage.Modules.Dialogue)
local tweenService = game:GetService('TweenService')
local fadeDuration = 0.5
local tweenFadeIn = TweenInfo.new(fadeDuration, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local sizeTweenInfo = TweenInfo.new(1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local tweenFadeOut = TweenInfo.new(fadeDuration, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
local dialogueAnimationEvent = game:GetService('ReplicatedStorage').Events.Bindable.DialogueAnimation
local dialogueEvent = game:GetService('ReplicatedStorage').Events.Bindable.Dialogue
local dialogueCG = script.Parent.DialogueCG
local OptionsCG = script.Parent.DialogueCG.DialogueBorder.Options
local choiceTemplate = game:GetService('ReplicatedStorage').GUI.ChoiceTemplate
local sfx = player.PlayerGui.SFX
local uis = game:GetService('UserInputService')
local currentDialogueLine

local canClick = true
local dialogueChat = false
local isTyping = true
local isInDialogue = false
local canSkip = false

dialogueCG.GroupTransparency = 1
dialogueCG.Position = UDim2.new(0.5,0,0.6,0)

local function skipDialogue(textLabel, text, textCooldown)
	textLabel.Text = text
	isTyping = false
	wait(textCooldown) --How long before the choices appear
	script.Parent.DialogueCG.DialogueBorder.DialogueFrame.Continue.Visible = true
	player.PlayerGui.SFX["switch.wav"]:Play()
	canSkip = true

end



local function typeText(textLabel, text, textCooldown, textSpeed, sound)
	isTyping = true
	for i = 1, #text do
		if isTyping == true then
			textLabel.Text = string.sub(text, 1, i)
			wait(0.2)
			if sound ~= nil then
				player.PlayerGui.SFX:FindFirstChild(sound):Play()
			end
		else
			
			return
		end
	end
	isTyping = false
	wait(textCooldown) --How long before the choices appear
	script.Parent.DialogueCG.DialogueBorder.DialogueFrame.Continue.Visible = true
	player.PlayerGui.SFX["switch.wav"]:Play()
	canSkip = true

end

dialogueAnimationEvent.Event:Connect(function(show)
	if show == true then
		tweenService:Create(dialogueCG, tweenFadeIn, {Position = UDim2.new(0.5,0,0.5,0)}):Play()
		tweenService:Create(dialogueCG, tweenFadeIn, {GroupTransparency = 0}):Play()
	else
	end

end)

local function showChoices(choices)
	canClick = true

	if #choices ~= 0 then
		for _, choice in choices do
			local newChoice = choiceTemplate:Clone()
			newChoice.Parent = script.Parent.DialogueCG.DialogueBorder.Options.OptionsBorder
			newChoice.TextLabel.Text = choice
			newChoice.Name = choice

			newChoice.MouseButton1Click:Connect(function()
				if canClick == true then
					canClick = false
					sfx["click"]:Play()
					tweenService:Create(newChoice.UIScale, sizeTweenInfo, {Scale = 1.1}):Play()
					newChoice.LocalScript.Enabled = false
					task.wait(1.2)
					local currentDialogueSettings = dialogue.Test.Choices[choice]
					dialogueChat = true
					runDialogue(currentDialogueSettings.Dialogue, currentDialogueSettings.Choices)
				end
			end)
		end

		tweenService:Create(OptionsCG, tweenFadeIn, {GroupTransparency = 0}):Play()
	else
		isInDialogue = false
		player.Character:FindFirstChild('Humanoid').WalkSpeed = workspace.Values.DefaultPlayerStats.WalkSpeed.Value
		player.Character:FindFirstChild('Humanoid').JumpHeight = workspace.Values.DefaultPlayerStats.JumpHeight.Value
		tweenService:Create(dialogueCG, tweenFadeIn, {Position = UDim2.new(0.5,0,0.6,0)}):Play()
		tweenService:Create(dialogueCG, tweenFadeIn, {GroupTransparency = 1}):Play()
	end
end

local line = 0

local function dialogueLines(currentDialogue, choices)
	currentDialogueLine = currentDialogue
	canSkip = false
	if line <= #currentDialogue and dialogueChat == true then
		
		for _, a in pairs(script.Parent:GetDescendants()) do
			if a:IsA('UIGradient') then
				a.Color = currentDialogue[line].Gradient.Color
			end
		end
		
		script.Parent.DialogueCG.DialogueBorder.CharacterName.CharacterName.Text = currentDialogue[line].Character
		typeText(script.Parent.DialogueCG.DialogueBorder.DialogueFrame.DialogueBorder.TextLabel, currentDialogue[line].Text, currentDialogue[line].Cooldown, currentDialogue[line].Speed, currentDialogue[line].Sound)
		line += 1
		return
	elseif line > #currentDialogue and dialogueChat == true then
		dialogueChat = false
		showChoices(choices)
	end
end

function runDialogue(currentDialogue, choices)
	dialogueChat = true
	line = 1
	tweenService:Create(OptionsCG, tweenFadeOut, {GroupTransparency = 1}):Play()
	local dialogueSection = player.PlayerScripts.Values:FindFirstChild("DialogueSection")
	local rep = player.PlayerScripts.Values:FindFirstChild("AspenReputation")
	coroutine.wrap(function()
		task.wait(fadeDuration)
		for _, choice in pairs(script.Parent.DialogueCG.DialogueBorder.Options.OptionsBorder:GetChildren()) do
			if choice:IsA("GuiButton") then
				choice:Destroy()
			end
		end
	end)()
	
	uis.InputBegan:Connect(function(input, a)
		if a then return end
		if input.KeyCode == Enum.KeyCode.Space then
			if canSkip == true and isTyping == false and isInDialogue == true then
				script.Parent.DialogueCG.DialogueBorder.DialogueFrame.Continue.Visible = false
				dialogueLines(currentDialogue, choices)
			elseif isTyping == true and canSkip == false and isInDialogue == true then
				skipDialogue(script.Parent.DialogueCG.DialogueBorder.DialogueFrame.DialogueBorder.TextLabel, currentDialogue[line].Text, currentDialogue[line].Cooldown / 2)
				return
			end
		end
	end)

	dialogueLines(currentDialogue)
	
end

dialogueEvent.Event:Connect(function(a, b, c)
	if isInDialogue == false then
		
		player.Character:FindFirstChild('Humanoid').WalkSpeed = 0
		player.Character:FindFirstChild('Humanoid').JumpHeight = 0

		isInDialogue = true
		runDialogue(a, b, c)
	end
end)

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

1 Like

Does your code automatically skip at the end of the animation?
Sounds like you aren’t cancelling that task, so it just skips when it was supposed to end.

sorta yeah, i added a video if u wanna take a look

Sorry your code is a bit hard to read, can you add a few prints to check when your functions are running?

i tried that and it seems that it registers the space bar being pressed multiple times

could it be because the runDialogue() function in my script is ran multiple times which then runs the inputbegan function?

Oh yeah that’s probably the issue, you should just connect it once outside that function or disconnect it when space was pressed.

how could i disconnect the function?

:Connect returns a RBXSCRIPTCONNECTION object, which has a :Disconnect() method you can use, to use it within the anonymous function, you can define the variable first, then assign it the connection object.

(on my phone rn, read the docs for more info)

nvm i just connected it outside the function, thanks for your help tho

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