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.

1 comment
im not gonna get fully in to this but maybe one thing that u can change and probably should change too is when u got magnitude checks, dont check using CFrame, check using HumanoidRootPart.Position