Was thinking about combat warriors and was thinking about how they probably handle hit detection on client for it to be that accurate
So with the only thing in mind of making some sort of hitbox that has detections on client i tried making one
Only works for tools (Somewhat) but overall it works
(no debounce / range check currently as i just was working on getting it to work in general)
Code
Module script
-- Variables
local Hitboxes = {}
local Event = script.HitboxEvent
local SendOnlyHumanoids = true
-- Functions
local function StartingHitbox(hb, t)
if not Hitboxes[hb] or Hitboxes[hb] ~= true then Hitboxes[hb] = true end
if not Hitboxes[hb] and Hitboxes[hb] ~= true then Hitboxes[hb] = true end
while task.wait(.01) do
if Hitboxes[hb] and Hitboxes[hb] == true then
local ThingsTouching = workspace:GetPartsInPart(hb, if t["Op"] then t["Op"] else OverlapParams.new()) --workspace:GetPartBoundsInBox(hb.CFrame, hb.Size, if t["Op"] then t["Op"] else OverlapParams.new())
if #ThingsTouching > 0 then
if SendOnlyHumanoids == true then
local temptable = {}
for i,v in ipairs(ThingsTouching) do
if v.Parent:FindFirstChild("Humanoid") and not table.find(temptable, v.Parent) then
table.insert(temptable, v.Parent)
end
end
if #temptable > 0 then Event:FireServer(temptable) end
else
Event:FireServer(ThingsTouching)
end
end
else
break
end
end
end
local function AttachPositions(Model)
local PartSize, PartPosition = nil, nil
local PartSize = Model:GetExtentsSize()
local PartPosition = Vector3.new(
Model:GetPivot().X,
Model:GetPivot().Y,
Model:GetPivot().Z
)
return PartSize, PartPosition
end
-- Module
local HitBoxM = {}
HitBoxM.__index = HitBoxM
HitBoxM.CreateHitbox = function(Tool : Tool, Model : Model)
local tabled = {}
local PartHitbox = Instance.new("Part")
PartHitbox.Anchored = true
PartHitbox.CanCollide = false
PartHitbox.Transparency = 1
PartHitbox.Color = Color3.new(255,255,255)
local HitboxWeld = Instance.new("Weld")
local PartSize, PartPosition = AttachPositions()
PartHitbox.Size = PartSize
PartHitbox.Position = PartPosition
HitboxWeld.Part0 = Tool.Handle
HitboxWeld.Part1 = PartHitbox
PartHitbox.Parent = Tool
tabled["HitBoxPart"] = PartHitbox
setmetatable(tabled, HitBoxM)
return tabled
end
HitBoxM.SetupHitbox = function(Hitbox : Part)
local t = {}
t["HitBoxPart"] = Hitbox
setmetatable(t, HitBoxM)
return t
end
function HitBoxM:StartHitbox()
if not self["HitBoxPart"] or self["HitBoxPart"].ClassName ~= "Part" then warn("Tried Starting a hitbox without setup/creation") return end
local Hitbox = self["HitBoxPart"]
local d = coroutine.create(StartingHitbox)
coroutine.resume(d, Hitbox, self)
end
function HitBoxM:StopHitbox()
if not self["HitBoxPart"] or self["HitBoxPart"].ClassName ~= "Part" then warn("Tried Stopping a hitbox without setup/creation") return end
local Hitbox = self["HitBoxPart"]
if Hitboxes[Hitbox] then Hitboxes[Hitbox] = false else warn("There was no hitbox detected for: " .. Hitbox.Name .. ", Creating Detection"); Hitboxes[Hitbox] = false end
end
function HitBoxM:CreateParams(Tool)
local Op = OverlapParams.new()
Op.FilterType = Enum.RaycastFilterType.Blacklist
Op.MaxParts = 0
Op.FilterDescendantsInstances = {Tool.Parent, Tool}
for i, v in Tool:GetChildren() do
if v.ClassName == "Part" then table.insert(Op.FilterDescendantsInstances, v) end
if v.ClassName == "Model" then for i, v in ipairs(v:GetChildren()) do table.insert(Op.FilterDescendantsInstances, v) end end
end
print(Op.FilterDescendantsInstances)
self["Op"] = Op
end
return HitBoxM
Client
repeat wait() until game:IsLoaded()
local tool = script.Parent
local Handle = tool.Handle
local SwordModel = tool["Realistc Sword"]
local T_SwordParts = SwordModel:GetChildren()
local Hitboxmod = game.ReplicatedStorage.SimpleHitboxModule
local HBM = require(Hitboxmod)
local Hitbox = HBM.SetupHitbox(tool.HitBox)
local debounce = false
function UseTool()
if debounce == true then return end
Hitbox:StartHitbox()
debounce = true
print("Started Hitbox")
task.wait(2)
debounce = false
print("Stopped Hitbox")
Hitbox:StopHitbox()
end
function Equipped()
Hitbox:CreateParams(tool)
end
function Unequipped()
Hitbox:StopHitbox()
end
tool.Activated:Connect(UseTool)
tool.Equipped:Connect(Equipped)
tool.Unequipped:Connect(Unequipped)
Server
local event = game.ReplicatedStorage.SimpleHitboxModule:WaitForChild('HitboxEvent')
local tb = {}
local function CoolDown(v)
task.wait(2)
table.remove(tb, table.find(tb, v))
end
event.OnServerEvent:Connect(function(player : Player, t)
for i, v in ipairs(t) do
if not table.find(tb, v) and player.Character and player.Character:FindFirstChildWhichIsA("Tool") and (player.Character:FindFirstChildWhichIsA("Tool").Handle.Position - v.HumanoidRootPart.Position).Magnitude < 10 then
print((player.Character:FindFirstChildWhichIsA("Tool").Handle.Position - v.HumanoidRootPart.Position).Magnitude)
table.insert(tb, v)
v:WaitForChild("Humanoid"):TakeDamage(10)
local d = coroutine.wrap(CoolDown)
d(v)
end
end
end)
with SendOnlyHumanoids set to false
With SendOnlyHumanioids set to true
(edit 1)
updated local script code & included server code