Why it happens
1. :MoveTo() on the client doesn’t replicate physics
When you call:
char:MoveTo(workspace.MainGame.BuildStuff.Lobby.SpawnLocation.Position)
from a LocalScript, you’re moving the character only visually on the client, but:
- The server still thinks the character is in its previous position.
- Because
Touched events are server-side physics events, the server’s copy of the character never actually touched the new part.
So:
On your screen you moved, but on the server, your HumanoidRootPart never left the chair.
That’s why .Touched events don’t trigger.
2. Why it happens for “ANY touched logic”
This isn’t specific to your code — any Touched event won’t fire when movement happens client-only, because physics are simulated on the server.
Even if the part is set to CanTouch = true, the event runs where physics happen, i.e., the server.
Solutions
Option 1: Move the character on the server
Make your LocalScript ask the server to teleport the character.
Example:
LocalScript:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local moveEvent = ReplicatedStorage:WaitForChild("MoveEvent")
local button = script.Parent
local frame = script.Parent.Parent.Parent.Parent
local player = game.Players.LocalPlayer
button.MouseButton1Click:Connect(function()
frame.Visible = false
button:FindFirstChild("clickfast.wav"):Play()
moveEvent:FireServer()
end)
ServerScript (in ServerScriptService):
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local moveEvent = Instance.new("RemoteEvent")
moveEvent.Name = "MoveEvent"
moveEvent.Parent = ReplicatedStorage
moveEvent.OnServerEvent:Connect(function(player)
local char = player.Character
if not char then return end
local spawnPos = workspace.MainGame.BuildStuff.Lobby.SpawnLocation.Position
char:MoveTo(spawnPos)
end)
Now the server teleports the character, and the touched events will fire normally.
Option 2: Force server-side sync after MoveTo (less ideal)
If you must move locally (e.g. for fast visual teleports), you can send a small RemoteEvent to tell the server to update the character’s position right after:
-- After char:MoveTo(...)
game.ReplicatedStorage.SyncPosition:FireServer(char.HumanoidRootPart.Position)
Server script:
game.ReplicatedStorage.SyncPosition.OnServerEvent:Connect(function(player, pos)
local char = player.Character
if char then
char:MoveTo(pos)
end
end)
This makes sure the server’s physics state matches what you see.
Option 3: Simulate the touched behavior locally
If your touch logic is purely cosmetic (like lights or UI triggers), you can run it on the client with a simple magnitude check:
local hrp = char:WaitForChild("HumanoidRootPart")
local trigger = workspace.SomePart
if (hrp.Position - trigger.Position).Magnitude < 5 then
-- Run local touched logic
end
But this won’t fire real .Touched events — only visual/sound logic.