
I’m very confused, as it is clearly there
Script?
This text will be blurred
local config = {}
--[[
coasterModel model that contains ONLY the track parts to be raytraced
startingPart first part to begin raytracing on
cartModel model that contains carts named properly (see below)
cartName name of each cart, must be appended by a number in order (cartName1, cartName2, ...)
cartOffset offset that the primarypart of the cart needs to be moved to line up with track
cartSeparation distance in studs between primaryparts of each cart
physicsProperties table containing the following information:
- minSpeed minimum speed (default 24)
- maxSpeed maximum speed (default 160)
- liftSpeed speed when ascending steep angles (default 48)
- liftSine sine of the angle for lifts (default math.sin(math.pi/4))
- initialSpeed speed at time t=0 (default minSpeed)
- gravity gravitational constant (default 64)
- friction coefficient of friciton (default 1.6)
- brakes proportionality for brakes (braking is linear with speed) (default 1)
- boostAcceleration acceleration (per second) of boosts (default 48)
--]]
local coaster = workspace.Coasters:FindFirstChild("GenericCoaster")
config.name = "GenericCoaster"
config.spline = coaster.Tracks
config.trains = coaster.Trains
config.trainoffset = CFrame.new(0, 0, 0) * CFrame.Angles(0, math.pi, 0)
config.start = coaster.Tracks["One"]
config.cartmodel = config.trains
config.cartseperation = 5
config.cartname = "Train"
config.pproperties ={boostacceleration = 45, liftspeed = 24, maxspeed = 449, brakes = 1.654}
return config```
https://www.roblox.com/library/9385542917/Trains-For-CFRAME-System?ViewInBrowser=true&CreatorId=11069647&SearchId=FECA70CB-4343-4BDC-A8A6-A7EB225C3A12&Category=Model&Position=1&SearchKeyword=&CreatorType=Group&SortType=Relevance
Can u show me the WHOLE script pls?
Just so I know if there’s any errors in the code
local handler = {}
local gs = game.GetService
local ffc, wfc = game.FindFirstChild, game.WaitForChild
local new, ray = Instance.new, Ray.new
local insert, remove = table.insert, table.remove
local v3, cf, matrix, ang = Vector3.new, CFrame.new, CFrame.fromMatrix, CFrame.Angles
local sign, abs, min, max, floor, sqrt = math.sign, math.abs, math.min, math.max, math.floor, math.sqrt
local rad, sin, deg = math.rad, math.sin, math.deg
local asin = math.asin
local isa = game.IsA
local destroy = game.Destroy
-- modules
local repstore,runserv, players = gs(game, "ReplicatedStorage"),gs(game, "RunService"),gs(game,"Players")
local inputserv = gs(game,"UserInputService")
local player = players.LocalPlayer
local camera = workspace.CurrentCamera
local NETWORK = require(repstore.Modules.Network)
local physicsfps = 15
local function recurse(o, callback)
for _, v in pairs(o:GetChildren()) do
callback(v)
if #v:GetChildren() > 0 then
recurse(v, callback)
end
end
end
local brickcolordata = {
[BrickColor.Black().Number] = function(currentVelocity, cosine, sine, timeDelta, physicsProperties)
local brakesAcceleration = -physicsProperties.brakes * cosine * currentVelocity
currentVelocity = currentVelocity + timeDelta * brakesAcceleration
return currentVelocity
end,
[BrickColor.new("Lime green").Number] = function(currentVelocity, cosine, sine, timeDelta, physicsProperties)
return currentVelocity + physicsProperties.boost * timeDelta
end,
[BrickColor.new("Eggplant").Number] = function(currentVelocity, cosine, sine, timeDelta, physicsProperties)
return currentVelocity + timeDelta * -1.5 * cosine * currentVelocity
end
}
local nv = v3()
local dot = nv.Dot
local nc = cf()
local upnorm = v3(0, 1, 0)
handler.cams = {"fps", "side", "cinematic"}
handler.cam = 1
handler.IsOnRide = false
local cincam = require(script.Cinematic)
function handler:new(config, coastername)
local funcs = {}
local movecam = false
local currentseat
local lastpos
local lastvel
local function getallnodes(model, start, prev)
local current = start
local nodes = {}
local cflist = {}
local temp = new("Model")
temp.Name = "IndexedParts"
temp.Parent = model.Parent
local face = {
"RightVector",
"UpVector",
"lookVector"
}
local size = {
"X",
"Y",
"Z"
}
insert(cflist, current.CFrame)
repeat
insert(nodes, current)
current.Name = #nodes
current.Parent = temp
if #nodes > 1 then
start.Parent=model
end
local nextp
for z = 1, 2 do
local t = z == 1 and 1 or -1
for i = 1, 3 do
nextp =
workspace:FindPartOnRayWithWhitelist(
ray(
current.Position - current.CFrame[face[i]] * current.Size[size[i]] / 3 * t,
current.CFrame[face[i]] * current.Size[size[i]] * 1.5 * t
),
{model},
true
)
if nextp then
break
end
end
if nextp then
break
end
end
if not nextp then
warn("Current Node:", #nodes, #nodes+1)
error("Couldn't find next node ", #nodes+1)
end
local tcf = nextp.CFrame
local cfc = cflist[#cflist]
local cfconst = {v3(1, 0, 0), v3(0, 1, 0), v3(0, 0, 1)}
for p = 1, 3 do
local vdot = 0
local nface = cfc[face[p]]
local taker
for z = 1, 2 do
local t = z == 1 and 1 or -1
for i = 1, 3 do
local ndot = nface:Dot(tcf[face[i]] * t)
if vdot < ndot then
vdot = ndot
taker = tcf[face[i]] * t
end
end
end
if not taker then
error("Unable to find a close face " .. #cflist)
end
cfconst[p] = p == 3 and taker * -1 or taker
end
local ncf = matrix(tcf.p, cfconst[1], cfconst[2], cfconst[3])
insert(cflist, ncf)
prev = current
current = nextp
until current == start
for _, t in ipairs(temp:GetChildren()) do
t.Parent = model
end
destroy(temp)
for t=1,#nodes do
nodes[t]={cframe = cflist[t], brickcolor = nodes[t].BrickColor, trigger = nodes[t]:FindFirstChild("Trigger") and nodes[t]:FindFirstChild("Trigger").Value or nil}
end
return nodes
end
local function movewithinbounds(pos, num)
return (pos-1)%num+1
end
local function distnodes(nodes, start, disp)
if disp == 0 then
return 0
end
local dir, disp = sign(disp), abs(disp)
local ndisp, prevnode = 0, 0
if start ~= floor(start) then
local prevnode = movewithinbounds(floor(start)+(1-dir)/2, #nodes)
local nextnode = movewithinbounds(floor(start)+(1+dir)/2, #nodes)
local fraction = abs(start-floor(start)-(1+dir)/2)
local ind = (nodes[nextnode].cframe.p - nodes[prevnode].cframe.p).magnitude
if ind*fraction>disp then
return dir*disp/ind
else
ndisp = ndisp+fraction
disp=disp-ind*fraction
end
end
prevnode = movewithinbounds(floor(start)+(1+dir)/2, #nodes)
while true do
local nextnode = movewithinbounds(floor(prevnode)+dir, #nodes)
local ind = (nodes[nextnode].cframe.p - nodes[prevnode].cframe.p).magnitude
if ind>disp then
return dir*(ndisp+disp/ind)
else
ndisp = ndisp+1
disp = disp-ind
end
prevnode = nextnode
end
end
local function getphysicsatpoint(nodes, pos)
local prevn = movewithinbounds(floor(pos), #nodes)
local nextn = movewithinbounds(prevn+1, #nodes)
local fraction = pos - floor(pos)
local totdist = nodes[nextn].cframe.p - nodes[prevn].cframe.p
local hordist = (totdist * v3(1, 0, 1)).magnitude
local verdist = (totdist * v3(0, 1)).Y
totdist = totdist.magnitude
return hordist/totdist, verdist/totdist, nodes[prevn]
end
local function getinterpolatedcframe(nodes, pos)
local prevn = movewithinbounds(floor(pos), #nodes)
local nextn = movewithinbounds(prevn + 1, #nodes)
local fraction = pos - floor(pos)
return nodes[prevn].cframe:lerp(nodes[nextn].cframe, fraction)
end
local function generateposcache(nodes,numcarts,cartoffset,cartsep,pproperties,cartslist,trigger)
local minspeed = pproperties.minspeed or 24
local maxspeed = pproperties.maxspeed or 160
local liftspeed = pproperties.liftspeed or 48
local liftsine = pproperties.liftsine or sqrt(0.5)
local initialspeed = pproperties.initialspeed or minspeed
local gravity = pproperties.gravity or 48
local friction = pproperties.friction or 1.6
local brakes = pproperties.brakes or 0.8
local boost = pproperties.boost or 48
local triggers = trigger or {}
pproperties = {
minspeed = minspeed,
maxspeed = maxspeed,
liftspeed = liftspeed,
liftsine = liftsine,
initialspeed = initialspeed,
gravity = gravity,
friction = friction,
brakes = brakes,
boost = boost
}
local timedelta = 1/physicsfps
local posdata = {}
local veldata = {}
local funcdata = {}
local liftdata = {}
local currentnodalpos = 1
local currentvel = initialspeed
local currentframe = -1
while currentnodalpos<#nodes+1 and currentframe*timedelta<600 do
currentframe=currentframe+1
local cosine, sine, part = getphysicsatpoint(nodes, currentnodalpos)
local currentsign = sign(currentvel)
--acceleration
local gravityacceleration = -gravity * sine
local frictionacceleration = -friction * cosine * currentsign
if brickcolordata[part.brickcolor.Number] then
currentvel = brickcolordata[part.brickcolor.Number](currentvel, cosine, sine, timedelta, pproperties)
end
currentvel = currentvel+timedelta*(gravityacceleration+frictionacceleration)
liftdata[currentframe] = sine>liftsine and currentvel<liftspeed
--velocity
if sine>liftsine and currentvel<liftspeed then
currentvel = min(currentvel+(liftspeed-gravityacceleration)*timedelta, liftspeed)
end
currentvel = max(min(currentvel,maxspeed), minspeed)
--displacement
currentnodalpos = currentnodalpos+distnodes(nodes, currentnodalpos,timedelta*currentvel)
posdata[currentframe] = {}
if triggers[currentframe] then
funcdata[currentframe] = triggers[currentframe]
end
veldata[currentframe] = currentvel
for i=1,numcarts do
local poffset = floor(numcarts/2) - i
local currentcart = ffc(cartslist, "Train" .. i)
local customoffset = ffc(currentcart, "Offset")
local noffset = 0
if customoffset then
noffset = customoffset.Value.Z
end
insert(posdata[currentframe], getinterpolatedcframe(nodes, currentnodalpos+distnodes(nodes, currentnodalpos, (noffset+cartsep)*poffset))*cartoffset)
end
if currentframe%100==0 then
wait()
end
end
posdata[#posdata]=posdata[0]
return posdata, veldata, funcdata, liftdata
end
local function setup(model,start,cartmodel,cartname,cartoffset,cartsep,pproperties, triggers)
pproperties = pproperties or 0
local nodes = getallnodes(model, start, model["0"])
local carts = {}
for i=1, #cartmodel:GetChildren() do
if i == 1 then
--self.Controllers.DebugController:AttachToCart(ffc(cartmodel, cartname..i))
end
local cart = ffc(cartmodel, cartname .. i)
if cart then
insert(carts, cart)
else
break
end
end
local posdata, veldata, funcdata, liftdata = generateposcache(nodes, #carts, cartoffset, cartsep, pproperties, cartmodel,triggers)
local ride = {}
ride.Active = false
local timetocompletion = #posdata/physicsfps
local timesyncval = workspace.Time
local lastsyncval, lasttickval, lastpausetime = 0,0,0
local lastsyncstarttime = 0
local remainingtime = 0
local paused,finished = false,true
NETWORK.call("SetCoasterTime", coastername, timetocompletion)
--self.Services.CoasterService:SetCoasterTime(coastername, timetocompletion)
local prevframe = posdata[movewithinbounds(1, #posdata)]
local nextframe = posdata[movewithinbounds(1+1, #posdata)]
local velocity = veldata[movewithinbounds(1+1, #posdata)]
for k,v in ipairs(carts) do
v:SetPrimaryPartCFrame(prevframe[k]:lerp(nextframe[k], 1))
end
local function gettimesincelastsync()
local t = tick()
local delta = t-lasttickval
lasttickval=t
return t+lastsyncval-lastsyncstarttime,delta
end
local function resynctime(timetosync)
local t = tick()
lastsyncval = timesyncval.Value
local initialval = lastsyncval+t-timetosync
lasttickval = t
lastsyncstarttime = initialval
end
local x,y = 0,0
inputserv.InputChanged:connect(function(io, gpe)
if gpe then return end
if io.UserInputType.Name == "MouseMovement" then
local delta = -io.Delta * 0.05
y = math.clamp(y + delta.Y, -60, 60)
x = math.clamp(x + delta.X, -75, 75)
end
end)
-- local userInput = self.Controllers.UserInput
-- local mobileInput = userInput:Get("Mobile")
-- mobileInput.TouchMoved:Connect(function(pos, d)
-- local delta = -d * 0.21
-- y = math.clamp(y + delta.Y, -60, 60)
-- x = math.clamp(x + delta.X, -75, 75)
-- end)
local function beginrun(coaster, isonride, ...)
local ran = {}
x,y=0,0
local function lerp(a,b,t)
return a*(1-t)+(b*t)
end
local function map(n, oldmin, oldmax, min, max)
return (min + ((max - min) * ((n - oldmin) / (oldmax - oldmin))))
end
local blackout = player.PlayerGui.Effects.Blackout
local velmeter = player.PlayerGui.Effects.Velocity
local wind = player.PlayerGui.Effects.Wind
local cosmetics = {}
-- local types = {"Hairs", "Hats", "Accessories", "Glasses"}
-- for i, costype in pairs(types) do
-- recurse(ffc(player.Character.Cosmetics, costype), function(o)
-- if isa(o, "BasePart") and o.Parent.Name == "Parts" and o.Transparency < 1 then
-- cosmetics[o] = {o, o.Transparency}
-- end
-- end)
-- end
runserv:BindToRenderStep(coaster, Enum.RenderPriority.Last.Value+1, function(delta)
local timesincestart, delta = gettimesincelastsync()
local framenumber, directionalframe = timesincestart*physicsfps
framenumber,fractionaltime = floor(framenumber), framenumber-floor(framenumber)
local prevframe = posdata[movewithinbounds(framenumber, #posdata)]
local nextframe = posdata[movewithinbounds(framenumber+1, #posdata)]
local velocity = veldata[movewithinbounds(framenumber+1, #posdata)]
local trig = funcdata[movewithinbounds(framenumber+1, #posdata)]
local lifthill = liftdata[movewithinbounds(framenumber+1, #posdata)]
for k,v in ipairs(carts) do
v:SetPrimaryPartCFrame(prevframe[k]:lerp(nextframe[k], fractionaltime))
if v:FindFirstChild("DebugStats") then
v.DebugStats.DebugText.Text = "Velocity: " .. velocity
end
end
local camera = workspace.CurrentCamera
if movecam then
local seatcf = currentseat and currentseat.CFrame or carts[1].Seats:FindFirstChild("Seat1").CFrame
if trig then
if ran[funcdata[movewithinbounds(framenumber+1, #posdata)]] then return end
ran[funcdata[movewithinbounds(framenumber+1, #posdata)]] = true
spawn(trig)
end
local pos = seatcf.p
if not lastpos then
lastpos = pos
end
local vel = (seatcf - pos):inverse()*((pos - lastpos)/delta)
lastpos = pos
lastvel = vel
local nextcameracframe =
seatcf
* cf(0, 0.5, 0)
* cf(0, 2, 0)
* ang(0, 0, 0)
--prevframe[#prevframe]:lerp(nextframe[#nextframe], fractionaltime)*CFrame.new(0, 4, 0) * CFrame.Angles(0, math.rad(90), 0)
if movecam then
inputserv.MouseBehavior = Enum.MouseBehavior.LockCenter
inputserv.MouseIconEnabled = false
local a = 1
local b = 2
local d = math.pi/2
local A = 1
local B = 0.75
local breathx = 1.5 * sin(a*tick() + d)
local breathy = 0.6 * sin(b*tick())
local camtype = handler.cams[handler.cam]
if camtype == "fps" then
for i, cosmetic in pairs(cosmetics) do
if cosmetic[1].Transparency < 1 then cosmetic[1].Transparency = 1 end
end
for i, p in pairs(player.Character:GetChildren()) do
if p:IsA("Accessory") or p:IsA("Accoutrement") then
if p.Handle.Transparency < 1 then p.Handle.Transparency = 1 end
end
end
player.Character.Head.Transparency=1
camera.CameraType = "Scriptable"
camera.CFrame = nextcameracframe * ang(0, rad(x), 0) * ang(rad(y), 0, 0) * ang(breathx*(velocity*.001)+0.05, 0, breathy*(velocity*.001)+0.05)
camera.FieldOfView = lerp(camera.FieldOfView, 60 + velocity * .31, fractionaltime)
elseif camtype== "side" then
for i, cosmetic in pairs(cosmetics) do
if cosmetic[1].Transparency ~= cosmetic[2] then cosmetic[1].Transparency = cosmetic[2] end
end
for i, p in pairs(player.Character:GetChildren()) do
if p:IsA("Accessory") or p:IsA("Accoutrement") then
if p.Handle.Transparency == 1 then p.Handle.Transparency = 0 end
end
end
player.Character.Head.Transparency=0
camera.CameraType = "Scriptable"
camera.CFrame = nextcameracframe * cf(-5, 2, 5)
camera.FieldOfView = lerp(camera.FieldOfView, 60 + velocity * .31, fractionaltime)
elseif camtype == "cinematic" then
for i, cosmetic in pairs(cosmetics) do
if cosmetic[1].Transparency ~= cosmetic[2] then cosmetic[1].Transparency = cosmetic[2] end
end
for i, p in pairs(player.Character:GetChildren()) do
if p:IsA("Accessory") or p:IsA("Accoutrement") then
if p.Handle.Transparency == 1 then p.Handle.Transparency = 0 end
end
end
player.Character.Head.Transparency=0
camera.CameraType = "Scriptable"
if not cincam.p then
cincam.last = tick()
cincam.p = seatcf.p + v3(math.random(-20, 20), 5, math.random(-20, 20))
end
if tick() - cincam.last >= 6 then
cincam.last = tick()
cincam.p = seatcf.p + v3(math.random(-20, 20), 5, math.random(-20, 20))
end
camera.CFrame = cincam.update(delta, seatcf.p, velocity)
--camera.FieldOfView = lerp(camera.FieldOfView, 60 + velocity * .31, fractionaltime)
end
local character = player.Character
if not wind.Playing then
wind:Play()
end
-- wind.PlaybackSpeed = (1.2 * (velocity / 200))
-- wind.Volume = 0.6
-- game.Lighting.Blur.Size = (velocity*0.05)-1.2
-- game.Lighting.ColorCorrection.Saturation = -(velocity*0.001)
--game.Lighting.ColorCorrection.Brightness = -(velocity*0.0003)
-- blackout.ImageTransparency = 1-(velocity*0.01)
end
else
local cartwind = carts[1].PrimaryPart:FindFirstChild("Wind")
if cartwind then
local cartwind = carts[1].PrimaryPart.Wind
if cartwind.Playing == false then
cartwind:Play()
end
cartwind.Volume = 0.3
cartwind.PlaybackSpeed = (1.2 * (velocity / 200))
end
end
remainingtime = remainingtime - delta
if remainingtime <= 0 then
local dust = camera:FindFirstChild("Dust")
if dust then dust:Destroy() end
camera.FieldOfView = 70
blackout.ImageTransparency = 1
game.Lighting.Blur.Size = 0
game.Lighting.ColorCorrection.Saturation = 0
game.Lighting.ColorCorrection.Brightness = 0
runserv:UnbindFromRenderStep(coaster)
end
end)
end
ride.Play = function(self, starttime, name)
resynctime(starttime or 0)
remainingtime = math.huge
paused,finished=false,false
beginrun(name)
end
ride.PlayOnceAndStop = function(self, starttime, name)
resynctime(starttime or 0)
remainingtime = timetocompletion - (starttime or 0)
paused, finished = false, false
beginrun(name)
end
ride.Resume = function(self, name)
if not (finished or paused) then
return
elseif finished and not paused then
self:Play(nil,name)
else
self:Play(lastpausetime,name)
end
end
ride.ResumeAndStop = function(self,offset,name)
if not (finished or paused) then
return
elseif finished and not paused then
self:PlayOnceAndStop(offset,name)
else
self:PlayOnceAndStop(offset,name)
end
end
ride.Pause = function(self, name)
self.Active=false
lastpausetime = gettimesincelastsync()
paused=true
pcall(function() runserv:UnbindFromRenderStep(name) end)
end
ride.ReSync = function(self, val)
resynctime(val)
end
ride.UpdateCam = function(self, val, seat)
if movecam and val == false then
player.Character.Head.Transparency=0
inputserv.MouseIconEnabled = true
for i, p in pairs(player.Character:GetChildren()) do
if p:IsA("Accessory") or p:IsA("Accoutrement") then
p.Handle.Transparency = 0
end
end
handler.IsOnRide = false
end
movecam = val
if not val then
camera.CameraType = "Custom"
else
currentseat = seat
handler.IsOnRide = true
end
end
ride.bind = function(self, name, func)
funcs[name]=func
end
return ride
end
return setup(config.spline, config.start, config.cartmodel, config.cartname, config.trainoffset, config.cartseperation, config.pproperties, config.triggers)
end
return handler
did you try :WaitForChild("One")?
1 Like

now this
What about
[“One”]
This text will be blurred
That’s what it says?,
How about referencing “One” like this:
coaster.Tracks.One instead of using square brackets
Edit: I don’t think it’ll make a difference, but I would try. I’m not that advanced of a script er lol
Oh sorry
This text will be blurred