I’m wanting to make a Delivery System. My first main issue is that I want the vehicle to spawn in a free area. So if there are 3 points and 2 points have other players vehicles on them I want the vehicle to spawn on the point which has no other vehicles. Basically a free spawn point for the vehicle.
My issue is that I don’t know how to find the available point.
Spawning Vehicle:
local VehC = game:GetService('ServerStorage').Veh
VehC.Parent = game.Workspace
VehC:MoveTo(workspace.DeliveryTruckSpawns.Part.Position) -- This would be the available spawn point
I have looked at posts regarding Region3 but I didn’t understand them a single bit, so I’m hoping to get some more help by making a post about the specific issue.
Hi, First of all, You can create a value inside the already spawned points for a little debounce (such as boolvalues, if outside of script) and then loop through all the spawn points to see which one doesn’t have the value.
You can replace the ‘v’ with whatever you basically want since it’s the name of the thing that was last checked. So, let’s say you name it “SpawnChecked” for now. You can then do:
local ValueCheck = SpawnChecked:FindFirstChild("Tag") -- Check for already made value.
if ValueCheck == nil and ValueCheck.Value == false then -- If there's no value, make.
local ValueCheck = Instance.new("BoolValue", SpawnChecked)
ValueCheck.Name = "Tag"
ValueCheck.Value = true
-- Spawn car.
end
Works perfectly, expect the vehicle spawns at all the points, as well makes the BoolValue Tag to all of them as well.
local VehC = game:GetService('ServerStorage').Veh:Clone()
VehC.Parent = game.Workspace
VehC:MoveTo() -- What point would it move to? ValueCheck.Parent.Position?
for _, SpawnChecked in pairs(workspace.DeliveryTruckSpawns:GetChildren()) do
local ValueCheck = SpawnChecked:FindFirstChild("Tag") -- Check for already made value.
if ValueCheck == nil then -- If there's no value, make.
local ValueCheck = Instance.new("BoolValue", SpawnChecked)
ValueCheck.Name = "Tag"
ValueCheck.Value = true
local VehC = game:GetService('ServerStorage').Veh:Clone()
VehC.Parent = game.Workspace
VehC:MoveTo(ValueCheck.Parent.Position)
end
end
Looking around it seems that none of the posts were detailed and use the new SpatialQuery like this one though it is on the right track using region 3.
Plus I will also have to do something similar for my game so here is my shot at it, make sure to modify the if condition which checks the models name for an occupied part.
--Change this within the below code with your own condition
if model.Name == "NameOfCar" then --Check the name of the model if it is another car, make sure to change here
return true
end
local function checkSpawnPointIsOccupied(spawnPart)
local cframeLocationCheck = spawnPart.CFrame
local sizeOfLocationCheck = spawnPart.Size*Vector3.new(1,10,1) --Modify the size if you want
local filter = {}
for i, player in pairs(game:GetService("Players"):GetPlayers()) do
local character = player.Character
table.insert(filter, character) --Get all player characters to filter out
end
table.insert(spawnPart)
local query = OverlapParams.new()
query.FilterDescendantsInstances = filter
query.FilterType = Enum.RaycastFilterType.Blacklist
local parts = workspace:GetPartBoundsInBox(spawnPart.CFrame, sizeOfLocationCheck, query)
local regionVisualizer = Instance.new("Part") --Part to visualize workspace only
regionVisualizer.CFrame = cframeLocationCheck
regionVisualizer.Size = sizeOfLocationCheck
regionVisualizer.Anchored = true
regionVisualizer.Transparency = 0.5
regionVisualizer.CastShadow = false
regionVisualizer.CanCollide = false
regionVisualizer.Parent = workspace
game:GetService("Debris"):AddItem(regionVisualizer, 0.5)
for _, part : BasePart in pairs(parts) do
if part.Locked == true then
--Skip locked parts like baseplate
continue
end
local model = part:FindFirstAncestorOfClass("Model") --See if part belongs to a car model.
if model.Name == "NameOfCar" then --Check the name of the model if it is another car, make sure to change here
return true
end
end
return false
end
local spawnPoints = workspace.SpawnPoints:GetChildren()
local spawnedSuccess = false
for _, spawnPointPart in pairs(spawnPoints) do
local isOccupied = checkSpawnPointIsOccupied(spawnPointPart)
if isOccupied then
continue --Keep searching
else
--Not occupied can spawn car here
local VehC = game:GetService('ServerStorage').Veh:Clone()
VehC.Parent = game.Workspace
VehC:MoveTo(spawnPointPart.Position)
spawnedSuccess = true
break --stop for loop searching for non occupied spawn points
end
end
if spawnedSuccess == false then
warn("All spawn points are full! :(")
end
Oh, my bad…! I just realised the big mistake. I’m pretty sure you can break the looping by simply putting break after you spawn the car. (Haven’t tested it.)
I added the break to stop it going to them all which fixed it but it still adds the “Tag” Value to all of the points.
for _, SpawnChecked in pairs(workspace.DeliveryTruckSpawns:GetChildren()) do
local ValueCheck = SpawnChecked:FindFirstChild("Tag") -- Check for already made value.
if ValueCheck == nil then -- If there's no value, make.
local ValueCheck = Instance.new("BoolValue")
ValueCheck.Name = "Tag"
ValueCheck.Value = true
local VehC = game:GetService('ServerStorage').Veh:Clone()
VehC.Parent = game.Workspace
ValueCheck.Parent = SpawnChecked
VehC:MoveTo(ValueCheck.Parent.Position)
break
end
end
No, no. Just add bool values and keep the values off. Then change the if ValueCheck == nil then to if SpawnChecked.Value == false then, And also delete the instance.
for _, SpawnChecked in pairs(workspace.DeliveryTruckSpawns:GetChildren()) do
local ValueCheck = SpawnChecked:FindFirstChild("Tag") -- Check for already made value.
if SpawnChecked.Tag.Value == false then -- If there's no value, make.
local VehC = game:GetService('ServerStorage').Veh:Clone()
VehC.Parent = game.Workspace
SpawnChecked.Tag.Value = true
VehC:MoveTo(SpawnChecked.Position)
break
end
end