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!
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.
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.
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 = Ray.new(RootPart.CFrame.p,Vector3.new(0,-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.
end
local TrainCF = Train.CFrame
local Rel = TrainCF * LastTrainCFrame:inverse()
LastTrainCFrame = Train.CFrame -- Updated here.
RootPart.CFrame = Rel * RootPart.CFrame -- Set the player's CFrame
--print("set")
else
LastTrainCFrame = nil -- Clear the value when the player gets off.
end
Function2 = player.Character.Humanoid.Died:Connect(function()
Function:Disconnect() -- Stop memory leaks
Function2:Disconnect() -- Stop memory leaks
end)
end
end
end)