Open Sourced Rail Grinding System

Hello! Around August of last year I made a post regarding Rail Grinding and how to implement it in-game.

> Blockquote

I wanted to make a somewhat clean way to make Rail Grinding that would allow one to place where they wanted rails visibly. After 8 difficult months (Quite a while, I know!) I believe I have finally come to a solution! Now, it may not be the perfect way to handle this type of thing (Admittedly I’m kind of a novice) but it shall suffice for now.

Although this was initially created for a game that I’m working on, I wanted to open source it for fellow aspiring game devs to also make great games! Below you can find the script itself (for those that know what they’re doing and wish to take a peek) and a place that already has the System set up (mainly for beginner developers and/or those who are too lazy to poke around).
RailGrind.rbxm (9.0 KB)
RailGrindSystemTestPlace.rbxl (98.5 KB)

I hope it is of some use to whomever feels they may need it! However I do have one request (or maybe two) and that is to credit me, as I spent a long time getting this to work. The other thing is to favorite
> Blockquote Multiversum, which is my passion project that I have been working on with my friends for the past year and a half.

With all of this out of the way I once again hope people find good use of this, and have a lovely day! :slight_smile:

23 Likes

thanks i may or may not use this maybe theres a chance i do theres a chance i dont
you should also share some screenshots so we can get a preview before downloading

4 Likes

What is a rail grinding system?

3 Likes

thank you, i probably should do that :laughing:

2 Likes

I used this as an example in a previous post, though this is most like much more advanced than what i made admittedly

3 Likes

A little visual Demo as per requested

10 Likes

thank you so much dude, I’ve been trying to implement a rail grinding system to my games for ages
thank you so muchhhhh

2 Likes

Hello, i really like this system, i was looking for it but I’m wondering how i can turn into R6. Could you help me out

1 Like

Hello, i would like to know if it’s working with R6?

2 Likes

It should still work with R6 save for some bugs:

  • You’ll need to create new Standing and Crouching animations for R6, since the original animations are made with R15 in mind
  • R6 does not have feet, just legs. Seeing as that’s the case try making the particle come out from the dominant leg
1 Like

Would you know how to make it go in the direction the character is facing? I’ve tried using Dot() but it didn’t quite work.

Here’s my code.

function rails(raila)
if (raila ~= _G.rail or _G.rail == nil) and player.Character then
local playercharacter = player.Character

	if _G.rail == nil then
		local dif = math.max((playercharacter.HumanoidRootPart.Velocity.magnitude - 80) / 75, 0)
		speedmulti = 1 + dif
		print(speedmulti)
	end

	_G.rail = raila
	bodyvelocity.MaxForce = Vector3.new(10000, 10000, 10000)
	bodygyro.MaxTorque = Vector3.new(100000, 100000, 100000)

	if crouching then
		fastslide:Play()
		normalslide1:Stop()
	else
		normalslide1:Play()
		fastslide:Stop()
	end

	GrindSound.Pitch = 1
	GrindSound:Play()

	bodygyro.CFrame = _G.rail.CFrame
	playercharacter.Humanoid.PlatformStand = true

	if _G.rail ~= nil then
		local xoff = _G.rail.CFrame:toObjectSpace(playercharacter.HumanoidRootPart.CFrame).p.X
		local zoff = _G.rail.CFrame:toObjectSpace(playercharacter.HumanoidRootPart.CFrame).p.Z
		local rot = playercharacter.HumanoidRootPart.CFrame - playercharacter.HumanoidRootPart.CFrame.p

		local railForward = _G.rail.CFrame.LookVector
		local playerForward = playercharacter.HumanoidRootPart.CFrame.LookVector

		local dotProduct = railForward:Dot(playerForward)

		local grindingDirection
		if dotProduct > 0 then
			grindingDirection = 1
			print("Forward")
		else
			grindingDirection = -1
			print("Backward")
		end

		-- Determine if the player is looking backward relative to the rail
		local cameraDirection = playercharacter.HumanoidRootPart.CFrame.LookVector
		local lookingBackward = cameraDirection:Dot(railForward) < 0

		if lookingBackward then
			grindingDirection = -1 -- Switch to backward grinding
			print("Looking Backward")
		end

		-- Update player's position and rotation based on grinding direction
		playercharacter.HumanoidRootPart.CFrame = CFrame.new((_G.rail.CFrame * CFrame.new(xoff, 3, zoff)).p) * rot
		local movementDirection = railForward * grindingDirection

		-- Adjusting velocities based on the grinding direction
		playercharacter.HumanoidRootPart.Velocity = movementDirection * (80 / speedmulti)
		bodyvelocity.Velocity = movementDirection * (25 * speedmulti)

		-- Ensure the player character faces backward when grinding backward
		if grindingDirection == -1 then
			if not originalCFrame then
				originalCFrame = playercharacter.HumanoidRootPart.CFrame -- Store original CFrame
			end
			playercharacter.HumanoidRootPart.CFrame = CFrame.lookAt(
				playercharacter.HumanoidRootPart.Position,
				playercharacter.HumanoidRootPart.Position + (railForward * -1) -- Face backward
			)
		else
			-- Reset to the original CFrame when not grinding backward
			if originalCFrame then
				playercharacter.HumanoidRootPart.CFrame = originalCFrame
				originalCFrame = nil -- Clear the original CFrame to avoid resetting multiple times
			end
		end
	end
end

end

Are you trying to make it so the player can move in either direction in relation to where they get on from? I never really had moving both ways in mind when I was working on the script since in my game’s context there’s only one direction i’d want the player to go in to begin with, but I can see what I can do.

I will say however that there’s no promises, since I do have like 3 large projects that I’m a part of at once

1 Like