Hey so my units keep hitting enemy’s even when they are out of range and im looked through the script and im not sure why. Any ideas?
Here’s the unit script
*
local physicsService = game:GetService(“PhysicsService”)
local replicatedStorage = game:GetService(“ReplicatedStorage”)
local serverStorage = game:GetService(“ServerStorage”)
local eventsFolder = replicatedStorage:WaitForChild(“Events”)
local animateUnit = eventsFolder:WaitForChild(“AnimateUnit”)
local functionsFolder = replicatedStorage:WaitForChild(“Functions”)
local placeUnitFunction = functionsFolder:WaitForChild(“SpawnUnit”)
local requestFunction = functionsFolder:WaitForChild(“RequestingUnit”)
local sellUnitFunction = functionsFolder:WaitForChild(“SellUnit”)
local changingUnitTargetFunction = functionsFolder:WaitForChild(“ChangeUnitTargetFunction”)
local map = workspace.Maps.FoodMap
local maxUnits = 16
local units = {}
function findNearestTarget(newUnit, range)
local nearestTarget = nil
for i, target in ipairs(workspace.FoodEnemys:GetChildren()) do
local distance = (target.HumanoidRootPart.Position - newUnit.HumanoidRootPart.Position).Magnitude
if distance < range then
nearestTarget = target
range = distance
end
end
return nearestTarget
end
function units.FindTarget(newUnit, range, mode)
local bestTarget = nil
local bestGoTo = nil
local bestDistance = nil
local bestHealth = nil
for i, foodEnemy in ipairs(workspace.FoodEnemys:GetChildren()) do
local distanceToFoodEnemy = (foodEnemy.HumanoidRootPart.Position - newUnit.HumanoidRootPart.Position).Magnitude
local distanceToGoTo = (foodEnemy.HumanoidRootPart.Position - map.GoTos[foodEnemy.GoingTo.Value].Position).Magnitude
if mode == "Near" then
if distanceToFoodEnemy <= range then
range = distanceToFoodEnemy
bestTarget = foodEnemy
end
elseif mode == "First" then
if not bestGoTo or foodEnemy.GoingTo.Value >= bestGoTo then
if bestGoTo then
bestDistance = nil
end
bestGoTo = foodEnemy.GoingTo.Value
if not bestDistance or distanceToGoTo < bestDistance then
bestDistance = distanceToGoTo
bestTarget = foodEnemy
end
end
elseif mode == "Last" then
if not bestGoTo or foodEnemy.GoingTo.Value <= bestGoTo then
bestGoTo = foodEnemy.GoingTo.Value
if not bestDistance or distanceToGoTo > bestDistance then
bestDistance = distanceToGoTo
bestTarget = foodEnemy
end
end
elseif mode == "Strong" then
if not bestHealth or foodEnemy.Humanoid.Health > bestHealth then
bestHealth = foodEnemy.Humanoid.Health
bestTarget = foodEnemy
end
elseif mode == "Weak" then
if not bestHealth or foodEnemy.Humanoid.Health < bestHealth then
bestHealth = foodEnemy.Humanoid.Health
bestTarget = foodEnemy
end
end
end
return bestTarget
end
function units.Attack(newUnit, player)
local configuration = newUnit.Configuration
local target = units.FindTarget(newUnit, configuration.Range.Value, configuration.TargetMode.Value)
if target and target:FindFirstChild("Humanoid") and target.Humanoid.Health > 0 then
local targetCFrame = CFrame.lookAt(newUnit.HumanoidRootPart.Position, target.HumanoidRootPart.Position)
newUnit.HumanoidRootPart.BodyGyro.CFrame = targetCFrame
animateUnit:FireAllClients(newUnit, "Attack")
target.Humanoid:TakeDamage(configuration.Damage.Value)
if target.Humanoid.Health <= 0 then
player.leaderstats.Coins.Value += target.Humanoid.MaxHealth
end
task.wait(configuration.Cooldown.Value)
end
task.wait(0.1)
if newUnit and newUnit.Parent then
units.Attack(newUnit, player)
end
end
function units.ChangeMode(player, model)
if model and model:FindFirstChild(“Configuration”) then
local targetMode = model.Configuration.TargetMode
local modes = {“Near”, “First”, “Last”, “Strong”, “Weak”}
local modeIndex = table.find(modes, targetMode.Value)
if modeIndex < #modes then
targetMode.Value = modes[modeIndex + 1]
else
targetMode.Value = modes[1]
end
return true
else
warn("Cant change tower mode")
return false
end
end
changingUnitTargetFunction.OnServerInvoke = units.ChangeMode
function units.Sell(player, model)
if model and model:FindFirstChild(“Configuration”) then
if model.Configuration.Owner.Value == player.Name then
player.PlacedUnits.Value -= 1
player.leaderstats.Coins.Value += model.Configuration.Price.Value
model:Destroy()
return true
end
end
warn("Cant sell unit")
return false
end
sellUnitFunction.OnServerInvoke = units.Sell
function units.Spawn(player, name, cframe, previous)
local allowUnitToSpawn = units.CheckSpawn(player, name, previous)
local configuration = units.Configuration
if allowUnitToSpawn then
local newUnit
local oldMode = nil
if previous then
oldMode = previous.Configuration.TargetMode.Value
previous:Destroy()
newUnit = replicatedStorage.Units.Upgrades[name]:Clone()
else
newUnit = replicatedStorage.Units[name]:Clone()
player.PlacedUnits.Value += 1
end
local ownerValue = Instance.new("StringValue")
ownerValue.Name = "Owner"
ownerValue.Value = player.Name
ownerValue.Parent = newUnit.Configuration
local targetMode = Instance.new("StringValue")
targetMode.Name = "TargetMode"
targetMode.Value = oldMode or "First"
targetMode.Parent = newUnit.Configuration
newUnit.HumanoidRootPart.CFrame = cframe
newUnit.Parent = workspace.Units
newUnit.HumanoidRootPart:SetNetworkOwner(nil)
local bodyGyro = Instance.new("BodyGyro")
bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
bodyGyro.D = 0
bodyGyro.CFrame = newUnit.HumanoidRootPart.CFrame
bodyGyro.Parent = newUnit.HumanoidRootPart
for i, object in pairs(newUnit:GetDescendants()) do
if object:IsA("BasePart") then
object.CollisionGroup = "Units"
end
end
player.leaderstats.Coins.Value -= newUnit.Configuration.Price.Value
coroutine.wrap(units.Attack)(newUnit, player)
return newUnit
else
warn("Unit not found:", name)
return false
end
end
placeUnitFunction.OnServerInvoke = units.Spawn
function units.CheckSpawn(player, name, previous)
local unitExists = replicatedStorage.Units:FindFirstChild(name, true)
if unitExists then
if unitExists.Configuration.Price.Value <= player.leaderstats.Coins.Value then
if previous or player.PlacedUnits.Value < maxUnits then
return true
else
warn("Player done reached the limit and cant place")
end
else
warn("Player cant afford Units")
end
else
warn("Thats tower dont exist")
end