How do you properly teleport a player out of a seat?

I have been battling with this issue for a while - is hard to solve since it is hard to reproduce and since Seats are kind of odd fellows. Seats got teleported for players in production, but not when developing in Studio (or team test).

Tried to listen to different property changes that the player is no longer seated, arbitrary waits, run unseat on the client before server teleported the player, unseat the player on the server etc without any results.

The solution I settled on was the dirty hack of teleporting the seat back to the original position if it got teleported with the player:

local humanoid = player.Character:FindFirstChild("Humanoid")
if humanoid then
	if humanoid.SeatPart then
		-- Delay a restore original seat position...
		local seatPart = humanoid.SeatPart
		local originalSeatCFrame = seatPart.CFrame
		
		delay(4, function()
			seatPart.CFrame = originalSeatCFrame
		end)
		
		-- Do a futile attempt to unseat the player
		humanoid.SeatPart:Sit(nil)
		humanoid.Sit = false
		humanoid:GetPropertyChangedSignal("SeatPart"):Wait()
	end
end

player.Character.HumanoidRootPart.CFrame = targetPosition

Might not fall under “properly”, but was the solution I ended up with. There might be some better solution where the server syncs with the client so both agree on the player being unseated using remote events, but I have spent enough time on this as it is.

6 Likes

I ran into this problem earlier today when attempting to teleport players out of seats. I couldn’t find a reliable way to ensure seats didn’t get teleported with the player.

Thanks to Sam’s solution above, I can get around the problem. However it’s disappointing I couldn’t find a normal way to guarantee that the seat doesn’t get teleported too. Shouldn’t there be a better way to solve this problem?

1 Like

One way to do can be just by disabling the seat for a while and then teleporting the player

local Char = Player.Character
local Hum  = Char.Humanoid
local Seat = Hum.SeatPart --Locating the Seat

Seat.Disable = true --Disables the Seat
Hum.Sit = false --Making it Stand

Char:SetPrimaryPartCFrame(game.Workspace.Part.Postion) --Since Character is a Model and has a Humanoid it will work good

Seat.Disable = false -- If you want to \_(O.O)_/
4 Likes

Hi, when a player sit on a seat roblox create a weld in the seat. You can destroy this weld before teleport player.

To detecte the seat used by the player you can use humanoid.SeatPart Humanoid | Documentation - Roblox Creator Hub

By destroy the weld you are sure that the seat will not move.

While your code is mostly correct, there needs to be a small wait time or else it will try to teleport the player too fast. I’ve corrected this in the code below:

        seat.Disabled = true -- Will make the player unable to sit in the seat so they don't accidentally sit back in it before teleporting
		Humanoid.Sit = false -- This will make the player stand up from the seat

		repeat wait() -- this will wait until the player is no longer sitting
		until Humanoid.Sit == false 

		wait(.1) -- I haven't tested this code without this wait, but I like having precautions

		Character.HumanoidRootPart.CFrame = CFrame.new(workspace.part.position) -- This is the teleport code

		seat.Disabled = false -- Allows the seat to be used again
6 Likes

You can make the player jump using char.Humanoid.Jump = true. Then move the character using :MoveTo

2 Likes
for _,v in pairs(workspace:GetDescendants()) do
	if v:IsA("Seat") then
		local originalpos = v.CFrame
		v:GetPropertyChangedSignal("Occupant"):Connect(function()
			if v.Occupant == nil then
				v.CFrame = originalpos
			else
				wait()
				local Occupant = v.Occupant.Parent
				local HRP = Occupant.HumanoidRootPart
				local OccOrigPos = HRP.Position
				while wait(.1) do
					local OccCurrentPos = HRP.Position
					if (OccCurrentPos - OccOrigPos).magnitude > 10 then
						if v:FindFirstChild("SeatWeld") then
							v.SeatWeld:Destroy()
						end
					end
				end
			end
		end)
	end
end

If you want to be indiscriminate, this doubly protects by retaining the original position of the seat and unseating the player when they teleport. Can be placed in any server script.

In 2024, I’m successfully teleporting characters by simply cloning and destroying the seat part:

local humanoid = player.Character.Humanoid

local seat = humanoid.SeatPart
if seat then
    humanoid.Sit = false
    local seatParent = seat.Parent
    local seatCopy = seat:Clone()

    task.defer(function()
        RunService.Heartbeat:Wait()
        pcall(seat.Destroy, seat)
        seatCopy.Parent = seatParent
    end)
end

player.Character:PivotTo(newLocation)
1 Like