I currently want to fix this train system that was made by someone else, the code is not understandable and currently I want to fix sudden errors and fix positioning system, here the code
local body = script.Parent.Engine.Body
local main = body.Main
local engine = main.Engine
local wps = script.Parent.Waypoints
local ts = game:GetService("TweenService")
local acceleration = .09
local deceleration = .2
local speed = 0
local accelerating,decelerating,stopping = false,false,false
local door = "closed"
local cwp
local originalspeed = 40
local Main_Dir = 0
local cwpn = 1
local playerwelds = {}
local traveling = false
local cp = 0
local Stopped = false
local glider = Instance.new("Part", script.Parent)
glider.Position = Vector3.new(main.Position.X, wps["1"].Position.Y, main.Position.Z)
glider.Anchored = true
glider.CanCollide = false
glider.Size = Vector3.new(1, 1, 1)
glider.Name = "Train_Glider"
main.Roll:Play()
function Weld(Model)
for i,v in pairs(Model:GetDescendants()) do
if v:IsA("BasePart") and v ~= main then
local wd = Instance.new("Weld", v)
wd.Name = v.Name.."_Weld"
wd.Part0 = v
wd.Part1 = main
wd.C0 = CFrame.new()
wd.C1 = main.CFrame:toObjectSpace(v.CFrame)
v.Anchored = false
elseif v == main then
local wd = Instance.new("WeldConstraint", v)
wd.Name = v.Name.."_Weld"
wd.Part0 = v
wd.Part1 = glider
v.Anchored = false
end
end
end
function Accelerate(maxspeed)
coroutine.resume(coroutine.create(function()
if maxspeed > speed then
accelerating = false
wait(.05)
accelerating = true
repeat
if stopping or decelerating then return end
game:GetService("RunService").Heartbeat:Wait()
speed = speed + acceleration
until speed >= maxspeed
accelerating = false
elseif maxspeed < speed then
decelerating = true
repeat
if stopping or accelerating then return end
game:GetService("RunService").Heartbeat:Wait()
speed = speed - deceleration
until speed <= maxspeed
decelerating = false
end
end))
end
function Run_Door(Model)
coroutine.resume(coroutine.create(function()
for i,v in pairs(Model:GetChildren()) do
if v:IsA("Model") then
spawn(function()
for i,v in pairs(body:GetDescendants()) do
if v:IsA("BasePart") then
v.Anchored = true
end
end
door = "opening"
local cl = v.PrimaryPart.CFrame
main.DoorOpen:Play()
main.Opening:Play()
for c=0,1,.004 do
game:GetService("RunService").Heartbeat:Wait()
if Model:FindFirstChild("Open"..v.Name) then
local pr = v.PrimaryPart
local cf = pr.CFrame:Lerp(Model["Open"..v.Name].CFrame, (c*(c))*0.2)
v:SetPrimaryPartCFrame(cf)
end
end
door = "open"
wait(20)
main.ClosingAnnouncement:Play()
wait(main.ClosingAnnouncement.TimeLength)
main.DoorClose:Play()
wait(3)
for c=0,1,.0035 do
game:GetService("RunService").Heartbeat:Wait()
local pr = v.PrimaryPart
local cf = pr.CFrame:Lerp(cl, (c*(c))*0.1)
v:SetPrimaryPartCFrame(cf)
end
door = "closed"
for i,v in pairs(body:GetDescendants()) do
if v:IsA("BasePart") then
v.Anchored = false
end
end
end)
end
end
end))
end
function DoorRun()
Run_Door(body.Doors)
Run_Door(script.Parent.Parent.StationDoors[script.Parent.NextStop.Value].Doors)
repeat wait() until door == "closed"
end
function Stop()
main.Brake:Play()
stopping = true
decelerating = true
local spd = speed
local dist = (glider.Position-cwp.Position).Magnitude
originalspeed = speed
while (glider.Position-cwp.Position).Magnitude >= .8 do
game:GetService("RunService").Heartbeat:Wait()
speed = ((spd/dist)*(glider.Position-cwp.Position)).Magnitude
if not stopping then return end
end
speed = 0
Remove_Player_Welds()
if not wps:FindFirstChild(cwpn-1) then
script.Parent.Direction.Value = 1
elseif not wps:FindFirstChild(#wps:GetChildren()+1) then
script.Parent.Direction.Value = -1
end
wait(1)
decelerating = false
stopping = false
Stopped = true
coroutine.resume(coroutine.create(function()
DoorRun()
Player_Weld()
if not wps:FindFirstChild(cwpn-1) then
script.Parent.Direction.Value = 1
elseif not wps:FindFirstChild(cwpn+1) then
script.Parent.Direction.Value = -1
end
main.Depart:Play()
wait(2.5)
if not traveling then
if cwp:FindFirstChild("DepartSpeed") then
Accelerate(cwp.DepartSpeed.Value)
else
Accelerate(originalspeed)
end
if not wps:FindFirstChild(tostring(cwpn-1)) then
Travel(1)
elseif not wps:FindFirstChild(tostring(cwpn+1)) then
Travel(-1)
end
end
end))
end
function Player_Weld()
local Region = Region3.new(
Vector3.new(
main.Position.X - main.Size.X/2,
main.Position.Y - main.Size.Y/2,
main.Position.Z - main.Size.Z/2
),
Vector3.new(
main.Position.X + main.Size.X/2,
main.Position.Y + 8,
main.Position.Z + main.Size.Z/2
)
)
for _,Part in pairs(game.Workspace:FindPartsInRegion3(Region,nil,math.huge)) do
if Part ~= nil and Part.ClassName == "Part" and Part.Name == "HumanoidRootPart" then
if Part.Parent:FindFirstChild("Humanoid") then
if not Part.Parent.Humanoid.Sit then
local wd = Instance.new("WeldConstraint", Part.Parent.HumanoidRootPart)
wd.Part0 = Part.Parent.HumanoidRootPart
wd.Part1 = main
wd.Name = "Train_Weld"
Part.Parent.Humanoid.JumpPower = 0
Part.Parent.Humanoid.PlatformStand = true
playerwelds[#playerwelds+1] = wd
end
end
end
end
end
function Remove_Player_Welds()
for i,v in pairs(playerwelds) do
pcall(function()
v.Part0.Parent.Humanoid.JumpPower = 50
v.Part0.Parent.Humanoid.PlatformStand = false
playerwelds[#playerwelds+1] = nil
v:Destroy()
end)
end
end
function Travel(Dir)
Player_Weld()
warn(Dir)
if Dir == 1 then
traveling = true
wait(1)
Main_Dir = 0
local w = 0
for w2=1,#wps:GetChildren() do
w = w + 1
local v = wps[tostring(w)]
cwp = v
cwpn = w
if not v:FindFirstChild("StationName") then Stopped = false end
if v:FindFirstChild("StationName") and not Stopped then repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 18+(speed*.5) else repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 21 end
if v:FindFirstChild("StationName") and not Stopped then script.Parent.NextStop.Value = v.StationName.Value repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 50+(speed*12) Stop() traveling = false end
if v:FindFirstChild("SetSpeed") then if v.SetSpeed.TargetDirection.Value == 1 and script.Parent.Direction.Value == 1 then Accelerate(v.SetSpeed.Value) end end
end
traveling = false
elseif Dir == -1 then
traveling = true
wait(1)
Main_Dir = -1
local w = #wps:GetChildren()-1
for w2=1,#wps:GetChildren() do
w = w - 1
local v = wps[w]
cwp = v
cwpn = w
if not v:FindFirstChild("StationName") then Stopped = false end
if v:FindFirstChild("StationName") and not Stopped then repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 18+(speed*.5) else repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 21 end
if v:FindFirstChild("StationName") and not Stopped then script.Parent.NextStop.Value = v.StationName.Value repeat game:GetService("RunService").Heartbeat:Wait() until (glider.Position-v.Position).Magnitude <= 50+(speed*12) Stop() traveling = false end
if v:FindFirstChild("SetSpeed") then if v.SetSpeed.TargetDirection.Value == -1 and script.Parent.Direction.Value == -1 then Accelerate(v.SetSpeed.Value) end end
end
cwpn = 1
traveling = false
end
end
main.Engine:Play()
game:GetService("RunService").Heartbeat:Connect(function()
if cwp then glider.CFrame = glider.CFrame:Lerp(CFrame.new(glider.CFrame.p, cwp.CFrame.p)*CFrame.Angles(0, math.rad(180)*Main_Dir, 0), .05*(speed*.03)) end
glider.CFrame = glider.CFrame * CFrame.new(0, 0, -math.rad(speed)*script.Parent.Direction.Value)
body.MainBody.Floor.Velocity = glider.CFrame.LookVector*speed*script.Parent.Direction.Value
main.Engine.Pitch = speed*.02
main.Engine.Volume = speed*.07
main.Roll.Volume = speed*.02
if main.Engine.Volume >= 1 then main.Engine.Volume = 1 end
if main.Engine.Pitch >= 1.07 then main.Engine.Pitch = 1.07 end
if main.Roll.Volume >= 1.3 then main.Roll.Volume = 1.3 end
end)
Weld(body)
wait(1)
Accelerate(originalspeed)
Travel(1)
errors:
here is the train itself
oh_no.rbxm (184.0 KB)