I am making a tower defense style game, and I made a minigunner tower for testing. But I am having a big problem.
On studio play mode, the tower's script works perfectly fine. But when in-game or on studio test mode, it breaks partially and the shoot() function doesn't fire for some reason.
Script:
--//Services local players = game:GetService("Players") local debris = game:GetService("Debris") --//Variables local tower = script.Parent.Parent local towerHumanoidRootPart = tower:WaitForChild("HumanoidRootPart") local humanoid = tower:WaitForChild("Humanoid") local minigun = tower:WaitForChild("Minigun") local storage = tower:WaitForChild("Storage") local animations = storage:WaitForChild("Animations") local idleAnimation = animations:WaitForChild("Idle") local soundEffects = storage:WaitForChild("SoundEffects") local gunshotSFX = soundEffects:WaitForChild("GunshotSFX") local statistics = require(storage:WaitForChild("TowerStatistics")) local range = statistics["Range"] local fireRate = statistics["FireRate"] local damage = statistics["Damage"] --//Functions local function generateRangeMarker() local rangeMarker = Instance.new("Part") rangeMarker.Anchored = true rangeMarker.CanCollide = false rangeMarker.CFrame = towerHumanoidRootPart.CFrame *CFrame.new(0, -1.75, 0) *CFrame.Angles(0, 0, math.rad(90)) rangeMarker.Size = Vector3.new(.1, range * 2, range * 2) rangeMarker.BrickColor = BrickColor.new("Deep blue") rangeMarker.Transparency = .5 local rangeMarkerMesh = Instance.new("SpecialMesh", rangeMarker) rangeMarkerMesh.MeshType = Enum.MeshType.Cylinder rangeMarker.Parent = tower end local function startAnimation() wait() humanoid:LoadAnimation(idleAnimation):Play() end local function shoot() --//The function that breaks when in-game. while wait(fireRate) do local playerList = players:GetPlayers() for i = 1, #playerList do local target = workspace:FindFirstChild(playerList[i].Name) if not target then return end local targetHumanoid = target:FindFirstChild("Humanoid") if not targetHumanoid then return end local targetHumanoidRootPart = target:FindFirstChild("HumanoidRootPart") if not targetHumanoidRootPart then return end local magnitude = (towerHumanoidRootPart.CFrame.p - targetHumanoidRootPart.CFrame.p).magnitude if magnitude < range then towerHumanoidRootPart.CFrame = CFrame.new(towerHumanoidRootPart.CFrame.p, targetHumanoidRootPart.CFrame.p) towerHumanoidRootPart.Orientation = Vector3.new(0, towerHumanoidRootPart.Orientation.Y, towerHumanoidRootPart.Orientation.Z) targetHumanoid:TakeDamage(damage) local newGunshotSFX = Instance.new("Sound") newGunshotSFX.Name = "ClonedGunshotSFX" newGunshotSFX.SoundId = gunshotSFX.SoundId newGunshotSFX.Parent = minigun newGunshotSFX:Play() debris:AddItem(newGunshotSFX, 1) end end end end --//Callers generateRangeMarker() startAnimation() shoot() --//The caller for the shoot() function.
This is the 3rd/4th time I am asking this, I didn't get a answer on the other times I asked this same question.
This lines:
if not target then return end if not targetHumanoid then return end
are ending your function completely rather than restarting the loop. You can either replace return
with break
that will break the for loop, or nest your code few more times, like this:
for i = 1, #playerList do local target = workspace:FindFirstChild(playerList[i].Name) if target then local targetHumanoid = target:FindFirstChild("Humanoid") if targetHumanoid then local targetHumanoidRootPart = target:FindFirstChild("HumanoidRootPart") if targetHumanoidRootPart then local magnitude = (towerHumanoidRootPart.CFrame.p - targetHumanoidRootPart.CFrame.p).magnitude if magnitude < range then towerHumanoidRootPart.CFrame = CFrame.new(towerHumanoidRootPart.CFrame.p, targetHumanoidRootPart.CFrame.p) towerHumanoidRootPart.Orientation = Vector3.new(0, towerHumanoidRootPart.Orientation.Y, towerHumanoidRootPart.Orientation.Z) targetHumanoid:TakeDamage(damage) -- TIP :this code below should be outside while loop as it needs to run just once local newGunshotSFX = Instance.new("Sound") newGunshotSFX.Name = "ClonedGunshotSFX" newGunshotSFX.SoundId = gunshotSFX.SoundId newGunshotSFX.Parent = minigun --end of just once code newGunshotSFX:Play() debris:AddItem(newGunshotSFX, 1) --not needed when you use my tip end end end end end