When players spawn, the spawn location is in a game area wich triggers this script that teleports them to the next game area:
local gameArea = script.Parent
local teleportPart = workspace.LiveOrDie.Areas.teleport
local Players = game:GetService("Players")
-- Track which players are already being teleported
local debounced = {}
local function teleportPlayer(player)
if not player.Character then return end
local hrp = player.Character:FindFirstChild("HumanoidRootPart")
if not hrp then return end
-- Get teleportPart size and position
local size = teleportPart.Size
local cf = teleportPart.CFrame
-- Pick a random offset within the X/Z bounds
local randX = (math.random() - 0.5) * size.X * 0.8 -- 0.8 to keep them inside
local randZ = (math.random() - 0.5) * size.Z * 0.8
-- Final position, lifted 3 studs
local targetPos = (cf * CFrame.new(randX, size.Y / 2 + 3, randZ)).Position
-- Teleport entire model (safer than just HRP)
player.Character:PivotTo(CFrame.new(targetPos))
end
local function onTouched(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if not player then return end
-- Debounce per player
if debounced[player] then return end
debounced[player] = true
-- Delay once, not multiple times
task.delay(7, function()
if player.Parent then -- still in game
teleportPlayer(player)
end
-- reset debounce so they can trigger again later if needed
debounced[player] = nil
end)
end
if gameArea:IsA("BasePart") then
gameArea.Touched:Connect(onTouched)
else
warn("GameArea is not a BasePart!")
end
The problem: Sometimes when its 3 or more players the teleporting time is slightly different and one person ends up teleporting back and forth a few times and then ending up outside of the next game area
I’m thinking: The problem is that your current debounce is per-player but the Touched event can fire multiple times quickly for the same character.. this may fix that:
local gameArea = script.Parent
local teleportPart = workspace.LiveOrDie.Areas.teleport
local Players = game:GetService("Players")
local debounced = {}
local function teleportPlayer(player)
if not player.Character then return end
local hrp = player.Character:FindFirstChild("HumanoidRootPart")
if not hrp then return end
local size = teleportPart.Size
local cf = teleportPart.CFrame
local randX = (math.random() - 0.5) * size.X * 0.8
local randZ = (math.random() - 0.5) * size.Z * 0.8
local targetPos = (cf * CFrame.new(randX, size.Y / 2 + 3, randZ)).Position
player.Character:PivotTo(CFrame.new(targetPos))
end
local function onTouched(hit)
local character = hit.Parent
local player = Players:GetPlayerFromCharacter(character)
if not player or debounced[character] then return end
debounced[character] = true
task.delay(7, function()
if player.Parent and character.Parent then
teleportPlayer(player)
end
debounced[character] = nil
end)
end
if gameArea:IsA("BasePart") then
gameArea.Touched:Connect(onTouched)
end
Try using .TouchEnded instead of wating 7 seconds ( task.delay(7,function() )
When you’re using if player.Parent then... you are referencing the Players service
SMALL SNIPPET
local function onTouchEnded(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if player then
task.wait(0.2) -- small delay to avoid player being unmarke too fast
debounced[player] = nil
end
end
Hopefully this helps you. If you have any console error please send it over.
Touchend is a headache all on it’s own.. avoid that at all costs.
@ Nova
local debounced = {}
This Is just a server script way of doing a mass debounce. That was just tossed together sticking to your logic, even if it’s a bit off, it is still a great way to handle that.
Be clear on your point if you say something like this, TouchEnded and Touched are both valid and useful events for simple stuff like teleport on touch.
TouchEnded and Touched have no differences in accuracy, geometry calculation or anything like that, they differ only in states, where one is Ended and one is Began. You’ve got nothing to say
Can you answer the thing i asked earlier today? Is it possible to do so that the players teleport at more similar times? its a very big gap the more players there are who join the game
Yes, I’m working on a different question atm, but that is next.
That 7 second thing per player may have held it up. Maybe this will be a better fit for you.
version 2
local gameArea = script.Parent
local teleportPart = workspace.LiveOrDie.Areas.teleport
local Players = game:GetService("Players")
local waiting = {}
local TELEPORT_DELAY = 7
local timerRunning = false
local function teleportPlayer(player)
if not player.Character then return end
local hrp = player.Character:FindFirstChild("HumanoidRootPart")
if not hrp then return end
local size = teleportPart.Size
local cf = teleportPart.CFrame
local randX = (math.random() - 0.5) * size.X * 0.8
local randZ = (math.random() - 0.5) * size.Z * 0.8
local targetPos = (cf * CFrame.new(randX, size.Y / 2 + 3, randZ)).Position
player.Character:PivotTo(CFrame.new(targetPos))
end
local function startTeleportTimer()
if timerRunning then return end
timerRunning = true
task.wait(TELEPORT_DELAY)
for player in pairs(waiting) do
if player.Parent then
teleportPlayer(player)
end
end
waiting = {}
timerRunning = false
end
local function onTouched(hit)
local character = hit.Parent
local player = Players:GetPlayerFromCharacter(character)
if not player or waiting[player] then return end
waiting[player] = true
startTeleportTimer()
end
if gameArea:IsA("BasePart") then
gameArea.Touched:Connect(onTouched)
end
TouchEnded is not very reliable, as in Roblox every time you stop on the trigger it resets. If you don’t account for that, which is pretty much impossible without a lot more scripting, it’s inconsistent. This can be done much more easily and reliably with zones and/or Region3 checks. This is indeed a more stable and manageable approach for detecting when something is inside an area. What part of that is misinformation? Take a break, Batman.
I’m right, please stop.. this isn’t your post and you’re so far off subject it’s getting stupid. Nova is asking a question marked URGENT. How about you try to help out a bit here.. You seem to have problems with the bigger picture and think you’re here to prove some point no one cares about. I’m going to set you to Block* now.. So nothing you say to me from here will ever matter.. Good luck here on the forums.
This is exactly what people say when they lose an argument, I don’t care if it’s not my post, I will not let you spread lies about Roblox Events to Roblox Developers.
Sure, when I win, suddenly no one cares, maybe you don’t, after all you were the one not knowing the better practice, so I’d understand if YOU don’t care.