Help with NPC script (again)

I’ve been working on an NPC talking system, and I’m basically done. However, I’m having an issue.

It’s pretty much the last thing I need to do.

To finish up, I’m trying to implement this system where it checks how many pages there are. I set mine to 3 pages of text, but it still shows the 4th page as an empty nothing.
(You will need to view the code)

ModuleScript:
local talk = {}
script.Parent.Enabled = false
talk.talkfunction = function(player)
--	local dbounce = false
	script.Parent.Enabled = false
--	print(script.Parent.Enabled)
	local textlabel1 = script.Parent:WaitForChild("Main"):WaitForChild("Text1")
	local textlabel2 = script.Parent:WaitForChild("Main"):WaitForChild("Text2")
	--local lines = require:(game.StarterPlayer.StarterCharacterScripts:WaitForChild(Lines)
	local npcs = game.Workspace.NPCs
	local Dummy = npcs.Dummy
	local page = 1
	local proceed = script.Parent:WaitForChild("Main"):WaitForChild("Proceed")
	local pagedone = false
	local lastpage = false
	local ispage2 = true
	local ispage3 = true
	local ispage4 = false
	local txt1 = "text test so i can copy this"
	local txt2 = "text test so i can copy this"
	local txt3 = "text test so i can copy this"
	local txt4 = "text test so i can copy this"
	local txt5 = "text test so i can copy this"
	local txt6 = "text test so i can copy this"
	local txt7 = "text test so i can copy this"
	local txt8 = "text test so i can copy this"


	local function typewrite(object,text)
		for i = 1,#text,1 do
			object.Text = string.sub(text,1,i)
			game:GetService("RunService").Stepped:Wait(0.001)
		end
	end

	local function dummyText(player)
		local dialoguefinished = false
		if script.Parent.Enabled == false then --if script.Parent.Enabled and dbounce == false then
		--	dbounce = true
			--warn("Began")
			local char = player.Character
			local hum = char.Humanoid
			hum.JumpPower = 0
			hum.WalkSpeed = 0
			hum.AutoRotate = false
			page = 1
			pagedone = false
			lastpage = false
			script.Parent.Enabled = true
	--		dialoguefinished = false
			typewrite(textlabel1,txt1)
			typewrite(textlabel2,txt2)
			pagedone = true
			local proceedevent
			proceedevent = proceed.MouseButton1Click:Connect(function()
				if lastpage and pagedone then
					script.Parent.Enabled = false
					textlabel1.Text = ""
					textlabel2.Text = ""
					hum.JumpPower = 50
					hum.WalkSpeed = 16
					hum.AutoRotate = true
					page = 1
					pagedone = false
					lastpage = false
					dialoguefinished = true
					proceedevent:Disconnect()
				--	dbounce = false
				elseif page ==1 and pagedone and ispage2 then
					textlabel1.Text = ""
					textlabel2.Text = ""
					page = 2
					pagedone = false
					lastpage = false
					typewrite(textlabel1, txt3)
					typewrite(textlabel2, txt4)
					pagedone = true
					pagedone = true
				elseif page == 2 and pagedone and ispage3 then
					textlabel1.Text = ""
					textlabel2.Text = ""
					pagedone = false
					page = 3

					typewrite(textlabel1, txt5)
					typewrite(textlabel2, txt6)
					pagedone = true
					--page = 1
				--	lastpage = true
				elseif page == 3 and pagedone and ispage4 then
					textlabel1.Text = ""
					textlabel2.Text = ""
					pagedone = false
					page = 4

					typewrite(textlabel1, txt7)
					typewrite(textlabel2, txt8)
					pagedone = true
					page = 1
					lastpage = true
				elseif page == 3 and pagedone and not ispage4 then
					lastpage = true
					page = 1
					pagedone = true
					textlabel1.Text = ""
					textlabel2.Text = ""
				elseif page == 2 and pagedone and not ispage3 then
					lastpage = true
					page = 1
					pagedone = true
					textlabel1.Text = ""
					textlabel2.Text = ""
				elseif page == 1 and pagedone and not ispage2 then
					lastpage = true
					page = 1
					pagedone = true
					textlabel1.Text = ""
					textlabel2.Text = ""
				end
			end)
			repeat
				wait(0.05)
			until dialoguefinished == true
		else

		end

	end
dummyText(player)

	


end

return talk
LocalScript:
local talkmodule = require(script.Parent.TalkModule)
local npcs = game.Workspace.NPCs
local Dummy = npcs.Dummy
local player = game.Players.LocalPlayer
local dbounce = false

Dummy.Click.ClickDetector.MouseClick:Connect(function()
	if dbounce == false then
		dbounce = true
		talkmodule.talkfunction(player)

		dbounce = false
	end
end)

If anyone could tell me how to improve my code too, that would be a huge help!

I honestly think my “Other idea” would work much better, but I have no idea what to do, so yeah. Any help with that would be great!

My other idea

I’ve been thinking about a system where there’s a variable like “pageamount”, and the talk page code runs once for each page, but I don’t know how to do that. I would appreciate help on that too!

Edit: I’ve decided to go with the other idea.

Thanks!

3 Likes

I can help on your other idea. Im working on it right now

2 Likes

https://i.gyazo.com/a64cdf069e4cc65e242a28bc9dc87390.mp4
Alright done.
heres how i did it
I had to add some spice (A viewport frame and some tweening)
My localscript

local Dummy = game.Workspace.Dummy
local gui = game.Players.LocalPlayer.PlayerGui
gui:WaitForChild("ScreenGui").Frame.Position = UDim2.new(0.5,0,1.2,0)
local Dialogue = {
	"I can say as much as i want now!";
	"Funy";
	"Look at me saying stuffs";
	"Literal Legend";
	"Bruh Moment";
	"Alright Final One"
}
local SpeakModule = require(game.ReplicatedStorage.ModuleScript)

Dummy.Head.Speak.Triggered:Connect(function()
	Dummy.Head.Speak.Enabled = false
	SpeakModule:InitTalk(Dummy, Dialogue, gui.ScreenGui.Frame)
	Dummy.Head.Speak.Enabled = true
end)

modulescript

local talkModule = {}

function talkModule:InitTalk(Adornee, Dialogue, GuiObject)
	GuiObject.DialogueBox.Text = ""
	local StopTypewrite = false--For all those children who spam click through dialogues
	
	local TweenSpeed = 0.2--Here, If you dont want spicy stuff remove this
	GuiObject.Position = UDim2.new(0.5,0,1.2,0)
	for i,v in pairs(GuiObject.ViewportFrame:GetChildren()) do
		v:Destroy()
	end
	local VPAvatar = Adornee:Clone()
	VPAvatar.HumanoidRootPart.Anchored = false
	VPAvatar.Parent = GuiObject.ViewportFrame
	VPAvatar.HumanoidRootPart.CFrame = CFrame.new(0,0,0)
	local VPCam = Instance.new("Camera", GuiObject.ViewportFrame)
	VPCam.CFrame = VPAvatar.Head.CFrame + Vector3.new(0, 0, -2)
	VPCam.CFrame = CFrame.new(VPCam.CFrame.Position, VPAvatar.Head.CFrame.Position)
	GuiObject.ViewportFrame.CurrentCamera = VPCam
	GuiObject:TweenPosition(UDim2.new(0.5,0,0.98,0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, TweenSpeed)
	wait(TweenSpeed)--To Here is spicy code, remove it if you dont want spicyness
	
	
	local function typewrite(object, text)
		for i = 1,#text,1 do
			if not StopTypewrite then --Stopping is false
				object.Text = string.sub(text,1,i)
				wait(0.001) --Not every frame, cant even read that stuff
				--Especially if some rat unlocks their fps to 1000
			else
				object.Text = text
				StopTypewrite = false
				break
			end
		end
	end
	
	
	local function DummyText()
		local Finished = false
		local RepeatIndex = 1
		typewrite(GuiObject.DialogueBox, Dialogue[RepeatIndex])
		local Event
		local debounce = false-- no spammy bois skipping dialogue here
		Event = GuiObject.NextButton.MouseButton1Click:Connect(function()
			if debounce then StopTypewrite = true return end
			RepeatIndex = RepeatIndex + 1
			if Dialogue[RepeatIndex] then
				debounce = true
				typewrite(GuiObject.DialogueBox, Dialogue[RepeatIndex])
				debounce = false
			else
				Finished = true
			end
		end)
		repeat
			wait(0.05)
		until Finished == true
		Event:Disconnect()
		GuiObject:TweenPosition(UDim2.new(0.5,0,1.2,0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, TweenSpeed)--Also spicy code
	end
	
	DummyText()
end

return talkModule
2 Likes

Could you maybe help with my script? I’m not sure how to implement it. (WOW YOU DID IT FAST)

Some of the things like the Tween etc. aren’t really my level yet.

If you can’t, it’s okay.

Alright i revised it and explained my code

This is my example now

localScript

local Dummy = game.Workspace.Dummy --Set this to your NPC
local gui = game.Players.LocalPlayer.PlayerGui--This is just the playerGui
gui:WaitForChild("ScreenGui", 10).Frame.Position = UDim2.new(0.5,0,1.2,0)--This is for position of tweening
--Set the UDim2 Position just off the screen in the direction you want it to tween
local Dialogue = {
	"I can say as much as i want now!";
	"Funy";
	"Look at me saying stuffs";
	"Literal Legend";
	"Bruh Moment";
	"Alright Final One";
	--If i wanted another one here I would type "Jk its not";
} --The dialogue is a list
local SpeakModule = require(game.ReplicatedStorage.ModuleScript)--Getting the module

Dummy.Head.Speak.Triggered:Connect(function()--Im using a ProximityPrompt in the dummy's head
	Dummy.Head.Speak.Enabled = false--setting it so the prompt is not enables
	SpeakModule:InitTalk(Dummy, Dialogue, gui.ScreenGui.Frame)--Initiates talking
	Dummy.Head.Speak.Enabled = true--setting it so the prompt is enabled after
end)

modulescript

local talkModule = {}
local CAS = game:GetService("ContextActionService")--Is used for pressing e to next

function talkModule:InitTalk(Adornee, Dialogue, GuiObject)
	--This module was designed for multiple dialogues.
	--So you can have different people saying different stuff
	
	local VPFrame = GuiObject.ViewportFrame--Set this to your VPFrame
	local DialogueBox = GuiObject.DialogueBox--Set this to your dialogue box
	local NextButton = GuiObject.NextButton--Set this to your nextButton
	local OutOfScreenPosition = UDim2.new(0.5,0,1.2,0)--Set this to your out of screen position
	local InScreenPosition = UDim2.new(0.5, 0, 0.98, 0)--Set this to your current ScreenPosition
	local CameraOffset = Vector3.new(0,0,-2)--Set this to your Vector3 CameraOffset of the head
	local TypewriteWaitTime = 0.001--Set this to how fast your Typewrites wait time is
	
	DialogueBox.Text = ""--Clearing the current text
	local StopTypewrite = false--A bool value we test for to show the rest of the dialogue
	
	local TweenSpeed = 0.2--Here is the tween speed or how fast you want your gui to go
	GuiObject.Position = OutOfScreenPosition--Setting the position to the out of screen thing again
	for i,v in pairs(VPFrame:GetChildren()) do
		v:Destroy()--Destroying everything in the VPFrame
	end
	local VPAvatar = Adornee:Clone()--Clones the Dummy
	VPAvatar.Parent = VPFrame--Sets dummy's parent to VPFrame
	
	--Viewport frames have a currentCamera and then renders any of its children
	--Its how Arsenal makes its character thingy
	
	VPAvatar.HumanoidRootPart.CFrame = CFrame.new(0,0,0)
	--Setting HRP to 0,0,0 so the camera will position correctly
	local VPCam = Instance.new("Camera", VPFrame)--Create Camera
	VPCam.CFrame = VPAvatar.Head.CFrame + CameraOffset--Offseting Camera
	VPCam.CFrame = CFrame.new(VPCam.CFrame.Position, VPAvatar.Head.CFrame.Position)
	--Pointing Camera towards head
	GuiObject.ViewportFrame.CurrentCamera = VPCam--Setting CurrentCamera of the VPFrame to the camera
	GuiObject:TweenPosition(InScreenPosition, Enum.EasingDirection.Out, Enum.EasingStyle.Linear, TweenSpeed)
	--The Line Above is Tweening the Gui Position
	--Enum.EasingDirection is only used if you dont use Linear
	--Enum.EasingStyle is the style of the tween, Look into different styles and easingDirections
	--TweenSpeed is how fast it will tween
	wait(TweenSpeed)--Wait for it to finish tweening
	
	
	local function typewrite(object, text)
		
		--The typewrite function is same except for the stop typewrite code
		for i = 1,#text,1 do
			if not StopTypewrite then --Stopping is false
				object.Text = string.sub(text,1,i)
				wait(TypewriteWaitTime) --Not every frame, cant even read that stuff
				--Especially if some rat unlocks their fps to 1000
			else
				--Stops the typing and breaks the loop
				object.Text = text
				StopTypewrite = false
				break
			end
		end
	end
	
	
	local function DummyText()
		local Finished = false
		--Debounce
		local RepeatIndex = 0
		local Event
		local debounce = false-- Is the typewriter still running?
		local function InitTypewrite(actionName, inputState)
			if actionName then
				if inputState ~= Enum.UserInputState.End then
					--inputState needs to be end
					return
				end
				if actionName ~= "Typewrite" then
					return
				end
			end
			if debounce then StopTypewrite = true return end --Is typewriter still running?
			--if so then set StopTypewrite to true
			RepeatIndex = RepeatIndex + 1--Add one to the RepeatIndex
			if Dialogue[RepeatIndex] then--Is there another one after this?
				--Initiate Typewrite
				debounce = true
				typewrite(DialogueBox, Dialogue[RepeatIndex])
				debounce = false
			else
				--Set Finished to true
				Finished = true
			end
		end
		InitTypewrite()--Say the first thing
		Event = NextButton.MouseButton1Click:Connect(function()
			InitTypewrite()
		end)
		CAS:BindAction("Typewrite", InitTypewrite, false, Enum.KeyCode.E, Enum.KeyCode.ButtonL1)
		--Binding Action To buttonPress
		
		
		repeat--Waits until finished is true
			wait(0.05)
		until Finished == true
		Event:Disconnect()
		--Disconnects the NextEvent
		GuiObject:TweenPosition(OutOfScreenPosition, Enum.EasingDirection.Out, Enum.EasingStyle.Linear, TweenSpeed)
		--Tweens the GUI back down
	end
	
	DummyText()
	--Initiates DummyText
end

return talkModule

Thats my general idea

1 Like

I have a lot of questions, sorry.

If I didn’t use this, and used my own thing, that would be fine, right?

I’m not using a ViewportFrame for mine.

What is RepeatIndex for yours? Not really sure how to edit it, as mine is click to talk, without a ViewportFrame.

The E button makes it a bit harder, could you explain what BindAction is?

It’s a bit confusing for me, as I just started scripting last month :sweat_smile:

Alright First question, Yes it will, Remove any line with a variable that has VP before it

Second question, RepeatIndex is the line i am on currently, every time I click it adds one to the RepeatIndex and tests if there is a line for that RepeatIndex, when you do

for i,v in ipairs(thingy)

end

i stands for Index and v stands for value, I did that but with a lot more control

Third question ContextActionService is a roblox service like UserInputService, I use it mostly for inputs, The way it works is you bind an action (or multiple actions) to a function and give it a string Identifier, I have it so you can click next, but what I was using CAS for is if someone wanted to press E aswell or space or something. If you dont want that remove the CAS BindAction line and remove the parameters ActionName and InputState from InitTypewrite and

if actionName then
	if inputState ~= Enum.UserInputState.End then
		--inputState needs to be end
		return
	end
		if actionName ~= "Typewrite" then
		return
	end
end

that line of code

1 Like

Could you help me out on implementing the dialogue line thing on my code? I’m kind of confused still and it would be helpful if things were pointed out in my code.

Code

LocalScript:

local talkmodule = require(script.Parent.TalkModule)
local npcs = game.Workspace.NPCs
local Dummy = npcs.Dummy
local player = game.Players.LocalPlayer
local dbounce = false

Dummy.Click.ClickDetector.MouseClick:Connect(function()
	if dbounce == false then
		dbounce = true
		talkmodule.talkfunction(player)

		dbounce = false
	end
end)

ModuleScript:

local talk = {}
script.Parent.Enabled = false
talk.talkfunction = function(player)
--	local dbounce = false
	script.Parent.Enabled = false
--	print(script.Parent.Enabled)
	local textlabel1 = script.Parent:WaitForChild("Main"):WaitForChild("Text1")
	local textlabel2 = script.Parent:WaitForChild("Main"):WaitForChild("Text2")
	--local lines = require:(game.StarterPlayer.StarterCharacterScripts:WaitForChild(Lines)
	local npcs = game.Workspace.NPCs
	local Dummy = npcs.Dummy
	local page = 1
	local proceed = script.Parent:WaitForChild("Main"):WaitForChild("Proceed")
	local pagedone = false
	local lastpage = false
	local ispage2 = true
	local ispage3 = true
	local ispage4 = false
	local pageamount = 3
	local pagesdone = 0
	local txt1 = "text test so i can copy this"
	local txt2 = "text test so i can copy this"
	local txt3 = "text test so i can copy this"
	local txt4 = "text test so i can copy this"
	local txt5 = "text test so i can copy this"
	local txt6 = "text test so i can copy this"
	local txt7 = "text test so i can copy this"
	local txt8 = "text test so i can copy this"


	local function typewrite(object,text)
		for i = 1,#text,1 do
			object.Text = string.sub(text,1,i)
			game:GetService("RunService").Stepped:Wait(0.001)
		end
	end

	local function dummyText(player)
		local dialoguefinished = false
		if script.Parent.Enabled == false then --if script.Parent.Enabled and dbounce == false then
		--	dbounce = true
			--warn("Began")
			local char = player.Character
			local hum = char.Humanoid
			hum.JumpPower = 0
			hum.WalkSpeed = 0
			hum.AutoRotate = false
			page = 1
			pagedone = false
			lastpage = false
			script.Parent.Enabled = true
			--		dialoguefinished = false
			--while pagesdone < pageamount do 
			typewrite(textlabel1,txt1)
			typewrite(textlabel2,txt2)
			pagedone = true
			local proceedevent
			proceedevent = proceed.MouseButton1Click:Connect(function()
				if lastpage and pagedone then
					script.Parent.Enabled = false
					textlabel1.Text = ""
					textlabel2.Text = ""
					hum.JumpPower = 50
					hum.WalkSpeed = 16
					hum.AutoRotate = true
					page = 1
					pagedone = false
					lastpage = false
					dialoguefinished = true
					proceedevent:Disconnect()
				--	dbounce = false
				elseif page ==1 and pagedone and ispage2 then
					textlabel1.Text = ""
					textlabel2.Text = ""
					page = 2
					pagedone = false
					lastpage = false
					typewrite(textlabel1, txt3)
					typewrite(textlabel2, txt4)
					pagedone = true
					pagedone = true
				elseif page == 2 and pagedone and ispage3 then
					textlabel1.Text = ""
					textlabel2.Text = ""
					pagedone = false
					page = 3

					typewrite(textlabel1, txt5)
					typewrite(textlabel2, txt6)
					pagedone = true
					--page = 1
				--	lastpage = true
				elseif page == 3 and pagedone and ispage4 then
					textlabel1.Text = ""
					textlabel2.Text = ""
					pagedone = false
					page = 4

					typewrite(textlabel1, txt7)
					typewrite(textlabel2, txt8)
					pagedone = true
					page = 1
					lastpage = true
				elseif page == 3 and pagedone and not ispage4 then
					lastpage = true
					page = 1
					pagedone = true
					textlabel1.Text = ""
					textlabel2.Text = ""
				elseif page == 2 and pagedone and not ispage3 then
					lastpage = true
					page = 1
					pagedone = true
					textlabel1.Text = ""
					textlabel2.Text = ""
				elseif page == 1 and pagedone and not ispage2 then
					lastpage = true
					page = 1
					pagedone = true
					textlabel1.Text = ""
					textlabel2.Text = ""
				end
			end)
			repeat
				wait(0.05)
			until dialoguefinished == true
		else

		end

	end
dummyText(player)

	


end

return talk

Because yours uses E, and all those tweens, I’m not sure how it works.

If you have more time for more questions

How does that work?

What are those arguments?

Sorry if I’m taking a lot of time out of your day. If you’re busy, you don’t have to help.

Im not busy, The typewrite function is your typewrite function with your parameters, The Dialogue[RepeatIndex] is what I use to find the line that i need to speak.

{
	[1] = "I can say as much as i want now!";
	[2] = "Funy";
	[3] = "Look at me saying stuffs";
	[4] = "Literal Legend";
	[5] = "Bruh Moment";
	[6] = "Alright Final One";
	--If i wanted another one here I would type "Jk its not";
} --The dialogue is a list

Lists basically look like that so if i do Dialogue[4] then it would start typewriting “Literal Legend”

What this does is it adds one to the repeat index so when i do Dialogue[RepeatIndex]
it would basically be getting the dialogue according to the repeatIndex number.

And the Arguments in InitTypewrite are dealing with CAS. Whenever you press a binded key, the parameters it will put in the function that its binded to is

  1. The Action Name, what you binded the function to, since i binded it like this
CAS:BindAction("Typewrite", InitTypewrite, false, Enum.KeyCode.E, Enum.KeyCode.ButtonL1)

the Action Name is “Typewrite”, So when I InitTypewrite I check if there is an action name, showing that the function wasn’t from the mousebuttonclick on the next button

  1. Then there is the UserInputState, I didn’t want it firing once when you began your input and once when you ended your input so I tested if it was the ending before firing the function

  2. Finally there is the InputObject, I didnt need it in this case, but it would have some properties, like showing you what the KeyCode you pressed in order to get the function to fire.

Something else I would also like to note are the parameters for the BindAction function

  1. The Action Name you want your Contextual Action to be binded to, typewrite in this instance

  2. The function you want your Contextual Action to activate, Don’t put parenthesis after the function as it overrides the parameters BindAction will give (the three I talked about earlier)

  3. This Parameter is a Bool Value if you want a button to be created for mobile devices (which in this case we do not)

  4. Lastly is a float of all the KeyCodes that should activate your function, like

E key on keyboard = Enum.KeyCode.E
Left Trigger on Controller = Enum.KeyCode.ButtonL1

Now im going to explain why you should use ContextActionService, When you use a script like this

local UIS = game:GetService("UserInputService")

UIS.InputBegan:Connect(function(InputObject)
	If InputObject.KeyCode == Enum.KeyCode.E or InputObject.KeyCode == Enum.KeyCode.ButtonL1 then
		InitTypewrite()
	end
end)

your script will not only pick up the times you press E when your in game. It will also pick up the times you press E in lets say the chat bar. Whenever you press E, that WILL fire. In your menus, in the chat, anytime your focused on the roblox client and press E, it will fire. That is bad because if you wanted to chat something you would be constantly opening and closing menus and pressing buttons and such, But if you use a script like this

local CAS = game:GetService("ContextActionService")

local function OnCasInput(ActionName, ActionState, ActionObject)
	if ActionState ~= Enum.UserInputState.End then return end
	if ActionName == "ToggleMenu" then
		--Open Your Menu
	elseif ActionName == "ShootGun" then
		--Shoot Gun
	elseif ActionName == "Typewrite" then
		--TypewriteCode
	end
end

CAS:BindAction("ToggleMenu", OnCasInput, false, Enum.KeyCode.Tab)
CAS:BindAction("ShootGun", OnCasInput, false, Enum.UserInputType.MouseButton1)
CAS:BindAction("Typewrite", OnCasInput, false, Enum.KeyCode.E)

Now none of those things would happen if you were in chat or something. Contextual Actions are like layers, the top one with the most priority takes effect, and stuff like chat takes priority over everything. If you wanted to temporarily disable someones controls, bind a contextual action that does nothing until you can unbind that action.

Sorry this was such a long reply, I tried to explain some of the things that I used

1 Like

Thank you! Now I get how those work. However, my NPC thing isn’t using that, so it won’t really work. Could you help me with making my script have like a dialogue list thing, so that there is always enough pages of text? Thanks!

Alright, Basically what makes mine different from yours is I have a list of dialogue I can pass into the function, when i click it goes down the list, I added the other things like CAS and tweening and VPFrame because I wanted to sorta show you how those work.

1 Like

How would I pass the list into the ModuleScript?

As a parameter, like

local List = {
"Im In List!";
}
local Module = require(ModulePath)

Module:PassList(List)
local Module = {}

function Module:PassList(List)
	print(List)
end

return Module
1 Like

Could you explain which part of your code goes through each line of the list?

InitTypewrite does, It adds one to the RepeatIndex and tests if there is one, if so it typewriters it

1 Like

What does the actionName and inputState do?

That was part of using ContextActionService

1 Like

So I wouldn’t need it, if I was doing click to activate, right?

exactly sir… If you were using click to activate, those would be pointless

1 Like

Excuse me for being late on this.
Perhaps I am missing something since it’s a “relatively” large size script.
But the reason you are seeing an empty page 4 is because there is nothing stopping the page from appearing.
The difference in your code between when ispage4 is true or false is that when it’s true the empty text gets overwritten by actual text. But there is nothing preventing it from showing!
I think if you change ispage2 and ispage3 to false you should have the exact same problem with those pages.

In your first if statement within “MouseButton1Click:Connect(function()” you have these lines:

script.Parent.Enabled = false
--other stuff
dialoguefinished = true
proceedevent:Disconnect()

I think it should work if you put those into this part:

elseif page == 3 and pagedone and not ispage4 then
					lastpage = true
					page = 1
					pagedone = true
					textlabel1.Text = ""
					textlabel2.Text = ""

So it would look like:

elseif page == 3 and pagedone and not ispage4 then
					lastpage = true
					page = 1
					pagedone = true
					textlabel1.Text = ""
					textlabel2.Text = ""
                    script.Parent.Enabled = false
                    dialoguefinished = true
                    proceedevent:Disconnect()

Edit: You will probably have to do the same for the parts with “and not ispage2” and “and not ispage3”.
Please let me know if this helped! Good luck either way.

1 Like