I slightly modified your script to work with unanchored objects moved by body movers. I changed the humanoid states to only work if you are falling or jumping, which lets Roblox handle the physical contact, and the script moves you back after you jump. I also adjusted the ray length, so it won’t push you back if you try to hop on from the front.
--BrahGames 07-27-2021 rewritten https://devforum.roblox.com/t/jailbreak-train-platform-system/236339
--slightly edited to work with bodymovers and such /maxx
local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService('RunService')
local CheckStates = true
local LastPartCFrame
local LastPart
local Function
local Function2
function CFrameLogic(Raycast, CFramePart)
--------------------------------------------------------------- MOVE PLAYER TO NEW POSITON FROM OLD POSITION
if Raycast.Instance ~= LastPart then
LastPart = Raycast.Instance
LastPartCFrame = nil
end
local Train = Raycast.Instance
if LastPartCFrame == nil then -- If no LastTrainCFrame exists, make one!
LastPartCFrame = Train.CFrame -- This is updated later.
end
local TrainCF = Train.CFrame
local Rel = TrainCF * LastPartCFrame:inverse()
LastPartCFrame = Train.CFrame -- Updated here.
CFramePart.CFrame = Rel * CFramePart.CFrame -- Set the player's CFrame
--print("set")
end
Function = RunService.Heartbeat:Connect(function()
--------------------------------------------------------------- CHECK PLATFORM BELOW
-- Build a "RaycastParams" object
local MovingObjects = workspace.MovingObjects --Make a folder and put all moving objects into it and call the folder "MovingObjects"
local HumanoidRootPart = player.Character.HumanoidRootPart
local humanoid = player.Character.Humanoid
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
raycastParams.FilterDescendantsInstances = {MovingObjects}
raycastParams.IgnoreWater = true
-- Cast the ray
local Hit = workspace:Raycast(HumanoidRootPart.CFrame.p, Vector3.new(0,-15,0), raycastParams) --Casts a ray facing down
--------------------------------------------------------------------------------------------
if Hit and Hit.Instance:IsDescendantOf(MovingObjects) then -- Check if the ray hits and if it hits an object inside of MovingObjects
if CheckStates then -- check if the character is jumping
local currentState = humanoid:GetState()
if currentState == Enum.HumanoidStateType.Freefall or currentState == Enum.HumanoidStateType.Jumping or currentState == Enum.HumanoidStateType.FallingDown then
CFrameLogic(Hit, HumanoidRootPart)
else
LastPartCFrame = nil -- Clear the value when the player gets off.
end
else
CFrameLogic(Hit, HumanoidRootPart)
end
else
LastPartCFrame = nil -- Clear the value when the player gets off.
end
end)
Function2 = player.Character.Humanoid.Died:Connect(function()
Function:Disconnect() -- Stop memory leaks
Function2:Disconnect() -- Stop memory leaks
end)
It gets buggy when I hop over the other player because the ray is not ignoring him, which turns the script off momentarily.