I have a script that works like this. A player hops in a car, does whatever, but script only activates when the player hops out of the car. The script then sends a RobloxNotification to the player, saying his or her car will despawn within 2-3 minutes if the player (or another player) doesn’t re-claim it. Works pretty well, except for a few issues:
Each time a player hops out of the car, I call a task.spawn() function to begin the countdown independently of the rest of the code. I’d imagine this could cause issues if a player is constantly hopping in and out of the car.
There is an issue where if a player hops out of the car but immediately hops back in, the countdown will not stop. So basically, if a player were to hop out of the car and then back in, the countdown would continue. If the player hopped out of the car again around the three minute mark, the car would despawn in like 2 seconds instead of waiting the normal 3 minutes/180 seconds.
I’m looking for ways to optimize this script and make it so that the countdown stops whenever the car is reclaimed. Here is my script:
local actualVehicle = script.Parent
local seat = actualVehicle.Seat
local proxPrompt = seat.PromptLocation.EndorsedVehicleProximityPromptV1_
local lastDriver = nil
proxPrompt.Triggered:Connect(function(who)
seat:Sit(who.Character.Humanoid)
proxPrompt.Enabled = false
end)
seat:GetPropertyChangedSignal("Occupant"):connect(function()
if seat.Occupant ~= nil then
local Humanoid =seat.Occupant
local Char = Humanoid and Humanoid.Parent
local Player = Char and game.Players:GetPlayerFromCharacter(Char)
if Player then
lastDriver = Player
seat:SetNetworkOwner(Player)
actualVehicle.Parent = Char
Humanoid.Died:Connect(function()
if Player == lastDriver then
game.Debris:AddItem(actualVehicle,2)
end
end)
end
else
proxPrompt.Enabled = true
actualVehicle.Parent = workspace
seat:SetNetworkOwnershipAuto()
task.spawn(function()
--- despawn the plane if no one comes back to get it
local despawnTime = actualVehicle:GetAttribute("despawnTime")
if despawnTime == nil then
despawnTime = 60
end
game.ReplicatedStorage.Remotes.notificationSystem:FireClient(lastDriver,"Vehicle Notification","Your vehicle will despawn in "..despawnTime.." seconds if left unattended.")
task.wait(despawnTime)
if seat.Occupant == nil then
actualVehicle:Destroy()
end
end)
end
end)
Is there a way I could despawn the function seen towards the end?
task.spawn(function()
--- despawn the plane if no one comes back to get it
local despawnTime = actualVehicle:GetAttribute("despawnTime")
if despawnTime == nil then
despawnTime = 60
end
game.ReplicatedStorage.Remotes.notificationSystem:FireClient(lastDriver,"Vehicle Notification","Your vehicle will despawn in "..despawnTime.." seconds if left unattended.")
task.wait(despawnTime)
if seat.Occupant == nil then
actualVehicle:Destroy()
end
end)
The above snippet of code is the problematic line(s), I’d imagine
You could look up coroutines or,
Connect an event to the seat so when someone sits in it they reset the despawnTime attribute, then check for that before destroying it or,
Use a named function when spawning the task, which would allow you to use task.cancel() to stop it.
Could you give me an example of spawning a named function, and then using task.cancel to stop it? I have played around with it before and it only seemed to work when using task.delay. If the there was no “task” running beforehand and I tried cancelling it, it would usually error out the code.
What I was gonna do was do something like this:
local actualVehicle = script.Parent
local seat = actualVehicle.Seat
local proxPrompt = seat.PromptLocation.EndorsedVehicleProximityPromptV1_
local lastDriver = nil
proxPrompt.Triggered:Connect(function(who)
seat:Sit(who.Character.Humanoid)
proxPrompt.Enabled = false
end)
local despawner = function()
task.wait(180)
actualVehicle:Destroy()
end)
seat:GetPropertyChangedSignal("Occupant"):connect(function()
if seat.Occupant ~= nil then
local Humanoid =seat.Occupant
local Char = Humanoid and Humanoid.Parent
local Player = Char and game.Players:GetPlayerFromCharacter(Char)
if Player then
task.cancel(despawner)
lastDriver = Player
seat:SetNetworkOwner(Player)
actualVehicle.Parent = Char
Humanoid.Died:Connect(function()
if Player == lastDriver then
game.Debris:AddItem(actualVehicle,2)
end
end)
end
else
proxPrompt.Enabled = true
actualVehicle.Parent = workspace
seat:SetNetworkOwnershipAuto()
task.spawn(despawner)
end
end)
local actualVehicle = script.Parent
local seat = actualVehicle.Seat
local proxPrompt = seat.PromptLocation.EndorsedVehicleProximityPromptV1_
local lastDriver = nil
local despawnMode = false
local despawnTime = actualVehicle:GetAttribute("despawnTime")
if despawnTime == nil then
despawnTime = 60
end
proxPrompt.Triggered:Connect(function(who)
seat:Sit(who.Character.Humanoid)
proxPrompt.Enabled = false
end)
local despawner = (function()
despawnMode = true
task.wait(despawnTime)
if seat.Occupant == nil then
actualVehicle:Destroy()
end
end)
seat:GetPropertyChangedSignal("Occupant"):connect(function()
if seat.Occupant ~= nil then
local Humanoid =seat.Occupant
local Char = Humanoid and Humanoid.Parent
local Player = Char and game.Players:GetPlayerFromCharacter(Char)
if Player then
if despawnMode == true then
task.cancel(despawner)
despawnMode = false
end
lastDriver = Player
seat:SetNetworkOwner(Player)
actualVehicle.Parent = Char
Humanoid.Died:Connect(function()
if Player == lastDriver then
game.Debris:AddItem(actualVehicle,2)
end
end)
end
else
proxPrompt.Enabled = true
actualVehicle.Parent = workspace
seat:SetNetworkOwnershipAuto()
game.ReplicatedStorage.Remotes.notificationSystem:FireClient(lastDriver,"Vehicle Notification","Your vehicle will despawn in "..despawnTime.." seconds if left unattended.")
task.spawn(despawner)
end
end)
Basically, any time the player leaves, it is supposed to spawn that “despawner” function, which it does. However, when I go back into my vehicle, I get this error:
“:38: invalid argument #1 to ‘cancel’ (thread expected, got function)”