My target system for my Tower defense game isn't working

This is my script can someone help me and see whats wrong with it

local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local PhysicsService = game:GetService(“PhysicsService”)

local events = ReplicatedStorage:WaitForChild(“Events”)
local animateTowerEvent = events:WaitForChild(“AnimateTower”)
local functions = ReplicatedStorage:WaitForChild(“Functions”)
local spawnTowerFunction = functions:WaitForChild(“SpawnTower”)
local requestTowerFunction = functions:WaitForChild(“RequestTower”)
local sellTowerFunction = functions:WaitForChild(“SellTower”)

local map = workspace.EnconnsHats
local maxTowers = 20
local tower = {}

function tower.FindTarget(newTower, range, mode)
local bestTarget = nil

local bestWaypoint = nil
local bestDistance = nil
local bestHealth = nil

for i, mob in ipairs(workspace.Mobs:GetChildren()) do
	local distanceToMob = (mob.HumanoidRootPart.Position - newTower.HumanoidRootPart.Position).Magnitude
	local distanceToWaypoint = (mob.HumanoidRootPart.Position - map.Waypoints[mob.MovingTo.Value].Position).Magnitude
	
	if distanceToMob <= range then
		if mode == "Near" then
			range = distanceToMob
			bestTarget = mob
			
		elseif mode == "First" then
			if not bestWaypoint or mob.MovingTo.Value >= bestWaypoint then
				if bestWaypoint then
					bestDistance = nil 
				end
				bestWaypoint = mob.MovingTo.Value
				
				if not bestDistance or distanceToWaypoint < bestDistance then
					bestDistance = distanceToWaypoint
					bestTarget = mob
				end
			end
		elseif mode == "Last" then
			if not bestWaypoint or mob.MovingTo.Value <= bestWaypoint then
				if bestWaypoint then
					bestDistance = nil
				end

				if not bestDistance or distanceToWaypoint > bestDistance then
					bestDistance = distanceToWaypoint
					bestTarget = mob
				end
			end
		elseif mode == "Strong" then
			if not bestHealth or mob.Humanoid.Health > bestHealth then
				bestHealth = mob.Humanoid.Health
				bestTarget = mob
			end
			
		elseif mode == "Weak" then
			if not bestHealth or mob.Humanoid.Health < bestHealth then
				bestHealth = mob.Humanoid.Health
				bestTarget = mob
			end
		end
	end
end

return bestTarget

end

function tower.Attack(newTower, player)
local config = newTower.Config
local target = tower.FindTarget(newTower, config.Range.Value, config.TargetMode.Value)

if target and target:FindFirstChild("Humanoid") and target.Humanoid.Health > 0 then

local targetCFrame = CFrame.lookAt(newTower.HumanoidRootPart.Position, target.HumanoidRootPart.Position)
newTower.HumanoidRootPart.BodyGyro.CFrame = targetCFrame

	animateTowerEvent:FireAllClients(newTower, "Attack")
	
	player.Bucks.Value += config.Damage.Value
	target.Humanoid:TakeDamage(config.Damage.Value)
	
	if target.Humanoid.Health <= 0 then
	
	end
	
	task.wait(config.Cooldown.Value)
end

task.wait(0.1)

if newTower and newTower.Parent then
	tower.Attack(newTower, player)
end

end

function tower.Sell(player, model)
if model and model:FindFirstChild(“Config”) then
if model.Config.Owner.Value == player.Name then
player.PlacedTowers.Value -= 1
player.Bucks.Value += model.Config.Price.Value / 2
model:Destroy()
return true
end
end

warn("Unable to sell this tower")
return false

end
sellTowerFunction.OnServerInvoke = tower.Sell

function tower.Spawn(player, name, cframe, previous)
local allowedToSpawn = tower.CheckSpawn(player, name)

if allowedToSpawn then
	
	local newTower
	if previous then
		previous:Destroy()
		newTower = ReplicatedStorage.Towers.Upgrades[name]:Clone()
	else
		newTower = ReplicatedStorage.Towers[name]:Clone()
		player.PlacedTowers.Value += 1
	end
	
	local ownerValue = Instance.new("StringValue")
	ownerValue.Name = "Owner"
	ownerValue.Value = player.Name
	ownerValue.Parent = newTower.Config
	
	local targetMode = Instance.new("StringValue")
	targetMode.Name = "TargetMode"
	targetMode.Value = "Last"
	targetMode.Parent = newTower.Config
	
	
	newTower.HumanoidRootPart.CFrame = cframe
	newTower.Parent = workspace.Towers
	newTower.HumanoidRootPart:SetNetworkOwner(nil)
	
	local bodyGryo = Instance.new("BodyGyro")
	bodyGryo.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
	bodyGryo.D = 0
	bodyGryo.CFrame = newTower.HumanoidRootPart.CFrame
	bodyGryo.Parent = newTower.HumanoidRootPart

	for i, object in ipairs(newTower:GetDescendants()) do
		if object:IsA("BasePart") then
			PhysicsService:SetPartCollisionGroup(object, "Tower")
		end
	end	
	
	player.Bucks.Value -= newTower.Config.Price.Value
		
	coroutine.wrap(tower.Attack)(newTower, player)
	
	return newTower
else
	warn("Requested tower does not exist", name)
	return false
end

end
spawnTowerFunction.OnServerInvoke = tower.Spawn

function tower.CheckSpawn(player, name)
local towerExists = ReplicatedStorage.Towers:FindFirstChild(name, true)

if towerExists then
	if towerExists.Config.Price.Value <= player.Bucks.Value then
		if player.PlacedTowers.Value < maxTowers then
			return true
		else
			warn("Player has reached the max limit")
		end
	else
		warn("Player cannot afford")
	end
else
	warn("That tower does not exist")
end

return false

end
requestTowerFunction.OnServerInvoke = tower.CheckSpawn

return tower

1 Like

Please help me eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee

You can format code using the guide.

Apart from that, when you run your script, is it throwing any errors in the output?

No it isn’t throwing any errors in the output

Its with the gui and the value not changing

It would speed up things significantly if you could narrow down what part of your script is failing to do what you would like it to do.

At first glance, I can’t see anything relating to a GUI, and value editing within the code you posted seems to update correctly, implying that your issue is with the GUI rather than this.

Again, please format your code, it’s overwhelming to developers to be given an uncommented, fragmented portion of code.

Like there is supposed to be a gui that tells you what target you are

I’m kind of new with developing though so I’m kind of dumb