I’m trying to make an Attack Dummy to test out the defense system but after a few test I notice the inconsistensy of the hitbox, sometime it can seemingly “missed” the player even tho in the video you can clearly see the hitbox of the attack touched the player. why does that happen?
The Attack Dummy's Script
local Storage = game:GetService("ReplicatedStorage")
local Debris = game:GetService("Debris")
local Dummy = script.Parent
local Hum = Dummy.Humanoid
local Animator = Hum.Animator
local Event = Storage.Events.Hit
local COD = Storage.Events.COD -- Event I use to set the GameOver Screen's Tip
local CurrentAnim = 0
local Dmg = 10
local DmgType = "Normal"
while task.wait(5) do
CurrentAnim = 0
for i = 1, #script:GetChildren() do
local Hit = false
CurrentAnim += 1
local Animation = Animator:LoadAnimation(script["Punch "..CurrentAnim])
Animation:Play()
Animation:GetMarkerReachedSignal("Hit"):Connect(function()
local Hitbox = Instance.new("Part", workspace)
Hitbox.Anchored = true
Hitbox.CanCollide = false
Hitbox.Transparency = 0.5
Hitbox.Size = Vector3.new(7,7,7)
Hitbox.Shape = Enum.PartType.Ball
Hitbox.BrickColor = BrickColor.new("Really red")
Hitbox.CFrame = Dummy.HumanoidRootPart.CFrame * CFrame.new(0,0,-2)
Hitbox.Touched:Connect(function(Part)
if Part.Parent:FindFirstChild("Humanoid") and not Hit then
if Part.Parent.Name ~= Dummy.Name then
if Part.Parent:FindFirstChild("Humanoid").Health > 0 then
Hit = true
local player = game.Players:GetPlayerFromCharacter(Part.Parent)
Event:FireClient(player, Dmg, DmgType)
COD:FireClient(player, "Attack Dummy")
end
end
end
end)
Debris:AddItem(Hitbox, 0.1)
end)
wait(Animation.Length-0.1)
end
end
Not really sure if this would work for ur case since idk how u want it to be but you can try to use raycasting or you can use a custom Hit module that detects the “.Touched” function way better
anyways, you really don’t want to use .Touched for hitboxes, because it relies on physics and is very inconsistent
don’t worry, your code doesn’t require much editing, you just need to change up the .Touched for something like GetPartBoundsInBox() or GetPartsInPart()
here’s an example code snippet:
local box = workspace:GetPartBoundsInBox(box.CFrame, box.Size)
for _, bodyPart in box do
local character = bodyPart.Parent
if not character then continue end -- you want to use continue in this
-- this is because returning will stop the entire loop, so if the box array
-- ever has a non-player part as the first index, damage won't be dealt
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid then continue end
-- deal damage here
end
just a bit of a suggestion, but you don’t have to follow it
instead of having a boolean like “Hit”, you could instead have a table called hitPlayers and add any player’s character to it upon being hit, then clear it after x seconds
you could prevent “hit-stacking” via one line:
if table.find(hitPlayers, character) then continue end
EDIT:
if you don’t want the enemy to be able to hit multiple players, you could instead use Raycasting like @ efsane14010 suggested (not mentioning because i don’t wanna flood his notifs)
TL;DR
use raycasting for hitting one enemy, use the methods i suggested for AoE (area of effect) damage