I have tried multiple different methods but none have worked correctly.
How would I implement a system that uses breakCart() if the cart has not been sat in within 20 seconds, and if a player does not jump back into the cart after 15 seconds?
--!strict
local Players = game:GetService("Players")
local SoundEffects = require(script:WaitForChild("SoundEffects"))
local ParticleEffects = require(script:WaitForChild("ParticleEffects"))
local getStatus = require(script:WaitForChild("getStatus"))
local breakCart = require(script:WaitForChild("breakCart"))
local setupCollisionGroups = require(script:WaitForChild("setupCollisionGroups"))
local Coupling = require(script:WaitForChild("Coupling"))
local Cart = script.Parent
local Throttle = script:WaitForChild("Throttle")
local Base = Cart:WaitForChild("Base")
local Motors = Base:WaitForChild("Motors"):GetChildren()
local Seat = Cart:WaitForChild("Seat") :: Seat
local Buttons = Cart:WaitForChild("Buttons")
local CurrentPlayer: Player? = nil
-- They may not be set up already
setupCollisionGroups()
local function occupantIsPlayer(player: Player): boolean
local occupant = Seat.Occupant
if occupant then
return occupant.Parent == player.Character
end
return false
end
script.SetThrottle.OnServerEvent:Connect(function(player: Player, throttle)
if occupantIsPlayer(player) and type(throttle) == 'number' then
Throttle.Value = math.clamp(throttle, -1.0, 1.0)
end
end)
Buttons:WaitForChild("Stop"):WaitForChild("ClickDetector").MouseClick:Connect(function(player)
Throttle.Value = 0
end)
Buttons:WaitForChild("Start"):WaitForChild("ClickDetector").MouseClick:Connect(function(player)
if Throttle.Value == 0 then
Throttle.Value = 0.8
elseif math.abs(Throttle.Value) <= 0.2 then
Throttle.Value = math.sign(Throttle.Value) * 0.8
end
end)
Buttons:WaitForChild("Decouple"):WaitForChild("ClickDetector").MouseClick:Connect(function(player)
Coupling.decouple()
end)
local LocalCartUI = script:WaitForChild("LocalCartUI")
function setup(player: Player)
local playerGui = player:FindFirstChild("PlayerGui") :: PlayerGui
if not playerGui:FindFirstChild("LocalCartUI") then
local localScript = LocalCartUI:Clone()
localScript.Disabled = false
localScript.Parent = playerGui
end
end
function teardown(player: Player)
end
Seat:GetPropertyChangedSignal("Occupant"):Connect(function()
if CurrentPlayer then
teardown(CurrentPlayer)
end
CurrentPlayer = nil
local currentOccupant = Seat.Occupant
if currentOccupant then
CurrentPlayer = Players:GetPlayerFromCharacter(currentOccupant.Parent)
end
if CurrentPlayer then
setup(CurrentPlayer)
end
end)
local function slowDownIfNoOccupant(dt)
-- Slow down if nobody is riding
if not Seat.Occupant then
local decay = 0.01 * dt
if math.abs(Throttle.Value) < decay then
Throttle.Value = 0
else
Throttle.Value -= math.sign(Throttle.Value) * decay
end
end
end
local lastPosition = Base.Position
local iteration = math.random(1, 100)
while true do
local dt = task.wait()
local shouldPlaySounds = script:GetAttribute("PlaySounds")
-- Only do the raycasts every 4th frame
iteration += 1
if iteration % 4 == 0 then
local isOnTrack, expired = getStatus(script:GetAttribute("DespawnAfter"))
if not isOnTrack and shouldPlaySounds then
SoundEffects.stopSounds()
end
if expired then
breakCart()
break
end
end
local thisPosition = Base.Position
SoundEffects.movedBy((lastPosition - thisPosition).Magnitude)
lastPosition = thisPosition
local velocity = Base.AssemblyLinearVelocity.Magnitude
local screeching = ParticleEffects.updateSparks(velocity)
if shouldPlaySounds then
SoundEffects.playSounds(dt, velocity, screeching)
end
slowDownIfNoOccupant(dt)
-- Apply the calculated throttle
for _, motor in ipairs(Motors) do
motor.AngularVelocity = -script:GetAttribute("MaxSpeed") * Throttle.Value
motor.MotorMaxTorque = 10000 * math.abs(Throttle.Value)^2
end
end