Jailbreak train platform system?

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.

2 Likes

Oh yea I completely forgot about that

1 Like

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.

1 Like

Jailbreak has a very custom-made train system that was designed to work before Characters On Moving Platforms was released.

17 Likes

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.

image

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!

100 Likes

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 :smiley:

134 Likes

Yeah, there is, though as soon as you jump your removed from that platform, causing you to just fall back.

3 Likes

Thank you, very helpful.

3 Likes

What’s the LastTrainCframe? And what’s the need of inverting it? Thank you btw.

3 Likes

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.

image

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.

31 Likes

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.

4 Likes

This is my code, however it wont cframe as a local script doesn’t seem to be able to do that.

12 Likes

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.

6 Likes

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?

11 Likes

Are you getting any errors?

4 Likes

No, however it seems to just keep me in the same position.

5 Likes

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
6 Likes

Fixed, thanks for the tip, never new that it excised.

4 Likes

I tried this method. It does, indeed move my character. But not as intended, as you can see here.

3 Likes

Yeah exactly what im having issues with.

5 Likes