Help fixing towers not targeting right

I have a script where for some reason it targets strongest or the enemy it hit first?
What its supposed to do is target first aka the zombie the closest.
I think its a if statement but im not fully sure. sorry if code is formatted bad code formatting is annoying to do

local tower = script.Parent
while true do
	wait(tower.Stats.Firerate.Value)
	p:Stop()
	local shooting = nil
	local dist = 0
	if tower.Stunned.Value == false and tower:IsA("Model") and tower.PrimaryPart and tower:FindFirstChild("Stats") and tower.PrimaryPart:FindFirstChildOfClass("Sound") then
		for i,v in pairs(workspace.Enemies:GetChildren()) do
			local v1 = tower:GetPrimaryPartCFrame().p-Vector3.new(0,tower.Height.Value,0)
			local v2 = v:GetPrimaryPartCFrame().p-Vector3.new(0,v.Height.Value,0)
			local distance = (Vector3.new(v1.X,0,v1.Z)-Vector3.new(v2.X,0,v2.Z)).Magnitude
			if distance <= tower.Stats.Range.Value then
		   		if v.PercentThrough.Value > dist then
					shooting = v
					dist = v.PercentThrough.Value
				end
			end
		end
		if shooting and shooting.PrimaryPart then
			local x,y,z = CFrame.new(tower:GetPrimaryPartCFrame().p,shooting:GetPrimaryPartCFrame().p):ToEulerAnglesYXZ()
			tower:SetPrimaryPartCFrame(CFrame.new(tower:GetPrimaryPartCFrame().p)*CFrame.Angles(0,y,0))
			p:Play()
			tower.PrimaryPart.Sound:Play()
			for i,v in pairs(game.Players:GetPlayers()) do
				if shooting.Health.Value >= tower.Stats.Damage.Value then
					v.leaderstats.Cash.Value = v.leaderstats.Cash.Value + tower.Stats.Damage.Value
				elseif shooting.Health.Value > 0 then
					v.leaderstats.Cash.Value = v.leaderstats.Cash.Value + shooting.Health.Value
				end
			end
			shooting.Health.Value = shooting.Health.Value - tower.Stats.Damage.Value
		end
	end
end

Your targeting script is really messy and hard to read what I use for targeting is this Zombie’s targeting script. all you need to do is fix some values such as how far it can see the part its raycasting from and some others.
Zombie
PS: Copy and Paste the scripts code so you don’t have to rewrite everything

this is mostly the main part most likely try looking here?

for i,v in pairs(workspace.Enemies:GetChildren()) do
	local v1 = tower:GetPrimaryPartCFrame().p-Vector3.new(0,tower.Height.Value,0)
	local v2 = v:GetPrimaryPartCFrame().p-Vector3.new(0,v.Height.Value,0)
	local distance = (Vector3.new(v1.X,0,v1.Z)-Vector3.new(v2.X,0,v2.Z)).Magnitude
	if distance <= tower.Stats.Range.Value then
	    if v.PercentThrough.Value > dist then
			shooting = v
			dist = v.PercentThrough.Value
		end
	end
end

Yes replace all of that with the zombie targeting function.

I dont want to use free models do u have any other options? this doesn’t really help me in the future if i do this

You should probably make your script a bit more readable.

for i,v in pairs(workspace.Enemies:GetChildren()) do
	local v1 = tower:GetPrimaryPartCFrame().p-Vector3.new(0,tower.Height.Value,0)
	local v2 = v:GetPrimaryPartCFrame().p-Vector3.new(0,v.Height.Value,0)
	local distance = (Vector3.new(v1.X,0,v1.Z)-Vector3.new(v2.X,0,v2.Z)).Magnitude
	if distance <= tower.Stats.Range.Value then
	    if v.PercentThrough.Value > dist then
			shooting = v
			dist = v.PercentThrough.Value
		end
	end
end

i recommend looking here since this is the main part the rest is not really targeting.

So your issue is, it targets a random zombie each time, is it always the same one? or is it completely random

it targets like the strongest sort of its more of randomish

Try printing the value that is returned for each zombie but also most importantly try printing v1 and v2 and what they return.

ill do so if it works ill press solution im mostly busy rn so It might take a bit for me to do so

The problem is that there is nothing that stopes the nearest zombie from getting replace by the next zombie that is run through the code. And its not using free models if your getting that model for a very small and specific piece. Lots of developers use already existing models and stuff to make the job easier.

2 Likes

He doesn’t check if the new one is closer to the previous one, so a fix would be adding right after the dist = v.PercentThrough.Value line:
previousDistance = distance
and an if that would check if distance is smaller than the previous distance

thats not the problem im pretty sure

dist = v.PercentThrough

this is already that

what even is v.PercentThrough.Value it doesn’t appear anywhere in the code is that supposed to be the distance between that zombie and the tower? if then why calculate all this here if it’s not then that’s the problem.

Its from the movement script I have and it changes the value so towers know where it is.

i fixed it with something so thanks