This is my first DevForum post so please correct anything I do wrong
Hey! I’ve been trying to make a rail grinding system but I’ve been only able to prototype 1 segment out of the entire railgrind model I want to make, so I temporarily named it to Zipline.
Here’s what I tried so far:
I used PrismaticConstraints to align the player onto the grindrail and set the velocity using an Attribute to move them across. Then in a while loop, I compare the constraint’s CurrentPosition to the distance between the Attachments to detect if they reached the end of the grindrail, then break out of the loop.
After that, I thought manually placing the ziplines together would work that way, but I sometimes just end up getting stuck between the two segments.
The goal is to find a way to link individual “ziplines” (which I’ll refer to as railgrind segments) together in a way creates a grindrail.
Note that this code is made using CollectionService and placed inside of StarterPlayerScripts
local CS = game:GetService('CollectionService')
local UIS = game:GetService('UserInputService')
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local HRP = char:WaitForChild("HumanoidRootPart")
local playerState = require(script.Parent.Parent:WaitForChild('PlayerStates'))
--PlayerStates being a module placed inside of StarterPlayerScripts too
local prismaticConstraint
--Referenced later to detect if the player wants to jump off the rail
for _, zipline in pairs(CS:GetTagged("Zipline")) do
local ziplinePart = zipline:WaitForChild("ZiplinePart")
local node0 = ziplinePart:WaitForChild("Node0")
local node1 = ziplinePart:WaitForChild("Node1")
local constraint = ziplinePart:WaitForChild("PrismaticConstraint")
prismaticConstraint= constraint
local velocity = zipline:GetAttribute("Velocity") or 35
constraint.Attachment0 = node0
local offset = 3
local dist = math.floor((node1.WorldPosition - node0.WorldPosition).Magnitude) + 2
zipline:SetAttribute("Touched",false)
ziplinePart.Touched:Connect(function(hit)
local humanoid = hit.Parent:FindFirstChildWhichIsA("Humanoid")
if humanoid and not zipline:GetAttribute("Touched") then
zipline:SetAttribute("Touched",true)
local char = humanoid.Parent
local HRP = char:WaitForChild("HumanoidRootPart")
HRP:WaitForChild("RootAttachment").Position -= Vector3.new(0,offset,0)
--Reposition attachment so player properly positions onto the rail
constraint.Attachment1 = HRP:WaitForChild("RootAttachment")
constraint.LimitsEnabled = true
constraint.UpperLimit = dist
constraint.Enabled = true
constraint.Velocity = velocity
while constraint.CurrentPosition < dist do
playerState.grindrailing = true
HRP.CFrame = CFrame.lookAt(HRP.Position, node1.WorldPosition + Vector3.new(0,offset,0))
task.wait()
if constraint.CurrentPosition >= dist or playerState.sliding == true or constraint.Enabled ~= true then
constraint.Enabled = false
constraint.Attachment1 = nil
playerState.grindrailing = false
HRP:WaitForChild("RootAttachment").Position += Vector3.new(0,offset,0)
break
end
end
task.wait(.1)
zipline:SetAttribute("Touched",false)
end
end)
end
--Cancel the grindrailing
UIS.InputBegan:Connect(function(input, gp)
if gp or input.KeyCode ~= Enum.KeyCode.Space then
return
end
prismaticConstraint.Enabled = false
prismaticConstraint.Attachment1 = nil
playerState.grindrailing = false
end)
Thank you in advance : P