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!
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
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
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