So I have a zombie NPC, right. It's already scripted and all, and everything (seems to) work fine. It follows the player, it takes/does damage, it dies, it respawns, blah blah bah. It does everything I need it to.
Yet when I test this in-game, the output has an error saying "Workspace.Zombies.Zombie.Respawn:7: attempt to index field 'Parent' (a nil value)". Now, 'Zombies' is the group/model that the zombie model is inside. It's the second parent in "script.Parent.Parent" referenced in line 9 of the script I'm going to show you. It says it's nil, yet it's there. What is causing this? To my understanding, nil means nonexistent. Can somebody explain what's going on?
Script below:
name="Zombie" robo=script.Parent:clone() while true do wait(5) if script.Parent.ZombieHealth.Health<1 then robot=robo:clone() robot.Parent=script.Parent.Parent robot:makeJoints() script.Parent:remove() end end
EDIT: Here is a section in the gun script that seems to have an issue with the first solution. Note that I need to keep the gun's script completely as-is, any changes need to happen within the zombie's respawn script. The gun is raycast.
if hit~=nil then if hit.Parent:FindFirstChild("VecHealth")~=nil then vech=hit.Parent:FindFirstChild("VecHealth") vech.Value=vech.Value-VehicleDamage print("Vech") end if hit.Parent:FindFirstChild("HealthStatus")~=nil then local fo=hit.Parent:FindFirstChild("HealthStatus") fo.Value=fo.Value-BaseDamage print("healthstatus") end local humanoid=hit.Parent:FindFirstChild("ZombieHealth") if humanoid~=nil then local ho=humanoid ho.Health=ho.Health-BaseDamage end if hit.Parent.Parent:FindFirstChild("HealthStatus")~=nil then local go=hit.Parent.Parent:FindFirstChild("HealthStatus") go.Value=go.Value-BaseDamage print("healthstatus") end local humanoid=hit.Parent:FindFirstChild("Humanoid") if humanoid~=nil then local eplr=game.Players:playerFromCharacter(humanoid.Parent) local plr=game.Players:playerFromCharacter(thetool.Parent) if eplr~=nil and plr~=nil then if plr.TeamColor ~= eplr.TeamColor then local damage=math.random(BaseDamage-(BaseDamage*.25),BaseDamage+(BaseDamage*.25)) tagHumanoid(humanoid) if hit.Name=="Head" then damage=damage*2 print("headshot") humanoid:takeDamage(damage) elseif hit.Name=="Torso" then print("torsoshot") damage=damage*1 humanoid:takeDamage(damage) else print("shot") damage=damage*.75 humanoid:takeDamage(damage) end end end end
It appears as that although you removed the script's Parent (which should be done using the Destroy
method instead of Remove
), the script isn't getting garbage collected and the loop continues to execute until the script terminates (in this case by throwing an error). My guess is that a reference to this script is getting set somewhere and therefore continues to persist, but I'm not really sure why (maybe someone else can give their two cents?).
You can fix the error simply by breaking out of the loop after removing the old Zombie model.
local robot =script.Parent:Clone() while true do wait(5) if script.Parent.ZombieHealth.Health < 1 then robot:MakeJoints() robot.Parent = script.Parent.Parent script.Parent:Destroy() break -- This will get rid of your error end end
However, this isn't a very efficient solution to accomplish what you want. It would be better to check the Zombie's health only when it is actually changed (instead of every 5 seconds).
Assuming that 'ZombieHealth' is a humanoid instance:
local robo=script.Parent:clone() local humanoid = script.Parent.ZombieHealth humanoid.HealthChanged:connect(function(health) if script.Parent.ZombieHealth.Health < 1 then robot:MakeJoints() robot.Parent = script.Parent.Parent script.Parent:Destroy() end end)