First off, please put code in a code block — either wrap it in these:
```
your code here
```
or paste your code, select it and press the button with the </> on it. (You should’ve learned this in the devforum introduction with the bot)
As for the code itself:
local spawner = script.Parent
local tool = nil
local region = Region3.new(
Vector3.new(spawner.Position.X - spawner.Size.X/2, spawner.Position.Y + spawner.Size.Y/2, spawner.Position.Z - spawner.Size.Z/2),
Vector3.new(spawner.Position.X + spawner.Size.X/2, spawner.Position.Y + 4, spawner.Position.Z + spawner.Size.Z/2)
)
local parts = game.Workspace:FindPartsInRegion3(region)
for _, part in pairs(parts) do
if part and part.Parent and part.Parent:IsA("Tool") then
tool = part.Parent
break
end
end
This code will look for any Tool that’s on top of the spawner.
Specifically, it will get all parts in the area spanned by the part (and a little above it), then look for one of these parts which is directly inside a Tool.
local configTable = spawner.Configurations
local configs = {}
local function loadConfig(configName, defaultValue)
if configTable:FindFirstChild(configName) then
configs[configName] = configTable:FindFirstChild(configName).Value
else
configs[configName] = defaultValue
end
end
loadConfig("SpawnCooldown", 5)
loadConfig()
is an overly fancy function to look for a configurable value in the tool with a default value.
So if your spawner has a folder named Configurations inside it, and a value inside that named SpawnCooldown, then its value will be the cooldown for spawning something. If it’s missing, then the cooldown will be 5.
Afterward, you can get the value of SpawnCooldown with configs["SpawnCooldown"]
.
I think this function is rather pointless if it’s being used for only one thing.
if tool then
tool.Parent = game.ServerStorage
If no tool was found, do nothing at all.
Otherwise, move the tool somewhere where players can’t just brush up against it and pick it up.
while true do
-- put tool on pad
local toolCopy = tool:Clone()
toolCopy.Parent = game.Workspace
Pretty self-explanatory.
Place a clone of the tool where it was in the world, waiting to be picked up.
local toolOnPad = true
local parentConnection
local handle = toolCopy:FindFirstChild("Handle")
parentConnection = toolCopy.AncestryChanged:connect(function()
if handle then handle.Anchored = false end
toolOnPad = false
parentConnection:disconnect()
end)
When the tool is picked up, change the toolOnPad
variable (which something below this is waiting for). In addition, unanchor the tool so that the player can move it.
parentConnection:disconnect()
is there so that this code doesn’t run more than once.
if handle then
handle.CFrame = (spawner.CFrame + Vector3.new(0,handle.Size.Z/2 + 1,0)) * CFrame.Angles(-math.pi/2,0,0)
handle.Anchored = true
end
OK, I lied. The tool isn’t placed exactly where it was before - this part puts it on top of the spawner.
It also anchors the tool so that it doesn’t roll off on its own.
-- wait for tool to be removed
while toolOnPad do
if handle then
handle.CFrame = handle.CFrame * CFrame.Angles(0,0,math.pi/60)
end
wait()
end
Wait for the tool to be removed. Also spin the tool around.
Note that the tool might be being rotated around the Z-axis, which might work for the specific tool this was made for, but not others.
-- wait for cooldown
wait(configs["SpawnCooldown"])
Wait a short time before spawning another tool.
Rewritten script
-- You can change this
local cooldown = 5
local RunService = game:GetService("RunService")
local spawner = script.Parent
local tool
-- Find the tool resting on top of the spawner
-- BUG: Ignores spawner's orientation
local parts = game.Workspace:FindPartsInRegion3(Region3.new(
spawner.Position - spawner.Size / 2,
spawner.Position + spawner.Size / 2 + Vector3.new(0, 4, 0)
))
for _, part in ipairs(parts) do
if part.Parent:IsA("Tool") then
tool = part.Parent
break
end
end
-- note: if tool is missing, then this will throw an error
-- which is GOOD, it will still do nothing in a live game,
-- but this time it rudely notifies you when there's a spawner that's doing nothing
-- unfortunately, this rewrite of the script doesn't deal with a tool that has no handle,
-- because if the tool doesn't spin and stay where it is, what's the point?
assert(tool, "No tool found above a tool spawner")
assert(tool:FindFirstChild("Handle"), "Tool has no handle")
tool.Parent = game.ServerStorage
while true do
local toolCopy = tool:Clone()
local handle = toolCopy.Handle
local spinConnection
-- put tool on pad
toolCopy.Parent = game.Workspace
handle.CFrame = (spawner.CFrame + Vector3.new(0, handle.Size.Z/2 + 1, 0)) * CFrame.Angles(-math.pi/2, 0, 0)
handle.Anchored = true
-- spin the handle
spinConnection = RunService.Stepped:Connect(function(t, dt)
handle.CFrame = handle.CFrame * CFrame.Angles(0, 0, math.pi * dt)
end)
-- wait for the tool to be removed
toolCopy.AncestryChanged:Wait()
-- clean up
handle.Anchored = false
spinConnection:Disconnect()
-- wait for cooldown
wait(cooldown)
end
(Untested)