Perhaps with spatial queries?
You could use :GetPartsInPart
(more accurate but more expensive) or :GetPartBoundsInBox
(for simple brick-like hitboxes)
:GetPartsInPart
local lp = game:GetService('Players').LocalPlayer
local char = workspace:WaitForChild(lp.Name)
local param = OverlapParams.new()
param.FilterDescendantsInstances = {char}
param.FilterType = Enum.RaycastFilterType.Blacklist
param.MaxParts = 1
local parts = {}
for _, v in ipairs(char:GetChildren()) do
if v:IsA('MeshPart') then
table.insert(parts, v)
print(v)
end
end
while char do
for _, v in ipairs(parts) do
char:SetAttribute(v.Name, #workspace:GetPartsInPart(v, param) > 0)
end
task.wait()
end
:GetPartBoundsInBox (extended hitbox)
local lp = game:GetService('Players').LocalPlayer
local char = workspace:WaitForChild(lp.Name)
local param = OverlapParams.new()
param.FilterDescendantsInstances = {char}
param.FilterType = Enum.RaycastFilterType.Blacklist
param.MaxParts = 1
local parts = {}
for _, v in ipairs(char:GetChildren()) do
if v:IsA('MeshPart') then
table.insert(parts, v)
print(v)
end
end
local extension = Vector3.new(.1, .1, .1)
while char do
for _, v in ipairs(parts) do
char:SetAttribute(v.Name, #workspace:GetPartBoundsInBox(v.CFrame, v.Size + extension, param) > 0)
end
task.wait()
end
Here’s a demo of the :GetPartBoundsInBox method that you can try yourself:
touchedAlternative.rbxl (34.8 KB)