Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why does this zombie script only target a single player?

#The Problem The zombie can move and target the player correctly but it only targets that specific player throughout the whole game. Even when the player dies it waits and ignores all other players and when the specific player respawns it starts attacking that same player again.


#My Code The "zombie" is a single part that is a zombie body mesh.

local me = script.Parent
function FindNearestTorso() --Problem function
	local on = false
	for _,plyr in pairs(game:GetService("Players"):GetPlayers()) do
		if plyr then
			on = true
			local char = plyr.Character
			local h = char:FindFirstChild("Humanoid")
			local t = char:FindFirstChild("Torso")
			local max = 1000
			closest = 0
			if h and t and h.Health > 0 then
				local mag = (me.Position - t.Position).magnitude
				if mag < max then --Problem here maybe??
					closest = t
					max = mag
				end
			end
		end
	end
	if on then
		return closest
	else
		return 0 --No Torso
	end
end

while wait() do
	if type(FindNearestTorso()) ~= "number" then
		me.CFrame = me.CFrame:lerp(FindNearestTorso().CFrame,.1) --Not the best way to move it... Any ideas?
	end
end


Hope it helps!

1 answer

✓ Accepted answer

First, a tiny bit of cleanup:

You should use nil to represent absence (as opposed to 0).

plyr can't be nil on line 5; tables don't store nil values. On the other hand, char can be nil and you aren't checking for that case.

Use real names! There's no point in taking the vowels out of player, especially when it will appear only twice in your code. Use humanoid instead of h and torso instead of t. You just make your code harder to read when you compress it to single letters.

Try a name like distance instead of mag since it more accurately describes what the variable means ("magnitude of what?")

The problem

local max is defined for each player. What you want is the closest player overall, which means max should be defined outside of the loop.

Similarly, closest should be defined as a local variable -- don't use global variables!

You've also forgotten to set on. But on is pointless since closest begins as 0 in the error case anyway.

local me = script.Parent
function FindNearestTorso()
	local closestTorso = nil
	local closestDistance = 1000
	for _, player in pairs(game:GetService("Players"):GetPlayers()) do
		local char = player.Character
		if char then
			local humanoid = char:FindFirstChild("Humanoid")
			local torso = char:FindFirstChild("Torso")
			if humanoid and torso and humanoid.Health > 0 then
				local distance = (me.Position - torso.Position).magnitude
				if distance < closestDistance then
					closestTorso = torso
					closestDistance = distance
				end
			end
		end
	end
	return closestTorso
end

while wait() do
	local target = FindNearestTorso()
	if target then
		me.CFrame = me.CFrame:lerp(target.CFrame, .1) --Not the best way to move it... Any ideas?
	end
end

If this is a humanoid, try looking up pathfinding and moveto.

This discussion is preserved as it was. New answers, comments, and votes are closed.