So I am making a game and am currently working on a combat system and while making it so when the player clicks, it punches, but I’ve run into the problem where whenever the player clicks, it fires the RemoteEvent to attack twice which means it is for some reason doing double damage.
Here is my code for the local script:
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local debounce = false
local timer = .25
mouse.Button1Down:Connect(function()
if script.Parent.Humanoid.Health > 0 then
if debounce == false then
debounce = true
print("click")
game.ReplicatedStorage.Remotes.AttackEvent:FireServer()
wait(timer)
debounce = false
end
end
end)
The print is there is to see if it fires twice and when I click it prints “click” twice.
That’s quite weird. Try using UserInputService instead of “GetMouse()” because to my knowledge GetMouse is either deprecated or recommended not to be used, so maybe it is glitching now
This is the code that is ran when the remote is received:
local function Attack(player)
local AttackNum = math.random(1,2)
local AttackAnim = player.Character.Humanoid.Animator:LoadAnimation(player.Character:FindFirstChild("Attack"..AttackNum))
AttackAnim:Play()
local Target = FindTarget(player)
if Target ~= nil then
local Damage = math.random(player.Character.Info.MinPower.Value, player.Character.Info.MaxPower.Value)
Target.Humanoid.Health = Target.Humanoid.Health - Damage
end
end
and here is the “FindTarget” function is refers to:
local function FindTarget(player)
local maxDistance = 5
for i,v in pairs(game.Workspace:GetChildren()) do
if v ~= player.Character then
local humanoid = v:FindFirstChild("Humanoid")
if humanoid then
if humanoid.Health > 0 then
local Distance = (v.HumanoidRootPart.Position - player.Character.HumanoidRootPart.Position).Magnitude
if Distance <= maxDistance then
maxDistance = Distance
return v
end
end
end
end
end
end
That looks more complicated than it should be, to me.
Also, using magnitude, you could damage him even though he is standing behind you.
I’d do it like this:
--LocalScript (StarterPlayerScripts)
local ContextActionService = game:GetService("ContextActionService");
local player = game:GetService("Players").LocalPlayer;
local remote = game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("AttackEvent");
local animation = ... --path
local debounce = false;
local cooldown = 0.25;
local function onClick()
if debounce == false then
debounce = true;
animation:Play();
remote:FireServer();
print("Yes");
wait(cooldown);
debounce = false;
end
end
ContextActionService:BindAction("Click", onClick, true, Enum.UserInputType.MouseButton1);
--Server Script (ServerScriptService)
local remote = game:GetService("ReplicatedStorage").Remotes.AttackEvent;
local alreadyHit = {};
local damage = 20;
remote.OnServerEvent:Connect(function(plr)
local f;
local char = plr.Character or plr.CharacterAdded:Wait();
--Now get his hand if he punches
local rightHand = char.RightLowerArm;
local function onTouched(hit)
if hit.Parent:FindFirstChild("Humanoid") or hit.Parent.Parent:FindFirstChild("Humanoid") then
local humanoid = hit.Parent:FindFirstChild("Humanoid") or hit.Parent.Parent:FindFirstChild("Humanoid");
local enemyChar = humanoid.Parent;
if not table.find(alreadyHit, enemyChar) then
table.insert(alreadyHit, #alreadyHit+1, enemyChar);
humanoid:TakeDamage(damage);
wait(0.5);
table.remove(alreadyHit, table.find(alreadyHit, enemyChar));
end
end
end
f = rightHand.Touched:Connect(onTouched)
coroutine.wrap(function()
wait(1); --Wait until the animation is done
f:Disconnect();
end)
end)
This is a simple fact, remotes don’t get fired twice nor gets picked up twice. Unless you have duplicates of code, have a remotefunction or a loose signal invoking them.
I did some testing with a wait time of 0.25, it appears to be a really insignificant wait time and can result in “double clicking.” For testing purposes, can you try changing the wait time to something larger like 1-2 seconds?