So how my code works is that the client plays an animation, and after a couple of seconds, it creates a hitbox and sends the hit players to the server. Now there are sanity checks, such as determining the distance between players, but if they’re exploiting, can’t they just spam the remote? It will essentially be like a constant AOE. How can I fix this? Here’s my code:
-- Client
local Character : Model = script.Parent
local Humanoid : Humanoid = Character:WaitForChild('Humanoid')
local HitAnimation : AnimationTrack = Humanoid:WaitForChild('Animator'):LoadAnimation(script.Hit)
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local AOE_Cooldown = false
local Attacking = false
UserInputService.InputBegan:Connect(function(Input, GameProcesedEvent)
if not GameProcesedEvent then
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
if AOE_Cooldown or Attacking then return end
Attacking = true
task.delay(0.5, function()
local VisualHitbox = Instance.new("Part")
VisualHitbox.Size = Vector3.one*20
VisualHitbox.Shape = Enum.PartType.Ball
VisualHitbox.CanCollide = false
VisualHitbox.CanQuery = false
VisualHitbox.Anchored = true
VisualHitbox.Massless = true
VisualHitbox.BrickColor = BrickColor.new("Really red")
VisualHitbox.Position = Character.HumanoidRootPart.Position
VisualHitbox.Transparency = 0.75
VisualHitbox.Material = Enum.Material.Neon
VisualHitbox.Parent = workspace
task.delay(1, function()
local Tween = TweenService:Create(VisualHitbox, TweenInfo.new(0.5), {Transparency=1})
Tween:Play()
Tween.Completed:Connect(function()
VisualHitbox:Destroy()
end)
end)
for _, Target in ipairs(game.Workspace:GetChildren()) do
if Target:IsA("Model") and Target:FindFirstChild("HumanoidRootPart") and Target:FindFirstChild("Humanoid") and Target ~= Character and (Character.HumanoidRootPart.Position - Target.HumanoidRootPart.Position).Magnitude <= 20 then
game.ReplicatedStorage.Remotes.Attack:FireServer('AOE', Target)
end
end
end)
task.delay(1, function()
Attacking = false
end)
AOE_Cooldown = true
task.delay(6, function()
AOE_Cooldown = false
end)
end
end
end)
local OldHP = Humanoid.Health
-- Animation is played here
Humanoid.HealthChanged:Connect(function(CurrentHP)
if OldHP > CurrentHP then
HitAnimation:Play()
end
OldHP = CurrentHP
end)
-- Server
game.ReplicatedStorage.Remotes.Attack.OnServerEvent:Connect(function(Player, Attack, Target)
local Character = Player.Character
if Attack == "AOE" then
if (Character.HumanoidRootPart.Position - Target.HumanoidRootPart.Position).Magnitude <= 25 then
Target.Humanoid:TakeDamage(10)
end
end
end)