Hello everyone.
-
What do you want to achieve?
I am trying to create an automatic turret that shoots the player that enters its zone. - What is the issue?
-
After messing around with my code I found out that if you spam going in and out a few times the turret will continue to shoot at your player even though you have already left the zone.
-
I feel the code itself could have been done a lot easier or have a lot part that are unnecessary, but I could not figure out anything else to do.
- What solutions have you tried so far?
-
I have tried my best debugging the issue but could not figure out a way to solve the problem completely.
-
The problem seems to be because targets[hit.Parent] becomes “CanBeShot” while the player has already left and since the script is delayed when checking for debounce to become true again, once it has become true the script continues and targets[hit.Parent] becomes true and the turret will start shooting at the player who has already left. (Not 100% sure if this is the problem)
local zone = script.Parent
local targets = {}
local rayParm = RaycastParams.new()
rayParm.IgnoreWater = true
rayParm.FilterType = Enum.RaycastFilterType.Blacklist
rayParm.FilterDescendantsInstances = {workspace.RedCrystal}
local function StartDamage(hit)
if hit.Name == "HumanoidRootPart" then
if targets[hit.Parent] == nil then
targets[hit.Parent] = true
targets[tostring(hit.Parent) .. "1"] = true
end
if targets[tostring(hit.Parent) .. "1"] == false then
targets[tostring(hit.Parent) .. "1"] = "Loading"
while targets[tostring(hit.Parent) .. "1"] == "Loading" do
wait(.1)
if targets[tostring(hit.Parent) .. "1"] == true then
break
end
end
end
if targets[tostring(hit.Parent) .. "1"] == true then
targets[tostring(hit.Parent) .. "1"] = false
if targets[hit.Parent] == "CanBeShot" then
targets[hit.Parent] = true
elseif targets[hit.Parent] == "Left" then
while targets[hit.Parent] == "Left" do
wait(.1)
if targets[hit.Parent] == "CanBeShot" then
targets[hit.Parent] = true
break
end
end
end
end
while targets[hit.Parent] == true and hit.Name == "HumanoidRootPart" do
targets[hit.Parent] = false
local distance = (workspace.RedCrystal.core.Position - hit.Position).Magnitude
local bullet = Instance.new("Part")
bullet.Size = Vector3.new(0 , 0 , distance)
bullet.CFrame = CFrame.new(workspace.RedCrystal.core.Position , hit.Position) * CFrame.new(0 , 0 , -distance/2)
bullet.Parent = workspace
bullet.Anchored = true
bullet.CanCollide = false
hit.Parent:FindFirstChild("Humanoid"):TakeDamage(10)
wait(.5)
bullet:Destroy()
wait(2)
targets[tostring(hit.Parent) .. "1"] = true
if targets[hit.Parent] ~= "Left" then
targets[hit.Parent] = true
elseif targets[hit.Parent] == "Left" then
targets[hit.Parent] = "CanBeShot"
end
end
end
end
zone.Touched:Connect(StartDamage)
zone.TouchEnded:Connect(function(hit)
if hit.Name == "HumanoidRootPart" then
targets[hit.Parent] = "Left"
end
end)
-
targets[hit.Parent] is suppose to check and act as a cooldown for when the turret can shoot again.
-
targets[tostring(hit.Parent) … “1”] is suppose to be a personal debounce for each player to make sure they don’t spam the touch function
Hopefully I have explained everything clearly enough. I am still quite new at scripting so I am hoping someone can teach me how to write better and clearer scripts here so I can improve.
Thank you!