Hey! I made a post earlier today and got some good general advice about hitboxes and how they should be made. I’ve now moved to a client-sided hitbox system where the hit validation is done on the server and then the effects are shown on all clients.
Though this is all well, (at least I think it is if there’s any more ways to validate a hit on the hitbox let me know!) I want to be able to send information like the cooldown timer, magnitude range and angle it can hit at to the server so I can just keep using the same hit validation script.
The problem is that I know this is a BIG no no because the exploiter could simply just change those values in the local script, the same way with the vTable but that’s where my checks come in.
So I’m wondering if this is something I shouldn’t be worried about or if it is and there’s a way to validate those variables so I can continually use this script for all of my abilities.
local script:
local RS = game:GetService("ReplicatedStorage")
local PLRS = game:GetService("Players")
local UIS = game:GetService("UserInputService")
local abilityEvents = RS:WaitForChild("Ability")
local abilityRemote = abilityEvents:WaitForChild("AbilityRemote")
--Hitbox is created on the client for WYSIWYG flow. We will need checks on the server side for exploit purposes
UIS.InputBegan:Connect(function(input, gameProcessed)
local character = script.Parent
if gameProcessed then
return
end
if input.KeyCode == Enum.KeyCode.Q then
local hrp = character:FindFirstChild("HumanoidRootPart")
local pos = hrp.Position
local hitCharacters = {}
local parameters = OverlapParams.new()
local hitbox = Instance.new("Part")
hitbox.Shape = Enum.PartType.Ball
hitbox.Size = Vector3.new(10, 10, 10)
hitbox.CanCollide = false
hitbox.Anchored = true
hitbox.Transparency = 0.5
local cf = hrp.CFrame
local size = hitbox.Size
parameters.FilterDescendantsInstances = {character}
hitbox.Position = pos
hitbox.Parent = workspace
local hitboxPart = workspace:GetPartBoundsInBox(cf, size, parameters)
local vTable = {}
for _, hitPart in pairs(hitboxPart) do
local vHum = hitPart.Parent:FindFirstChild("Humanoid")
if vHum and not table.find(vTable, hitPart.Parent) then
table.insert(vTable, hitPart.Parent)
end
end
abilityRemote:FireServer(vTable) --I would add a cooldown, magnitude and angle value in here
game.Debris:AddItem(hitbox, 0.1)
end
end)
Server Script:
local RS = game:GetService("ReplicatedStorage")
local abilityEvents = RS:WaitForChild("Ability")
local abilityRemote = abilityEvents:WaitForChild("AbilityRemote")
local abilityVFX = abilityEvents:WaitForChild("AbilityVFX")
local debounce = {}
abilityRemote.OnServerEvent:Connect(function(player, vTable) --and the cooldown, distance and degAngle values would change here
local cooldown = 3
local hitChars = {}
local pChar = player.Character
local hrp = pChar:FindFirstChild("HumanoidRootPart")
local pos = hrp.Position
local pDirection = hrp.CFrame.LookVector
if table.find(debounce, player.Name) ~= nil then --Debounce cooldown so exploiters cannot spam the server with requests
print("Under debounce!")
else
print("Ability casted!")
table.insert(debounce, player.Name)
for _, vChar in pairs (vTable) do --Checks if hit was actually valid
local vrp = vChar:FindFirstChild("HumanoidRootPart")
local vPos = vrp.Position
local magCheck = (vPos - pos)
local distance = magCheck.Magnitude --Gets distance between the players
local normalizedDist = magCheck.Unit --Normalizes that distance number
local dot = pDirection:Dot(normalizedDist) --Normalizes look vector
local radAngle = math.acos(dot) --Finds the angle between the vrp and player look direction
local degAngle = math.deg(radAngle) --Converts above into an angle
if distance <= 6 and degAngle <= 45 and vChar and not table.find(hitChars, vChar) then --Validation check
print("Hit")
table.insert(hitChars, vChar) --Adds player to table for VFX purposes
vChar.Humanoid:TakeDamage(10)
end
end
abilityVFX:FireAllClients(hitChars) --VFX
task.wait(cooldown)
debounce[table.find(debounce, player.Name)] = nil
end
end)
Sorry if this is considered a double post, but thanks regardless!