local StoryStage = "Tutorial"
local Substage = 1
local Touchactivaters = game.Workspace:WaitForChild("Touchactivaters")
local SubtitleEvent = game.ReplicatedStorage.RemoteEvents:WaitForChild("Subtitles")
-- Dialogue and touch trigger mapping
local Dialogues = {
Tutorial = {
[1] = {
PartName = "Tutorial1",
Speaker = "Robot",
Text = "hello? Over here! I can help you!",
Color = Color3.new(1, 0.917647, 0)
},
[2] = {
PartName = "Tutorial2",
Speaker = "Robot",
Text = "hello?",
Color = Color3.new(1, 0.917647, 0)
},
-- You can easily add more substages here:
-- [2] = { PartName = "AnotherPart", Speaker = "Robot", Text = "Next step!", Color = Color3.fromRGB(255, 255, 255) }
}
}
local function onTouch(hit)
print("Something was touched:", hit.Name) -- Debugging print
local character = hit.Parent
local player = game.Players:GetPlayerFromCharacter(character)
if not player then return end
print("Player detected:", player.Name) -- Debugging print
local currentDialogue = Dialogues[StoryStage] and Dialogues[StoryStage][Substage]
if currentDialogue then
print("Current substage:", Substage, "Expected part:", currentDialogue.PartName)
if hit.Name == currentDialogue.PartName then
SubtitleEvent:FireAllClients(currentDialogue.Speaker, currentDialogue.Text, currentDialogue.Color)
Substage += 1
print("Dialogue triggered! Moving to Substage:", Substage) -- Debugging print
end
end
end
local function connectTouchEvents(folder)
for _, part in pairs(folder:GetChildren()) do
if part:IsA("BasePart") then
part.Touched:Connect(onTouch)
end
end
end
-- Initial setup
connectTouchEvents(Touchactivaters)
-- Connect new parts dynamically
Touchactivaters.ChildAdded:Connect(function(newPart)
if newPart:IsA("BasePart") then
newPart.Touched:Connect(onTouch)
end
end)
it breaks at line 39 and then dosent fire all clients, yes the part name is correct, Tutorial1
So either the problem is that it isn’t finding a player so the code is returning, again I don’t know what line 39 is so I can’t confirm or that getPlayerFromCharacter isn’t working
Ok, after copying it out to see what line 39 is then it looks like it’s just a mismatch of what you’re expecting.
“hit” seems to be expected to be the a part of the Players character while currentDialogue.PartName looks like the name of the part that got touched.
So on like 39 which looks like
if hit.Name == currentDialogue.PartName then
I would never expect hit.name to equalt currentDialogue.PartName.
What are you wanting to accomplish?
So to sum it up, “Tutorial1” is a part inside of the player’s character, and it is making contact with your “touch activator”. Your print statements reach “Current substage…”, of which show substage 1 and the expected part name of “Tutorial1”. The “Something was touched” print shows “Tutorial1” as well? If all this sounds correct, confirm that the part “Tutorial1” does not have a space suffixing its name
Tutorial1 is in the workspace and it’s properly defined in the table, yes, the function is supposed to be like an invisible wall that activates dialoge
That is not what your code is expecting. I believe you mean to check the name of the part the player contacted. Currently, you’re matching a limb of the player’s character. You need to pass forward the hitbox part to the onTouch callback so you can check its name
Yeah, so you’re going to need to pass in the specific part in a context for the touch event to know what the part is.
Something like
local function connectTouchEvents(folder)
for _, part in pairs(folder:GetChildren()) do
if part:IsA("BasePart") then
-- Here is where we are wrapping the current onTouch in order to add the part we are currently setting the touch event for.
part.Touched:Connect(function(hit) onTouch(hit, part) end))
end
end
end
Then update the onTouch function to also take in the dialogue part.
local function onTouch(hit, dialoguePart)
....
end