You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? Keep it simple and clear!
A simply rail grinding system similar to those seen in 3D sonic games, no boosters or momentum work needed though. -
What is the issue? Include screenshots / videos if possible!
As of right now, you just get flung out of existence. No idea how the hell i’d fix it. Here is a video. https://gyazo.com/b52d2982004a351f3ae53cf0e2dac1d7 -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I’ve tried getting help from twitter and the devforum. I’ve gotten nowhere and I’m stumped.
Here is the code so far.
--\\
--||
--|| grind rail system
--|| made by kizu, some snippets of code from an open sourced game.
--||
--//
--\\ Services
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
--\\ Constants
local PLAYER = Players.LocalPlayer
local GrindSpeed = 50
local CanGrind = true
--\\ Variables
local Character = PLAYER.Character
repeat wait() until Character.HumanoidRootPart
Humanoid = Character:WaitForChild("Humanoid")
RootPart = Character:WaitForChild("HumanoidRootPart")
local Rotation = CFrame.new()
local Grinding = false
local CurrentRail = nil
local RailOffset = 0
local Direction = -1
local CurrentRails = {}
local finished = false
--\\ Functions
for _, part in pairs(workspace.Rails:GetDescendants()) do
if part:IsA("BasePart") then
part.Touched:connect(function(hit)
if hit.Parent.Name == PLAYER.Name then
PLAYER.PlayerGui.DEBUGui.Touching.Text = "Touching: "..part.Name
if CanGrind then
CurrentRail = part
for i,v in pairs(part.Parent:GetChildren()) do
if v:IsA("BasePart") and v.Name:match("Part") then
table.insert(CurrentRails, v)
end
end
for i,v in pairs(CurrentRails) do
print(v)
end
CanGrind = false
PLAYER.PlayerGui.DEBUGui.Grinding.Text = "Grinding: Yes"
repeat wait() until CurrentRail
local offset = CurrentRail.CFrame:pointToObjectSpace(RootPart.Position)
if offset.Y > 0 then
local lookOffset = CurrentRail.CFrame:vectorToObjectSpace(RootPart.CFrame.lookVector)
Direction = lookOffset.Z <= 0 and -1 or 1
RailOffset = offset.Z
Grinding = true
end
end
end
end)
end
end
--\\ initiate
RunService.Heartbeat:Connect(function()
if Character and Humanoid.Health > 0 then
if Grinding and CurrentRail then
CanGrind = false
Humanoid.AutoRotate = false
for i_,RAIL in pairs(CurrentRails) do
repeat
PLAYER.PlayerGui.DEBUGui.RailSize.Text = "RailSize: "..CurrentRail.Size.Z
PLAYER.PlayerGui.DEBUGui.RailOffset.Text = "RailOffset: "..RailOffset
CurrentRail = RAIL
print(CurrentRail.Name)
RootPart.CFrame = CurrentRail.CFrame * CFrame.new(0, 1.1 + 2.6, RailOffset) * CFrame.Angles(0, (Direction == 1 and math.pi or 0), 0)
RailOffset = RailOffset + (Direction * GrindSpeed)
RootPart.Velocity = CurrentRail.CFrame.lookVector * GrindSpeed * (-Direction)
CanGrind = false
Humanoid.PlatformStand = true
if Direction == -1 then
finished = RailOffset < -(CurrentRail.Size.Z / 2.5)
print("finished: ".. -(CurrentRail.Size.Z / 2.5))
elseif Direction == 1 then
finished = RailOffset > CurrentRail.Size.Z / 2.5
print("finished: ".. CurrentRail.Size.Z / 2.5)
end
if finished then
CanGrind = true
print("DONE!")
end
until finished
end
CanGrind = true
--RootPart.CFrame = CurrentRail.CFrame * CFrame.new(0, 1.1 + 2.6, RailOffset) * CFrame.Angles(0, (Direction == 1 and math.pi or 0), 0)
--RailOffset = RailOffset + (Direction * GrindSpeed)
--RootPart.Velocity = CurrentRail.CFrame.lookVector * GrindSpeed * (-Direction)
--Humanoid.PlatformStand = true
end
Grinding = false
if Grinding == true then
if Humanoid:GetState() ~= Enum.HumanoidStateType.PlatformStanding and Grinding == true then
CanGrind = false
Humanoid.PlatformStand = true
Humanoid.AutoRotate = false
end
elseif (Grinding == false) then
if Humanoid:GetState() == Enum.HumanoidStateType.PlatformStanding and Grinding == false then
Grinding = false
CurrentRail = nil
CanGrind = true
Humanoid.PlatformStand = false
Humanoid.AutoRotate = true
CurrentRail = nil
PLAYER.PlayerGui.DEBUGui.RailSize.Text = "RailSize: "
PLAYER.PlayerGui.DEBUGui.RailOffset.Text = "RailOffset: "
print("DONE WITH RAILS CLEARING TABLE")
table.clear(CurrentRails)
end
end
end
if Humanoid.Jump == true and Grinding then
Grinding = false
Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
end)
It reads numbered rails from 001 to whatever the amount of rails it ends at. Help would be much appreciated!
Here’s a place file demo of the script:
rail demo.rbxl (37.2 KB)
i know i posted this before but now everything should be easier to read and better to try