Recently, I started work on attempting to make a tower defense game, I’m relatively new to scripting and attempted to work on a tower script
As shown in the video, sometimes my towers will have the error
“ServerScriptService.NewTowerScript:52: attempt to index nil with ‘FindFirstChild’”
This results in the tower no longer firing and just standing blank.
I’ve attempted rewriting it but it came out to the same issue. If someone could explain to me why this is happening that would be great. Thanks
local TowersFolder = game.Workspace.Towers
local RunService = game:GetService("RunService")
local Map = game.Workspace.Map
local Path = Map.Path
local Destination = Map:FindFirstChild("Path"):FindFirstChild("HomeBase"):FindFirstChild("Destination")
local function Attack(enemy, distance, tower)
if tower:FindFirstChild("TowerInfo"):FindFirstChild("CooldownActive").Value == false then
print(enemy.Name)
if enemy.Parent == game.Workspace.Enemies then
if enemy:FindFirstChild("EnemyInfo"):FindFirstChild("Health") then
local EnemyHealth = enemy:FindFirstChild("EnemyInfo"):FindFirstChild("Health")
if EnemyHealth.Value > 0 then
local TowerInfo = tower:WaitForChild("TowerInfo")
local CooldownActive = TowerInfo:FindFirstChild("CooldownActive")
local Enemies = game.Workspace.Enemies
local Damage = TowerInfo:FindFirstChild("Damage")
local Cooldown = TowerInfo:FindFirstChild("Cooldown")
local Range = TowerInfo:FindFirstChild("Range")
local HRP = tower:FindFirstChild("HumanoidRootPart")
local MiddlePosition = Path:FindFirstChild("HomeBase"):FindFirstChild("Destination").Position
local EnemyPosition = enemy:WaitForChild("HumanoidRootPart")
local PrimaryPart = tower.PrimaryPart
PrimaryPart.CFrame = CFrame.new(PrimaryPart.Position, Vector3.new(EnemyPosition.Position.x, PrimaryPart.Position.y, EnemyPosition.Position.z))
local EnemyInfo = enemy:FindFirstChild("EnemyInfo")
local EnemyHealth = EnemyInfo:FindFirstChild("Health")
EnemyHealth.Value = EnemyHealth.Value - Damage.Value
CooldownActive.Value = true
print(tower.Name.."Fired")
wait(Cooldown.Value)
TowerInfo:FindFirstChild("CooldownActive").Value = false
end
end
end
end
end
local function ActiveScript(tower)
local TowerInfo = tower:WaitForChild("TowerInfo")
local Enemies = game.Workspace.Enemies
local Damage = TowerInfo:FindFirstChild("Damage")
local Cooldown = TowerInfo:FindFirstChild("Cooldown")
local Range = TowerInfo:FindFirstChild("Range")
local PrimeTarget = math.huge
local PrimeDistance = math.huge
while wait(0.1) do
if TowerInfo:FindFirstChild("CooldownActive").Value == false then
local Root = tower:FindFirstChild("HumanoidRootPart")
for i, enemy in pairs(Enemies:GetChildren()) do
if enemy ~= nil then
local Health = enemy:FindFirstChild("EnemyInfo"):FindFirstChild("Health")
if Health.Value > 0 then
if enemy:FindFirstChild("Humanoid") then
if enemy:FindFirstChild("HumanoidRootPart") then
local EnemyRoot = enemy:FindFirstChild("HumanoidRootPart")
local EnemyPos = EnemyRoot.Position
local EnemyPosition = Vector3.new(EnemyPos.X, Root.Position.Y, EnemyPos.Z)
local EnemyMag = (Root.Position - EnemyPosition).Magnitude
if EnemyMag < Range.Value then
local EnemyFromBase = Vector3.new(EnemyPos.X, Destination.Position.Y, EnemyPos.Z)
local DistanceFromBase = (Destination.Position - EnemyFromBase).Magnitude
if DistanceFromBase < PrimeDistance then
PrimeTarget = enemy
PrimeDistance = DistanceFromBase
end
Attack(PrimeTarget, PrimeDistance, tower)
end
end
end
end
end
end
end
end
end
while wait() do
for i, tower in pairs(TowersFolder:GetChildren()) do
if tower:FindFirstChild("Humanoid") then
if TowersFolder:FindFirstChild(tower.Name) then
local TowerInfo = tower:FindFirstChild("TowerInfo")
local Active = TowerInfo:FindFirstChild("Active")
if Active.Value == false then
Active.Value = true
spawn(function()
print("Activated: ".. tower.Name)
ActiveScript(tower)
end)
end
end
end
end
end