Best method to create a moving object that players can stand on?

In a game I’m working, there is a train car that moves around on a track and the player can jump on top of it.

The problem here is the way I traditionally move a part is by modifying the part’s CFrame or position in a loop, separated by wait().

This creates a pretty consistent, easy to plot movement, however the part moves with no respect for the player’s character. If you jump on top of my moving train car, you won’t move with it like real physics would dictate.

What would be the best way to get this working?
I am aware of a method that welds the character to the part, but this seems kind of hacky and if there is a cleaner solution I’d rather use that.

I am also aware of different physics objects like body movers, however in my experience these do not provide a consistent speed, you are very much at the mercy of their limitations and it doesn’t let you do a whole lot.

Any guidance on this topic would be appreciated. Thanks!


The best way to my knowledge is using something like

local weld ="WeldConstraint")



similar to what I posted here: How can I Make Two Parts Weld On Touch?

I know you said you don’t want to weld, but it’s one of the best and simplest methods.

1 Like

I have tried implementing your method, and it leads to a weird result.

When I jump on the moving train car with my character, they do not stay stuck to the train car, just like before.

However, something odd happens when the train car moves away and the character would normally fall to their death. Instead, they go into their falling animation but just stay stuck floating there.

Any experience with this happening?

1 Like

Just do your usual cframe on part with tweenservice or renderstepped both on client then you can “attach” the character using a raycast and set the position reative to ontop of the part the player is on.

Heres the jist:


Works great! I needed to make a few modifications to get it running so I’ll just post that here for others to use. Throw this in a local script in StarterPlayerScripts and it should be good to go!

--Written by Kord_K. Slight modifications by BADGRAPHIX.

    local Players = game:GetService("Players")
    local player = game.Players.LocalPlayer
    local RunService = game:GetService('RunService')

    local LastTrainCFrame

    local Function
    local Function2

    Function = RunService.Heartbeat:Connect(function()

    	--------------------------------------------------------------- CHECK PLATFORM BELOW
    	if player.Character then
    		local RootPart = player.Character:FindFirstChild("LowerTorso")
    		if RootPart then
    			local Ignore = player.Character
    			local ray =,,-50,0))
    			local Hit, Position, Normal, Material = workspace:FindPartOnRay(ray,Ignore)
    			if Hit and Hit.Name == "TrainCarC" then -- Change "RaftTop" to whatever the moving part's name is
    				--------------------------------------------------------------- MOVE PLAYER TO NEW POSITON FROM OLD POSITION
    				local Train = Hit
    				if LastTrainCFrame == nil then -- If no LastTrainCFrame exists, make one!
    					LastTrainCFrame = Train.CFrame -- This is updated later.
    				local TrainCF = Train.CFrame 
    				local Rel = TrainCF * LastTrainCFrame:inverse()
    				LastTrainCFrame = Train.CFrame -- Updated here.
    				RootPart.CFrame = Rel * RootPart.CFrame -- Set the player's CFrame
    				LastTrainCFrame = nil -- Clear the value when the player gets off.
    			Function2 = player.Character.Humanoid.Died:Connect(function()
    				Function:Disconnect() -- Stop memory leaks
    				Function2:Disconnect() -- Stop memory leaks

You could also do the exact opposite and make the surroundings move instead of the train to give the illusion

That wouldn’t work with terrain, which is heavily used, and would cause severe lag moving the entire map.