Help with NPC script (again)

Any errors? Your modulescript looks alright but… It does not appear that you have anything in the clickdetector in the localscript

1 Like

What would I put for

I don’t know what arguments to put.

talkmodule.talkfunction(Dialogue)

1 Like

I’m also kind of confused on the second line - would I need it? And if I did, what would I put?

no you would not need the second line.

1 Like

I get an error:
Players.RipPBB_TUD.PlayerGui.NPCTalk.Animator:23: attempt to call a nil value - Client - Animator:23

Line 23:

	talkmodule.talkfunction(Dialogue)

Whole code: (LocalScript)

local player = game.Players.LocalPlayer
local npcs = game.Workspace.NPCs
local Dummy = npcs.Dummy

local Dialogue = {
	"Testing1 Testing1 Testing1",
	"testing2 testing2",
	"Testing3 testing3",
	"Testing4 testing4 Testing4",
	

}
local talkmodule = require(script.Parent.TalkModule)

--[[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)
]]--
Dummy.Click.ClickDetector.MouseClick:Connect(function()
	
	talkmodule.talkfunction(Dialogue)
	--Dialogue:


end)

Is Animator the talkmodule in this case?

1 Like

Not sure what you mean, but here is my StarterGUI hierarchy:
image

use talkmodule:InitTalk(dialogue)

1 Like

Also, how would I get the player’s humanoid? I want to freeze the player when they start talking.

Thank you!

Uhh… I’m having an error for mine. Since I’m not using the E to talk thing, you can click on the person multiple times, how would I make it so you can only talk when it is finished?

@PostVivic
I tried using a talk variable, and if script.Parent.Enabled == false then but the text didn’t show up. I tried using them in various places, but they either broke, or didn’t do anything. Could you help me out, I have no idea what to do in this situation.

Dummy.Click.ClickDetector.MouseClick:Connect(function()
	Dummy.Click.ClickDetector.Enabled = false--Disable click detector
	talkmodule:InitTalk(dialogue)--Initiated Dialogue
	Dummy.Click.ClickDetector.Enabled = true--Enable click detector
end)

Sorry I didn’t see your replies until now

If the module was called by a localscript (in this case it is) you can use

game.Players.LocalPlayer.Character:FindFirstChildWhichIsA("Humanoid")

and reference the Humanoid in the modulescript

1 Like

It unfortunately doesn’t work for me, as ClickDetectors don’t have an “Enabled” property, would there be another way?

Yeah, I just looked at ClickDetectors

Dummy.Click.ClickDetector.MouseClick:Connect(function()
	Dummy.Click.ClickDetector.MaxActivationDistance = 0--Disable click detector
	talkmodule:InitTalk(dialogue)--Initiated Dialogue
	Dummy.Click.ClickDetector.MaxActivationDistance = 35
end)

Setting the MaxActivationDistance would work

Hmm… it still allows the player to click multiple times.

Hmmm, Might I suggest using a Proximity Prompt instead? You can make it so you can actually click it, bad thing though, is that you NEED a keycode for it to work…

Do you know of any possible workarounds though? I really want mine to be click to activate.

Some code that could help:

New Code
LocalScript
script.Parent.Enabled = false
local talking = false
local player = game.Players.LocalPlayer
local npcs = game.Workspace.NPCs
local Dummy = npcs.Dummy
local Test = npcs.Test

local Dialogue = {
	

}
local talkmodule = require(script.Parent.TalkModule)

--[[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)
]]--
Dummy.Click.ClickDetector.MouseClick:Connect(function()

	
	local Dialogue = {
		"LineOfText AnotherLineOfText UselessLineOfText",
		"LineOfText YetAnotherLineOfText UselessLineOfText",
		"AnotherLineOfText AnotherUselessLineOfText",
		"Testing4 testing4 Testing4 testing4 testing4",


	}
	script.Parent.Enabled = true
	Dummy.Click.ClickDetector.MaxActivationDistance = 0
	talkmodule:InitTalk(Dialogue)
	Dummy.Click.ClickDetector.MaxActivationDistance = 6
	--Dialogue:



end)
Module:
local talkModule = {}


function talkModule:InitTalk(Dialogue)
 
--function talkModule:InitTalk(Adornee, Dialogue, GuiObject)
	--This module was designed for multiple dialogues.
	--So you can have different people saying different stuff
	local DialogueBox = script.Parent:WaitForChild("Main"):WaitForChild("Text1")
	--local textlabel2 = script.Parent:WaitForChild("Main"):WaitForChild("Text2")
	local proceed = script.Parent:WaitForChild("Main"):WaitForChild("Proceed")
	--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
	-- helpme aaaa
	DialogueBox.Text = ""--Clearing the current text
	--textlabel2.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()
			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
				script.Parent.Enabled = false

			end
		end
		InitTypewrite()--Say the first thing
		Event = proceed.MouseButton1Click:Connect(function()
			InitTypewrite()
		end)


		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

Old 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 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

Oldest Code
LocalScript:
script.Parent.Enabled = false
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 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)
	if script.Parent.Enabled == false then --
		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
		typewrite(textlabel1,"This is a long long long long long line of random text.")
		typewrite(textlabel2,"This is a test for the 2nd line test test test.")
		pagedone = true
		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
			elseif page ==1 and pagedone then
				textlabel1.Text = ""
				textlabel2.Text = ""
				page = 2
				pagedone = false
				lastpage = false
				typewrite(textlabel1, "This is the 1st line of the 2nd page!")
				typewrite(textlabel2, "This is the 2nd line of the 2nd page!")
				pagedone = true
				pagedone = true
			elseif page == 2 and pagedone then
				textlabel1.Text = ""
				textlabel2.Text = ""
				pagedone = false
				page = 3

				typewrite(textlabel1, "This is the 1st line of the 3rd page!")
				typewrite(textlabel2, "This is the 2nd line of the 3rd page!")
				pagedone = true
				page = 1
				lastpage = true
			end
		end)
	else
		
	end
	
end


Dummy.Click.ClickDetector.MouseClick:Connect(dummyText)


Alright, I guess a Debounce in the connected clickdetector function would work

script.Parent.Enabled = false
local talking = false
local DB = false
local player = game.Players.LocalPlayer
local npcs = game.Workspace.NPCs
local Dummy = npcs.Dummy
local Test = npcs.Test

local Dialogue = {
	

}
local talkmodule = require(script.Parent.TalkModule)

--[[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)
]]--
Dummy.Click.ClickDetector.MouseClick:Connect(function()
	if DB then return end
	DB = true
	
	local Dialogue = {
		"LineOfText AnotherLineOfText UselessLineOfText",
		"LineOfText YetAnotherLineOfText UselessLineOfText",
		"AnotherLineOfText AnotherUselessLineOfText",
		"Testing4 testing4 Testing4 testing4 testing4",


	}
	script.Parent.Enabled = true
	talkmodule:InitTalk(Dialogue)
	--Dialogue:
	DB = false
end)
1 Like

Wow, that worked fast. Thank you for the simple solution!