I’ve made code which hits the player(Clientsided), tends to go well except for one little issue.
It hits the player multiple times.
I’ve tried changing the already hit detection, and I’ve tried changing the actual damage function.
Ignore the parry system, unless its affecting the hit detection.
The hitbox itself:
local hit = false
game["Run Service"].Heartbeat:Connect(function()
local chars = game.Workspace:GetPartsInPart(script.Parent)
for i, h in pairs(chars) do
if h.Parent == game.Players.LocalPlayer.Character and hit == false then
if h.Parent:FindFirstChild("Parry") == nil then
game.ReplicatedStorage.DmgPlr:FireServer(15)
script.Parent.Color = Color3.new(0,1,0)
else
game.ReplicatedStorage.DmgPlr:FireServer(-15)
script.Parent.Parry:FireServer()
end
hit = true
end
end
end)
i need more info,use this code instead and then tell me what the console shows:
local hit = false
game["Run Service"].Heartbeat:Connect(function()
local chars = game.Workspace:GetPartsInPart(script.Parent)
for i, h in pairs(chars) do
if h.Parent == game.Players.LocalPlayer.Character and hit == false then
if h.Parent:FindFirstChild("Parry") == nil then
game.ReplicatedStorage.DmgPlr:FireServer(15)
script.Parent.Color = Color3.new(0,1,0)
else
game.ReplicatedStorage.DmgPlr:FireServer(-15)
script.Parent.Parry:FireServer()
end
print(h.Name)
print(hit)
hit = true
end
end
end)
That way we can know exactly what the problem could be.
store the hit flag per character rather than adding a global flag. if that’s not the problem then it may be your if h.Parent == game.Players.LocalPlayer.Character check.
local hit = false
local chars = game.Workspace:GetPartsInPart(script.Parent) -- this value dosn't change locally
local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local function onBeat()
for i, h in pairs(chars)
if h.Parent == character and not hit then
hit = true
if h.Parent:FindFirstChild("Parry") then
game.ReplicatedStorage.DmgPlr:FireServer(-15)
script.Parent.Parry:FireServer()
else
game.ReplicatedStorage.DmgPlr:FireServer(15)
script.Parent.Color = Color3.new(0,1,0)
end
end
print(h.Name)
print(hit)
end
end
game:GetService("Run Service").Heartbeat:Connect(onBeat)
Just as @AntoniV_17 requested, run this code and let us know what the output console returns.
I have a feeling it was detecting multiple hits because the hit = true debounce was set at the end of the if h.Parent statement rather than at the beginning. My theory is the next Heartbeat fires before the hit debounce can be set to true.
And I agree with @CraX_573 , this should be tied to Instance.Touched rather than on every heartbeat.
Sorry about the eyeburn of light mode, but the issue seems to be that it does detect the hit twice. It’s likely the heartbeat loop, so a better solution that i can think of is likely to use the current damage detection once upon creation, and then use instance.touched to detect if the hitbox collides after creation.
script.Parent.Touched:Connect(function(h)
if h.Parent == game.Players.LocalPlayer.Character and hit == false then
hit = true
if h.Parent:FindFirstChild("Parry") == nil then
game.ReplicatedStorage.DmgPlr:FireServer(15)
script.Parent.Color = Color3.new(0,1,0)
else
game.ReplicatedStorage.DmgPlr:FireServer(-15)
script.Parent.Parry:FireServer()
end
print(h)
print(hit)
end
end)
However the issue still prevails. The console still shows the duplication.
A .Touched setup with a debounce would only run once as intended unless your script is running twice, or the debounce variable is being set elsewhere. We’ll need more context
this is the ENTIRE script, maybe there’s an issue here?
local hit = false
game["Run Service"].Heartbeat:Connect(function()
script.Parent.CFrame = script.Parent.attachment.Value.CFrame * script.Parent.Offset.Value
end)
script.Parent.Touched:Connect(function(h)
if hit == true then
return
end
if h.Parent == game.Players.LocalPlayer.Character then
hit = true
if h.Parent:FindFirstChild("Parry") == nil then
game.ReplicatedStorage.DmgPlr:FireServer(15)
script.Parent.Color = Color3.new(0,1,0)
else
game.ReplicatedStorage.DmgPlr:FireServer(-15)
script.Parent.Parry:FireServer()
end
print(h)
print(hit)
end
end)
Otherwise, there is an enemy ai which clones the hitbox from serverstorage and sets up the size and that.
I pasted your script into a part in an empty place file and it runs properly. The script that creates the hitbox must be creating two of them, what does that script look like?
After some testing, taking the function out of the spawn() call fixed the double hitbox issue
spawn(function()
task.wait(1)
while task.wait() do
local target = SwingAttempt(script.Parent.HumanoidRootPart.Position)
if target ~= nil and db == false then
----print(script.Parent.Humanoid.WalkSpeed)
local attack = math.random(1,1)
if attack == 1 then
db = true
print("attack")
local anim = script.Parent.Humanoid:LoadAnimation(script.DoubleSlash)
anim:Play(0.05)
task.wait(0.05)
script.Parent.HumanoidRootPart.AlignOrientation.CFrame = script.Parent.HumanoidRootPart.CFrame
script.Parent.HumanoidRootPart.AlignOrientation.Enabled = true
task.wait(0.07)
local velocity = Instance.new("BodyVelocity",script.Parent.HumanoidRootPart)
velocity.MaxForce = Vector3.new(math.huge,0,math.huge)
velocity.Velocity = script.Parent.HumanoidRootPart.CFrame.LookVector*125
local hitbox = game.ServerStorage.attacks.juggernaut.hitbox:Clone()
hitbox.attachment.Value = script.Parent.HumanoidRootPart
hitbox.Offset.Value = CFrame.new(0,0,-3)
hitbox.Size = Vector3.new(4,5,6)
hitbox.Parent = game.Workspace.Attacks
task.wait(0.2)
hitbox:Destroy()
velocity.Velocity = Vector3.new(0,0,0)
script.Parent.HumanoidRootPart.AlignOrientation.Enabled = false
task.wait(0.14)
script.Parent.HumanoidRootPart.AlignOrientation.CFrame = script.Parent.HumanoidRootPart.CFrame
script.Parent.HumanoidRootPart.AlignOrientation.Enabled = true
task.wait(0.2)
velocity.Velocity = script.Parent.HumanoidRootPart.CFrame.LookVector*125
local hitbox = game.ServerStorage.attacks.juggernaut.hitbox:Clone()
hitbox.attachment.Value = script.Parent.HumanoidRootPart
hitbox.Offset.Value = CFrame.new(0,0,-3)
hitbox.Size = Vector3.new(4,5,6)
hitbox.Parent = game.Workspace.Attacks
task.wait(0.2)
hitbox:Destroy()
velocity.Velocity = Vector3.new(0,0,0)
task.wait(0.1)
velocity:Destroy()
script.Parent.HumanoidRootPart.AlignOrientation.Enabled = false
task.wait(0.5)
db = false
end
end
end
end)
For what it’s worth, using spawn() isn’t necessary here, and your SwingAttempt() function can be potentially very laggy with higher instance counts in the workspace