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

What about changing the HumanoidStateType?

char.Humanoid:ChangeState(Enum.HumanoidStateType.RunningNoPhysics) 
char.HumanoidRootPart.CFrame = workspace.Part.CFrame

by “very rarely”, do you mean that it still does happen?

Yes. I tried this once in a loop with 4 players resulting in 2 players being teleported correctly and 2 together with the seat.

1 Like

This makes the player teleport together with the seat

changing the state of the humanoid seems to have no effect at all when the character is sitting

Darn, I brainstormed a new idea though. How about setting the Seat’s Occupant to nil?

seat.Occupant = nil

If nil doesn’t work, try it with a placeholder Humanoid Instance

1 Like

Using this doesnt work at all.

seat.Occupant = nil

Using the code below works, but I get the same result as method 4. Not knowing how long the wait() has to be. Since wait() is too fast. But wait(0.2) not. So there may be cases where wait(0.2) could not be fast enough

game.Workspace.Seat:Sit(nil)
wait()
char.HumanoidRootPart.CFrame = game.Workspace.Part.CFrame
2 Likes

You can use GetPropertyChangedSignal for exactly when Sit changes:

char.Humanoid:GetPropertyChangedSignal("Sit"):Wait()
2 Likes

This doesn’t seems to work either… same problem as

repeat wait() until char.Humanoid.Sit == false

And for this I would need to use multiple scripts to teleport a player. One for the event and one for making the player stand up.

I’m really surprised that it’s so hard to reliably teleport a player out of a seat

2 Likes
script.Parent:GetPropertyChangedSignal("Occupant"):Connect(function()
	local Humanoid = script.Parent.Occupant
	if not Humanoid then
		return
	end
	connection = Humanoid.StateChanged:Connect(function(prevState, newState)
		if prevState == Enum.HumanoidStateType.Seated then
			Humanoid.Parent.HumanoidRootPart.CFrame = CFrame.new(0, 10, 0)
			connection:Disconnect()
		end
	end)
end)
2 Likes

Has anyone, you know, tried jumping a Humanoid off the seat or destroying the seat weld from the server first? The only way to remove a Humanoid from a seat?

1 Like

I’ve been told that destroying the SeatWeld causes problems, look at my reply here:

1 Like

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.

7 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.

1 Like

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)
5 Likes

Almost 2025, and I quickly made a script, which ik is not the best in terms of efficiency (2 connections per seat)

Which is a normal script, parented to each Seat, with the RunContext set to “Client”
^^ it only counteracts the buggy positioning

local Seat = script.Parent
local CachedPivot = Seat:GetPivot()


Seat.ChildAdded:Connect(function()
	task.defer(function()
		Seat:PivotTo(CachedPivot) -- Reset 
	end)
end)

Seat.ChildRemoved:Connect(function()
	Seat:PivotTo(CachedPivot) -- Reset
end)