Heya, so I made a dialogue system using a tutorial and here’s the thing - I can’t figure out how to integrate callback functions.
MODULE // CODE
local Info = {} local head = script.Parent.Head Info.LeaveMessage = "..'Cya 'round, I guess." Info.LeaveButtonText = "I must go." local Callbacks = { killSomeone = function() print("Starting assassination quest.") end, birthdayWish = function() print("Happy Birthday event triggered!") end, luckyOne = function() print("Who is to die?") end } Info.Dialog = { [1] = { Text = "'Sup, need someone popped?", Choices = { [1] = { Text = "Err.. popped?", Next = 2 }, [2] = { Text = "Happy birthday.", Next = 3, Follow = false, Callback = Callbacks.birthdayWish }, }, }; [2] = { Text = "Popped, killed, terminated, whatever you wanna call it. Whaddya need?", Choices = { [1] = { Text = "Kill someone.", Next = 4 , Follow = false, }, }, }; [3] = { Text = "..These words will have you end up in a grave some unfortunate day.", Choices = {}, }; [4] = { Text = "Great! Now, who's the lucky fella?", Choices = {}, }; } Info.CameraSpeed = 2 Info.CameraCFrame = CFrame.new(Vector3.new(-104.361, 75.317, 133.111), head.Position) return Info The above code is what stores the information (it’s located inside of the NPCs)
CLIENTSIDE HANDLER // CODE
repeat wait() until game:IsLoaded() ------------------------- -- VARIABLES / SERVICES -------------------------- local repStorage = game:GetService("ReplicatedStorage") local players = game:GetService("Players") local tweenService = game:GetService("TweenService") ----------------------- -- VARIABLES / GUI ----------------------- local gui = script.Parent local main = gui.Main local background = main.BG local choiceFrame = main.ChoicesFrame local nameFrame = main.NameFrame local dialogFrame = main.DialogFrame local nameLabel = nameFrame.Label local dialogLabel = dialogFrame.Label local choiceTemplate = script.ChoiceTemplate -------------------------- -- VARIABLES / CONSTANTS -------------------------- local event = repStorage.Events:FindFirstChild("TalkEvent") local camera = workspace.CurrentCamera local plr = players.LocalPlayer local char = plr.Character or plr.CharacterAdded:Wait() local currentNPC = nil local storedChoices = {} -------- -- CODE -------- char:WaitForChild('Humanoid').Died:Connect(function() task.wait(0.5) if currentNPC then currentNPC.HumanoidRootPart.ProximityPrompt.Enabled = true end camera.CameraType = Enum.CameraType.Custom camera.CameraSubject = game.Players.LocalPlayer.Character main:TweenPosition(UDim2.new(0,0,1,0)) task.wait(1) main.Visible = false nameLabel.Text = "" dialogLabel.Text = "" storedChoices = {} currentNPC = nil end) -- // TYPEWRITER EFFECT local function typeWrite(text, label, TypeDelay) label.Text = "" for _, letter in text:split("") do label.Text = label.Text..letter task.wait(TypeDelay) end end -- // END DIALOG local function endDialog(info) for _, button in pairs(choiceFrame:GetChildren()) do if button:IsA("TextButton") then button:Destroy() end end typeWrite(info.LeaveMessage, dialogLabel, 0.05) task.wait(0.5) currentNPC.HumanoidRootPart.TalkPrompt.Enabled = true camera.CameraType = Enum.CameraType.Custom camera.CameraSubject = char main:TweenPosition(UDim2.new(0, 0,1.221, 0)) task.wait(1) main.Visible = false nameLabel.Text = "" dialogLabel.Text = "" storedChoices = {} currentNPC = nil end -- // MOVE TO NEXT DIALOG local function nextDialog(info, lastChoice) for _, button in pairs(choiceFrame:GetChildren()) do if button:IsA("TextButton") then button:Destroy() end end local dialog if lastChoice then if lastChoice.Next then dialog = info.Dialog[lastChoice.Next] if lastChoice.Callback then lastChoice.Callback() end else end else dialog = info.Dialog[1] end if not dialog then return end typeWrite(dialog.Text, dialogLabel, 0.05) if dialog.Choices and (#dialog.Choices > 0 or #storedChoices > 0) then for i, choice in pairs(storedChoices) do local clone = choiceTemplate:Clone() clone.Text = choice.Text clone.Name = choice.Text clone.Parent = choiceFrame clone.MouseButton1Click:Connect(function() storedChoices[i] = nil nextDialog(info, choice) end) end local leaveButton = choiceTemplate:Clone() leaveButton.Text = info.LeaveButtonText leaveButton.Name = "Leave" leaveButton.UIStroke.Color = Color3.fromRGB(136, 0, 0) leaveButton.BackgroundColor3 = Color3.fromRGB(83, 0, 0) leaveButton.TextColor3 = Color3.fromRGB(255, 0, 0) leaveButton.Parent = choiceFrame leaveButton.MouseButton1Click:Connect(function() endDialog(info) end) for i, choice in pairs(dialog.Choices) do local clone = choiceTemplate:Clone() clone.Text = choice.Text clone.Name = choice.Text clone.Parent = choiceFrame if choice.Follow == true then storedChoices[i] = choice end clone.MouseButton1Click:Connect(function() storedChoices[i] = nil if choice.Callback then print("Calling callback for choice:", choice.Text) -- Debugging: Confirm callback exists choice.Callback() -- Call the callback else print("No callback found for choice:", choice.Text) -- Debugging: If no callback, print this print(choice.Next) print(choice.Follow) end nextDialog(info, choice) end) if dialog.DialogCallback then dialog.DialogCallback() end end else task.wait(1) if dialog.Next then nextDialog(info,dialog) else endDialog(info) end end end -- // MAIN CODE event.OnClientEvent:Connect(function(npc, info, useCameraParams) if currentNPC == nil and npc then currentNPC = npc nameLabel.Text = npc.Name -- // Reset dialogue dialogLabel.Text = "" storedChoices = {} -- // Reset choices for _, button in pairs(choiceFrame:GetChildren()) do if button:IsA("TextButton") then button:Destroy() end end end npc.HumanoidRootPart.TalkPrompt.Enabled = false main.Visible = true if useCameraParams == true then camera.CameraType = Enum.CameraType.Scriptable local Tinfo = TweenInfo.new(info.CameraSpeed, Enum.EasingStyle.Cubic, Enum.EasingDirection.In, 0, false) local goal = {} goal.CFrame = info.CameraCFrame tweenService:Create(camera, Tinfo, goal):Play() end main.Position = UDim2.new(0, 0,1.221, 0) main:TweenPosition(UDim2.new(0, 0,0.561, 0), Enum.EasingDirection.In, Enum.EasingStyle.Sine, 1, true) task.wait(1) nextDialog(info, nil) end) That is the clientside code. I can’t seem to figure out how to implement the callbacks, as it keeps printing No callback found for choice. It’s been getting on my nerves quite a bit.