Characters on Moving Platforms - Now Live As @Crazyman32 it was an update and thats probably how jailbreak did it
If you read that posts replies, you’ll see that the update doesn’t maintain player velocity, it stops players from sliding off moving platforms.
Oh yea I completely forgot about that
They fixed this a long time before the new physics update. This feature was implemented into jailbreak with vehicles pretty soon after it was released.
Jailbreak has a very custom-made train system that was designed to work before Characters On Moving Platforms was released.
I gave badcc some insight on how we do our trains which he used to implement into jb’s new update, if he used exactly what we suggested, it’s actually pretty simple. For anchoring yourself to the train we just multiply the player’s rootpart CFrame to stay with the movement of the train car.
For anchoring other players, it’s a tiny bit harder but still pretty straight forward.
We essentially have a relative cframe from the center of the train car on the server and, after trains are cframed, have your client take that info, loop through other players and if they’re on a train then set their hrp.cframe to trainroot * relativecframe(the one sent from the server)
Hope this helps!
Yep! @tyridge77 tipped me off on the idea of CFraming the Character along with train movement. I didn’t originally want to do this because it’s kind of a fake momentum feel (if train goes around corner and you jump in the air, you’ll turn with it). But it makes everything feel super smooth, so I decided to finally add. Previously I was manually calculating Velocity/RotVelocity for every anchored train part, and the character would move along with it. This broke down a bit on Xbox, something is different there.
Now at start of train update frame I raycast down and check if player is standing on train, perform train update step, and check CFrame of that same part I raycasted earlier in frame. In my code above, that’s LastTrainCF
and TrainCF.
This way no matter what far the update step is, character moves with it. It’s beautiful. We also have some invisible platforms in between the train cars so that the ray hits it when you jump across.
In Tyridge’s fancy train demo he also broadcasts clients relative CFrame to train base part to every other client. I’m not doing this atm. You should show them some videos of yours @tyridge77
Yeah, there is, though as soon as you jump your removed from that platform, causing you to just fall back.
Thank you, very helpful.
What’s the LastTrainCframe? And what’s the need of inverting it? Thank you btw.
I think I understand this, and they can correct me if I’m wrong.
The system can be likened to a loop. Even if it is a connection to a RunService event, it acts like a loop so I will call it one.
Every loop, it moves players by the difference in position of the car between loops. So if the train car moved 14 studs in one loop (as an example), it would move the players inside 14 studs also. The script knows how far the train travelled in one loop by comparing where it was last loop and where it is this loop. So if it was at 45 studs last loop and it’s now at 59, 59-45 = 14 studs of movement. The delta is always calculated by taking the current position and subtracting the previous position.
This gets a little more complicated when 3D is taken into account. Since the cars exist in 6 dimensions (position and rotation), there needs to be a way to know exactly how the position and rotation changed. This is where CFrame comes in. CFrames are special and you can’t add or subtract them directly, but the basics of it is that :inverse() is the way to make a CFrame “negative”, and multiplying is the way CFrames add to each other.
So in a sense, they are taking the current CFrame and subtracting the previous CFrame from it to find the amount of position and rotation that changed during the loop. This change is called Rel. And the last line uses Rel to move the player to the Relative spot it was last loop; relative to the train car.
Now, the specifics of implementation, I don’t know, but I’m pretty sure it happens client-side based on some hints that @badcc was giving. Supposedly, Jailbreak’s implementation relies on network ownership to update the player positions between players which stutters based on connection due to the unusual nature of the movement, and Tyridge’s implementation sends the relative position to all players outright for smoother-looking movement. Also unknown is whether or not the update is occurring in RenderStepped, Heartbeat, or Stepped. All three are usable, as the load of the script is very small so there won’t be any concern about delaying render when using RenderStepped.
Ahh makes sense, thanks for explaining it in further depth, I’ll give it an attempt let you guys know how it turns out, may give it to you guys if you would like it.
you need to set LastTrainCFrame after you calculate Rel. Otherwise you’re calculating the difference between something and itself (which is zero). You also need to break out LastTrainCFrame out of the loop either as an upvalue or as a global. And maybe what you have for finding the humanoid works in Play Solo, but you’ll have to move to Player.CharacterAdded event to get the current humanoid in a live game.
MY CODE
local Players = game:GetService("Players")
local LastTrainCF
local function onCharacterAdded(player)
while true do
wait(0.0001)
--------------------------------------------------------------- CHECK PLATFORM BELLOW
local RootPart = player.HumanoidRootPart
local Ignore = player
local ray = Ray.new(RootPart.CFrame.p,Vector3.new(0,-50,0))
local Hit, Position, Normal, Material = workspace:FindPartOnRay(ray,Ignore)
if Hit.Name == "InertiaPart" then
--------------------------------------------------------------- MOVE PLAYER TO NEW POSITON FROM OLD POSITION
local Train = Hit
local TrainCF = Train.CFrame
LastTrainCF = Hit.CFrame
local Rel = TrainCF * LastTrainCF:Inverse()
RootPart.CFrame = Rel * RootPart.CFrame
end
end
end
--------------------------------------------------------------- CONNECTED
local function onPlayerAdded(player)
player.CharacterAdded:Connect(onCharacterAdded)
end
Players.PlayerAdded:Connect(onPlayerAdded)
QUESTION
Thanks for the heads up, though i have no idea on what i’m doing wrong?
Are you getting any errors?
No, however it seems to just keep me in the same position.
It would be nice if you posted your code in a code block. Formatting your code makes it easier for anyone to read your code and potentially help you with your problem.
Format a code block like so:
```lua
-- Your code here
```
That’ll become
-- Your code here
Fixed, thanks for the tip, never new that it excised.
I tried this method. It does, indeed move my character. But not as intended, as you can see here.