Car spawner problem

Hello people, so i have been trying to fix my car spawning scripts for some time now and havent been able to, i keep running into bugs where for example: Car spawns in the wrong place, UI doesnt open or the car just does not spawn. Here is my code

Serverscript:

local SpawnCarEvent = game:GetService("ReplicatedStorage"):WaitForChild("Remotes").SpawnCar
local CarsInGame = workspace.CarsIngame

local Spawner = nil

for i, spawner in pairs(workspace:GetDescendants()) do
	if spawner:IsA("Model") and spawner.Name == "Spawner" then
		local PClone = script.SpawnPrompt:Clone()
		PClone.Parent = spawner:FindFirstChild("Select")
		
		Spawner = spawner
	end
end

local function SpawnVehicle(Player, Vehicle)
	if Vehicle then
		--If the player has any old cars
		for i, oldcar in pairs(CarsInGame:GetChildren()) do
			if oldcar:IsA("Model") then
				if oldcar.Name == Player.Name then
					oldcar:Destroy()
				end
			end
		end
		
		--Wait a nanosecond so if the player has more than 1 car, the script deletes them when they try to spawn a new one
		task.wait()
		
		local ClonedVehicle = Vehicle:Clone()
		ClonedVehicle.Name = Player.Name
			ClonedVehicle.Parent = CarsInGame
		ClonedVehicle:MoveTo(Spawner.SpawnPos.Position)
	end
end

local function OnPlayerLeave(Player)
	if CarsInGame:FindFirstChild(Player.Name) then
		CarsInGame:FindFirstChild(Player.Name):Destroy()
	else
		return
	end
end

game.Players.PlayerRemoving:Connect(OnPlayerLeave)
SpawnCarEvent.OnServerEvent:Connect(SpawnVehicle)

Local script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SpawnCarEvent = ReplicatedStorage.Remotes.SpawnCar
local Vehicles = ReplicatedStorage:WaitForChild("Cars")
local SelectionFrame = script.Parent.Selection
local UITemplate = ReplicatedStorage:WaitForChild("Templates").Template

-- Add a button for every spawnable vehicle
for i, vehicleModel in pairs(Vehicles:GetChildren()) do
	if vehicleModel:IsA("Model") and vehicleModel:FindFirstChildOfClass("VehicleSeat") then
		local NewUI = UITemplate:Clone()
		NewUI.Parent = SelectionFrame
		NewUI.Name = vehicleModel.Name
		NewUI.Text = vehicleModel.Name

		NewUI.MouseButton1Up:Connect(function()
			local chosenVehicle = Vehicles:FindFirstChild(NewUI.Name)	
			SpawnCarEvent:FireServer(chosenVehicle)

			script.Parent.Enabled = false
		end)
	end
end

-- Make vehicle selection UI visible when the player triggers the prompt
for i, spawner in pairs(workspace:GetDescendants()) do
	if spawner:IsA("Model") and spawner.Name == "Spawner" then
		local selectFolder = spawner:FindFirstChild("Select") or spawner:WaitForChild("Select")
		if selectFolder and selectFolder:FindFirstChildOfClass("ProximityPrompt") then
			local prompt = selectFolder:FindFirstChildOfClass("ProximityPrompt")

			prompt.Triggered:Connect(function(plr)
				if script.Parent.Enabled == false then
					script.Parent.Enabled = true
				else
					script.Parent.Enabled = false
				end
			end)
		end
	end
end


Heres a picture of the explorer window:

When the code does not work, you print a thing, stare at the thing for 10 minutes, and then eventually fix the problem.

Basically just debug.

2 Likes

Already have done that for like 3h but still cant find the issue :frowning:

1 Like

damn that’s crazy

Unfortunately, that’s the only thing you can do.
Put prints EVERYWHERE and print EVERYTHING, down to the indexes.

I do have something to say, in your local script, DO NOT REFERENCE CHILDREN VIA PERIODS. ALWAYS USE :WaitForChild(). That can be the issue.

2 Likes

Alright ill try that, thank you!

1 Like

When referencing instances in ReplicatedStorage, ServerStorage, etc. from a server side Script you do not need to use :WaitForChild() because the replication is done from server to clients and not server to server which means that when the server starts it will already have all assets ready.

This is inefficient, consider using CollectionService and retrieve all spawners by using CollectionService:GetTagged("CarSpawner") and tag all car spawners CarSpawner through the properties window. Anyway why would this be necessary if you are setting the Spawner variable which can only hold one spawner?

Avoid using so similar variable names.

This is unsafe, you are cloning whatever the player is passing as argument to the RemoteEvent, which if the player is using exploits will cause errors.

If SpawnVehicle() is the only function that spawns vehicles, this is redundant since you can just use

local oldCar = CarsInGame:FindFirstChild(player.Name)

if oldCar then
    oldCar:Destroy()
end

This is redundant

Corrected server script:

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CarsInGame: Folder -- Looks like you are using a folder

local Spawner -- Set a reference to the vehicles spawner

local function SpawnVehicle(player: Player, vehicleName: string)
    -- Check if the server received a the name of a valid vehicle

    local targetVehicle = ReplicatedStorage.Cars:FindFirstChild(vehicleName)

    if not targetVehicle then
        -- Server received invalid vehicle name, player might be exploiting or there is a bug on the client side
        return
    end

    -- Destroy the player's previous vehicle

    local oldVehicle = CarsInGame:FindFirstChild(player.Name)

    if oldVehicle then
        oldVehicle:Destroy()
    end

    -- Spawn the new car

    local newVehicle: Model = targetVehicle:Clone()
    newVehicle.Name = player.Name
    newVehicle.Parent = CarsInGame
    newVehicle:PivotTo(CFrame.new(Spawner.SpawnPos.Position))
end

local function OnPlayerLeave(player)
    local playerVehicle = CarsInGame:FindFirstChild(player.Name)

    if playerVehicle then
        playerVehicle:Destroy()
    end
end

SpawnCarEvent.OnServerEvent:Connect(SpawnVehicle)
Players.PlayerRemoving:Connect(OnPlayerLeave)

It seems the issue is in the LocalScript. Are there any errors in the output?

1 Like

How should i go about making the Clone() part safer? And also using the collectionservice correctly? So my problem which i actually managed to fix a few minutes ago was that, i had 3 spawners, and when i spawned a car on one of them, it spawned, but when i walked to another spawner and spawned a car, it spawned in the previous spawner.

Heres my updated code, tell me what to change if needed:

Serverscript:

local CollectionService = game:GetService("CollectionService")

local SpawnCarEvent = game.ReplicatedStorage.Remotes.SpawnCar
local CarsInGame = workspace.CarsIngame

local Spawner = nil

for i, spawner in pairs(workspace:GetDescendants()) do
	if spawner:IsA("Model") and spawner.Name == "Spawner" then
		local PClone = script.SpawnPrompt:Clone()
		PClone.Parent = spawner:FindFirstChild("Select")
		
		Spawner = spawner
	end
end

local function SpawnVehicle(Player, Vehicle)
	if Vehicle then

		--If the player has any old cars
		local oldCar = CarsInGame:FindFirstChild(Player.Name)

		if oldCar then
			oldCar:Destroy()
		end
		
		--Wait a nanosecond so if the player has more than 1 car, the script deletes them when they try to spawn a new one
		task.wait()
		
		local ClonedVehicle = Vehicle:Clone()
		ClonedVehicle.Name = Player.Name
		ClonedVehicle.Parent = CarsInGame
		
		
		--This part is in progress, gonna make it so that the car is a bit farther away from the spawner and is also facing it with its side
		--Rotate the model to face the spawner with its left side
	end
end

local function OnPlayerLeave(Player)
	if CarsInGame:FindFirstChild(Player.Name) then
		CarsInGame:FindFirstChild(Player.Name):Destroy()
	end
end

game.Players.PlayerRemoving:Connect(OnPlayerLeave)
SpawnCarEvent.OnServerEvent:Connect(SpawnVehicle)

Localscript:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SpawnCarEvent = ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("SpawnCar")
local Vehicles = ReplicatedStorage:WaitForChild("Cars")
local SelectionFrame = script.Parent:WaitForChild("Selection")
local UITemplate = ReplicatedStorage:WaitForChild("Templates"):WaitForChild("Template")

-- Make vehicle selection UI visible when the player triggers the prompt
for i, spawner in pairs(workspace:GetDescendants()) do
	if spawner:IsA("Model") and spawner.Name == "Spawner" then
		local selectFolder = spawner:FindFirstChild("Select") or spawner:WaitForChild("Select")
		if selectFolder and selectFolder:FindFirstChildOfClass("ProximityPrompt") then
			local prompt = selectFolder:FindFirstChildOfClass("ProximityPrompt")

			prompt.Triggered:Connect(function(plr)
				if script.Parent.Enabled == false then
					script.Parent.Enabled = true
				else
					script.Parent.Enabled = false
				end
			end)
		end
	end
end


-- Add a button for every spawnable vehicle
for i, vehicleModel in pairs(Vehicles:GetChildren()) do
	if vehicleModel:IsA("Model") and vehicleModel:FindFirstChildOfClass("VehicleSeat") then
		local NewUI = UITemplate:Clone()
		NewUI.Parent = SelectionFrame
		NewUI.Name = vehicleModel.Name
		NewUI.Text = vehicleModel.Name

		NewUI.MouseButton1Up:Connect(function()
			local chosenVehicle = Vehicles:FindFirstChild(NewUI.Name)	
			SpawnCarEvent:FireServer(chosenVehicle)

			script.Parent.Enabled = false
		end)
	end
end

And also, thank you so much!



Collection service helps you organize your instances by grouping them with tags. Think of it like a sorting function on a website that has blog articles and help articles listed together. CollectionService would group the articles in Blog and Help.

By using CollectionService you don’t have to use for loops to find specific instances among mixed ones to filter out those that don’t meet a condition. If you tag all your car spawners CarSpawner, in your script you can then do

local spawners = CollectionService:GetTagged("CarSpawner")

and when a player spawns a car you can loop through the spawners array, find the one closest to the player and spawn the car there.

2 Likes

Alright thank you so much bro! :slightly_smiling_face:

2 Likes

Also one last question, how do i make it so that when the car is spawned, it always is about 15 studs away from the spawner and is facing it with its left side no matter the position or orientation of the spawner?

edit: forgot to say that i removed the spawnpos part too

This is how the spawners look like:

2 Likes

What you want to do is first make the car look with its front face at the spawner so that then you will know how much to rotate it to make it look at the spawner with its left face.

Here’s a link to a documentation section that explain specifically that:

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.