This script controls my loot drops from NPC’s. The loot drops fine, but for some reason it gives an error every time it drops some loot.
while true do -- Loop
wait(.1)
if (script.Parent.Humanoid.Health <=0) then -- If the Enemy dies (Change Enemy to whatever the enemys Humanoid is named)
drop() -- calling the drop function
end
end
The issue is coming from these two lines. Ill attach an error photo regarding line 57, which is the line with drop()
The character or NPC model does not exist, therefore the Humanoid does not exist. Working with Humanoids is a tad tedious, so have that loop check some conditions to ensure the both NPC model exists and the Humanoid exists.
while true do
local character = script.Parent
if not character then
warn(“Did not find the Character!”)
continue
end
local humanoid = character:FindFirstChildOfClass(“Humanoid”)
if not humanoid then
warn(“Did not find the Humanoid!”
continue
end
— do stuff with it
end
if (script.Parent.Humanoid.Health <=0) then -- If the Enemy dies (Change Enemy to whatever the enemys Humanoid is named)
drop() -- calling the drop function
end
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid", 5)
while task.wait() do
if Humanoid.Health <= 0 then
drop()
task.wait(game.Players.RespawnTime - 1)
break
end
end
Your solution timed out and crashed the client for some reason. Here is my entire script so you can have a better idea of what I have. Ignore the mess up top, it is a work in progress and has a lot of testing drops in it. The end is the only part that isnt working.
function drop()
local maths = math.random(1, 6) -- change 6 to however many nothings and tools you have (Right now its a 1 in 6 chance of dropping the tool)
local tool = game.ReplicatedStorage.Tools:FindFirstChild("Goldlow") -- Finding the tool
local nothing = game.ReplicatedStorage.Tools:FindFirstChild("Nothing") -- Finding Nothing
local goldmed = game.ReplicatedStorage.Tools:FindFirstChild("Goldmed")
local gem = game.ReplicatedStorage.Tools:FindFirstChild("Gem")
local goldsound = script.Parent.Tool.Handle.coindrop
local gemsound = script.Parent.Tool.Handle.gemdrop
local healthpotion = game.ReplicatedStorage.Tools:FindFirstChild("Healing Potion")
local potionsound = script.Parent.Tool.Handle.potionsound
if maths == 1 then -- The rest of the lines determin which is chosen
local toolc = tool:Clone()
toolc.Parent = game.Workspace
toolc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0) -- Making the "Tool" Spawn near the Enemy
script:remove()
goldsound:Play()
else if maths == 2 then
local nothingc = nothing:Clone()
nothingc.Parent = game.Workspace
nothingc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0) -- making the "Nothing" Spawn under the map
script:remove()
else if maths == 3 then
local toolc = tool:Clone()
toolc.Parent = game.Workspace
toolc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0)
script:remove()
goldsound:Play()
else if maths == 4 then
local nothingc = nothing:Clone()
nothingc.Parent = game.Workspace
nothingc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0)
script:remove()
else if maths == 5 then
local goldmedc = goldmed:Clone()
goldmedc.Parent = game.Workspace
goldmedc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0) -- (5,4,0)
script:remove()
goldsound:Play()
else if maths == 6 then
local gemc = gem:Clone()
gemc.Parent = game.Workspace
gemc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0) -- (0,-200,0) for nothing under the ground.
script:remove()
gemsound:Play()
end
end
end
end
end
end
end
while task.wait() do
if (script.Parent.Humanoid.Health <=0) then -- If the Enemy dies (Change Enemy to whatever the enemys Humanoid is named)
drop() -- calling the drop function
end
end
You’ve got a lot of stuff going on here to be running this function every step. I recommend this:
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local RunService = game:GetService('RunService')
local tools = ReplicatedStorage:FindFirstChild('Tools')
local tool = tools:FindFirstChild('Goldlow')
local nothing = tools:FindFirstChild('Nothing')
local goldMed = tools:FindFirstChild('Goldmed')
local gem = tools:FindFirstChild('Gem')
local healthPotion = tools:FindFirstChild('Healing Potion')
local scriptTool = script.Parent:FindFirstChild('Tool'):FindFirstChild('Handle')
local goldSound = scriptTool:FindFirstChild('coindrop')
local gemSound = scriptTool:FindFirstChild('gemdrop')
local potionSound = scriptTool:FindFirstChild('potionSound')
function drop()
local maths = math.random(1, 6) -- change 6 to however many nothings and tools you have (Right now its a 1 in 6 chance of dropping the tool)
local characterHead = script.Parent:FindFirstChild('Head')
if not characterHead then
warn("Did not find Character's Head")
return
end
if maths == 1 then -- The rest of the lines determin which is chosen
local toolc = tool:Clone()
toolc.Parent = game.Workspace
toolc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- Making the "Tool" Spawn near the Enemy
goldSound:Play()
script:Destroy()
else
if maths == 2 then
local nothingc = nothing:Clone()
nothingc.Parent = game.Workspace
nothingc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- making the "Nothing" Spawn under the map
script:Destroy()
else
if maths == 3 then
local toolc = tool:Clone()
toolc.Parent = game.Workspace
toolc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0)
goldSound:Play()
script:Destroy()
else
if maths == 4 then
local nothingc = nothing:Clone()
nothingc.Parent = game.Workspace
nothingc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0)
script:Destroy()
else
if maths == 5 then
local goldmedc = goldMed:Clone()
goldmedc.Parent = game.Workspace
goldmedc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- (5,4,0)
goldSound:Play()
script:Destroy()
else
if maths == 6 then
local gemc = gem:Clone()
gemc.Parent = game.Workspace
gemc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- (0,-200,0) for nothing under the ground.
gemSound:Play()
script:Destroy()
end
end
end
end
end
end
end
RunService.Heartbeat:Connect(function()
RunService.RenderStepped.Wait()
local character = script.Parent
if not character then
warn('Did not find Character')
return
end
local humanoid = character:FindFirstChildOfClass('Humanoid')
if not humanoid then
warn('Did not find Humanoid')
return
end
if humanoid.Health <= 0 then
drop()
end
end)
1.) I moved most the object references within the script outside the scope of the the drop() function so that they aren’t being re-referenced everytime the function is run. This should result in minimal performance increase.
2.) Instead of using while true do on the client, you can use connect a callback to RunService.Heartbeat and check your conditions then. When scripting server-side, it’s not the worst idea to use a while true loop sometimes, but on the client, it’s much nicer to utilize the RunService Service.
Other than some other minor changes to your script, I think those two are the most important. I don’t see anything in the script block I’ve changed for you that should cause any issues for you at all. There could be some improvements to the conditions being ran within the drop function, but those wouldn’t necessarily impact your performance, they’d just make the script nicer lol
So I plugged this script in to test and it caused a infinite loop of errors that made the game run extremely laggy. I was not able to test the actual drops because the error would not let it get that far. Ill attach a photo.
script.Parent.Humanoid.Died:Connect(function()
function drop()
local maths = math.random(1, 6) -- change 6 to however many nothings and tools you have (Right now its a 1 in 6 chance of dropping the tool)
local tool = game.ReplicatedStorage.Tools:FindFirstChild("Goldlow") -- Finding the tool
local nothing = game.ReplicatedStorage.Tools:FindFirstChild("Nothing") -- Finding Nothing
local goldmed = game.ReplicatedStorage.Tools:FindFirstChild("Goldmed")
local gem = game.ReplicatedStorage.Tools:FindFirstChild("Gem")
local goldsound = script.Parent.Tool.Handle.coindrop
local gemsound = script.Parent.Tool.Handle.gemdrop
local healthpotion = game.ReplicatedStorage.Tools:FindFirstChild("Healing Potion")
local potionsound = script.Parent.Tool.Handle.potionsound
if maths == 1 then -- The rest of the lines determin which is chosen
local toolc = tool:Clone()
toolc.Parent = game.Workspace
toolc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0) -- Making the "Tool" Spawn near the Enemy
goldsound:Play()
else if maths == 2 then
local nothingc = nothing:Clone()
nothingc.Parent = game.Workspace
nothingc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0) -- making the "Nothing" Spawn under the map
else if maths == 3 then
local toolc = tool:Clone()
toolc.Parent = game.Workspace
toolc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0)
goldsound:Play()
else if maths == 4 then
local nothingc = nothing:Clone()
nothingc.Parent = game.Workspace
nothingc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0)
else if maths == 5 then
local goldmedc = goldmed:Clone()
goldmedc.Parent = game.Workspace
goldmedc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0) -- (5,4,0)
goldsound:Play()
else if maths == 6 then
local gemc = gem:Clone()
gemc.Parent = game.Workspace
gemc.CFrame = script.Parent.Head.CFrame + Vector3.new(5,4,0) -- (0,-200,0) for nothing under the ground
gemsound:Play()
end
end
end
end
end
end
end
drop()
script:Destroy()
end)
Might’ve made a typo. Try replacing the detecting part with this.
It detects when the humanoid dies instead of checking every second.
Another method of course would be to connect to the .Died event on the Humanoid as @Redluo suggested.
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local tools = ReplicatedStorage:FindFirstChild('Tools')
local tool = tools:FindFirstChild('Goldlow')
local nothing = tools:FindFirstChild('Nothing')
local goldMed = tools:FindFirstChild('Goldmed')
local gem = tools:FindFirstChild('Gem')
local healthPotion = tools:FindFirstChild('Healing Potion')
local scriptTool = script.Parent:FindFirstChild('Tool'):FindFirstChild('Handle')
local goldSound = scriptTool:FindFirstChild('coindrop')
local gemSound = scriptTool:FindFirstChild('gemdrop')
local potionSound = scriptTool:FindFirstChild('potionSound')
function drop()
local maths = math.random(1, 6) -- change 6 to however many nothings and tools you have (Right now its a 1 in 6 chance of dropping the tool)
local characterHead = script.Parent:FindFirstChild('Head')
if not characterHead then
warn("Did not find Character's Head")
return
end
if maths == 1 then -- The rest of the lines determin which is chosen
local toolc = tool:Clone()
toolc.Parent = game.Workspace
toolc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- Making the "Tool" Spawn near the Enemy
goldSound:Play()
script:Destroy()
else
if maths == 2 then
local nothingc = nothing:Clone()
nothingc.Parent = game.Workspace
nothingc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- making the "Nothing" Spawn under the map
script:Destroy()
else
if maths == 3 then
local toolc = tool:Clone()
toolc.Parent = game.Workspace
toolc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0)
goldSound:Play()
script:Destroy()
else
if maths == 4 then
local nothingc = nothing:Clone()
nothingc.Parent = game.Workspace
nothingc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0)
script:Destroy()
else
if maths == 5 then
local goldmedc = goldMed:Clone()
goldmedc.Parent = game.Workspace
goldmedc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- (5,4,0)
goldSound:Play()
script:Destroy()
else
if maths == 6 then
local gemc = gem:Clone()
gemc.Parent = game.Workspace
gemc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- (0,-200,0) for nothing under the ground.
gemSound:Play()
script:Destroy()
end
end
end
end
end
end
end
local humanoid = script.Parent:FindFirstChildOfClass('Humanoid')
assert(humanoid, string.format('Failed to get Humanoid for "%s" character.', script.Parent.Name + "'s"))
humanoid.Died:Connect(drop)
could also cut out the redundant wall of elseif statements with a table lol
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local tools = ReplicatedStorage:FindFirstChild('Tools')
local tool = tools:FindFirstChild('Goldlow')
local nothing = tools:FindFirstChild('Nothing')
local goldMed = tools:FindFirstChild('Goldmed')
local gem = tools:FindFirstChild('Gem')
local healthPotion = tools:FindFirstChild('Healing Potion')
local scriptTool = script.Parent:FindFirstChild('Tool'):FindFirstChild('Handle')
local goldSound = scriptTool:FindFirstChild('coindrop')
local gemSound = scriptTool:FindFirstChild('gemdrop')
local potionSound = scriptTool:FindFirstChild('potionSound')
local Sounds = {
[1] = goldSound,
[3] = goldSound,
[5] = goldSound,
[6] = gemSound
}
local ItemDrops = {
[1] = tool,
[2] = nothing,
[3] = tool,
[4] = nothing,
[5] = goldMed,
[6] = gem
}
function drop()
local maths = math.random(1, 6) -- change 6 to however many nothings and tools you have (Right now its a 1 in 6 chance of dropping the tool)
local characterHead = script.Parent:FindFirstChild('Head')
if not characterHead then
warn("Did not find Character's Head")
return
end
local Item = ItemDrops[maths]:Clone() --grabs the item from its index in the item table rather than using a huge elseif statement lol
local Sound = Sounds[maths] --grabs the correlating sound from its index in the sound table, if it exists
Item.Parent = workspace
Item.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0)
if Sound then --if the item has a special sound, play it
Sound:Play()
end
script:Destroy()
--[[if maths == 1 then -- The rest of the lines determin which is chosen
local toolc = tool:Clone()
toolc.Parent = game.Workspace
toolc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- Making the "Tool" Spawn near the Enemy
goldSound:Play()
script:Destroy()
else
if maths == 2 then
local nothingc = nothing:Clone()
nothingc.Parent = game.Workspace
nothingc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- making the "Nothing" Spawn under the map
script:Destroy()
else
if maths == 3 then
local toolc = tool:Clone()
toolc.Parent = game.Workspace
toolc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0)
goldSound:Play()
script:Destroy()
else
if maths == 4 then
local nothingc = nothing:Clone()
nothingc.Parent = game.Workspace
nothingc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0)
script:Destroy()
else
if maths == 5 then
local goldmedc = goldMed:Clone()
goldmedc.Parent = game.Workspace
goldmedc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- (5,4,0)
goldSound:Play()
script:Destroy()
else
if maths == 6 then
local gemc = gem:Clone()
gemc.Parent = game.Workspace
gemc.CFrame = characterHead.CFrame + Vector3.new(5, 4, 0) -- (0,-200,0) for nothing under the ground.
gemSound:Play()
script:Destroy()
end
end
end
end
end
end]]
end
local humanoid = script.Parent:FindFirstChildOfClass('Humanoid')
assert(humanoid, string.format('Failed to get Humanoid for "%s" character.', script.Parent.Name + "'s"))
humanoid.Died:Connect(drop)
Haha ok ok I got a lot to go over here. Thanks I will check these suggestions out after I get off work. It’s not too much spoon feeding, I take the time to really get into what I am learning and seeing. This is beyond my comfort zone and I can feel my brain expanding. It’s slightly painful haha.