New to this, where should I be putting this solution?
Check my github for latest patches. Download version 4.01a
Hey I cant find a download for this edit:
nvm found it
Hey I get a bug
19:11:31.733 ReplicatedStorage.Modules.RaycastHitboxV4.Solvers.Bone:39: Expected , got âmoduleâ - Studio - Bone:39
with
return solverlocal module = {}
in bone, please help!
can you send me an example place file to further invstigate?
Am I able to use this module on the client for hit-detection?
Yes, thats exactly what this does.
Hit detect on client then fire to server for validation. Thats what Im doing in my current project
Is there a way to only have the debug visualizer visible on the client?
Hi all,
This resource is no longer supported and has been superseded by ShapecastHitbox. While the library is still usable today, it contains some bugs and performance issues that the original team is no longer addressing. You are welcome to fork the project and publish improvements if you wish.
Thank you all for supporting this project for the last 6 years, you all are awesome!
hi there, ive been using this for a while⌠is there any way to make the hitbox go with the object when you play an animation on the client? so far ive only found out that the hitbox is correct if you play it serversided cuz that prevents hacking the hitboxes if im not wrongâŚ
i would love help because that will def make my experience better
You can play the animation both on client and server.
yes but once i play it on the client the hitbox isnt correct with the tools thats the problem im facing
is there a way to make dismemberment with this?
This is a hitbox library, is not related to dismemberment in any way. You can make dismemberment with this module, but it wonât help you do the actual dismemberment itself.
Ie. Detect parts with this library, then make your own interface to decouple the parts from the rig once you do.
Is there a way you can detect exactly which attachment hit in the OnHit event?
As far as I remember, there isnât a way. You can go inside the Hitboxcaster and edit it to make it return the attachment on this line:
Change this
ActiveHitboxes[i].OnHit:Fire(part, humanoid, raycastResult, point.Group)
with:
ActiveHitboxes[i].OnHit:Fire(part, humanoid, raycastResult, point.Group, point.Instances[1])
The last parameter will return the attachment.
I know it is no longer being supported but I decided I might as well try my luck, I am making a combat system using this and it works most of the time but sometimes it doesnât detect.
I have tried a lot of different things to fix it but I am kind of stuck any help would be greatly appreciated. I do the raycast and detection on the client but then I do the damage on the server. It works fine maybe 85% of the time but sometimes it just doesnât detect the victim
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LocalPlayer = Players.LocalPlayer
local Tool = script.Parent.Parent
local Mouse = LocalPlayer:GetMouse()
local Character, Humanoid, Animator
local remotesFolder = ReplicatedStorage:WaitForChild("Remotes")
local onHitEvent = remotesFolder:WaitForChild("OnHitEvent")
local RaycastHitbox = require(ReplicatedStorage:WaitForChild("Modules"):WaitForChild("RaycastHitboxV4"))
local Handle = Tool:WaitForChild("Grip")
local Body = Tool:WaitForChild("Grip"):WaitForChild("Cutlass")
local HitboxPart = Tool:WaitForChild("Hitbox")
local VariablesFolder = Tool:WaitForChild("Variables")
local Clicked = VariablesFolder:WaitForChild("Clicked")
local Count = VariablesFolder:WaitForChild("Count")
local Equipped = VariablesFolder:WaitForChild("Equipped")
local Inspect_Ready = VariablesFolder:WaitForChild("Inspect_Ready")
local isSharp = false
local baseDmg = 8
local attackWindows = {}
local HIT_WINDOW = 0.5
local activeHitboxConnection -- Track active hitbox
--// Raycast params
local excludedParts = {workspace:WaitForChild("BulletVisuals")}
local rayParams = RaycastParams.new()
rayParams.FilterDescendantsInstances = excludedParts
rayParams.FilterType = Enum.RaycastFilterType.Exclude
local newHitbox = RaycastHitbox.new(HitboxPart)
newHitbox.RaycastParams = rayParams
local Equipped = false
--// Animations + chain timings
local AnimationsFolder = Tool:WaitForChild("Animations")
local animData = {
{anim = AnimationsFolder:WaitForChild("Slash"), chainTime = 0.7, hitboxDelay = 0.1},
{anim = AnimationsFolder:WaitForChild("Slash2"), chainTime = 0.6, hitboxDelay = 0.1},
{anim = AnimationsFolder:WaitForChild("Slash3"), chainTime = 1, hitboxDelay = 0.1}
}
local IdleAnim = AnimationsFolder:WaitForChild("Idle")
local PulloutAnim = AnimationsFolder:WaitForChild("Pullout")
local loadedIdle, loadedPullout
local loadedAttacks = {}
--// Update character refs
local function updateCharacterReferences()
Character = LocalPlayer.Character
if Character then
Humanoid = Character:WaitForChild("Humanoid")
Animator = Humanoid:WaitForChild("Animator")
excludedParts = {Character, workspace:WaitForChild("BulletVisuals")}
rayParams.FilterDescendantsInstances = excludedParts
newHitbox.RaycastParams = rayParams
end
end
updateCharacterReferences()
LocalPlayer.CharacterAdded:Connect(updateCharacterReferences)
--// Cleanup old attack windows
local function cleanupWindows()
local now = tick()
for i = #attackWindows, 1, -1 do
if attackWindows[i].finish < now - 1 then
table.remove(attackWindows, i)
end
end
end
--// Improved hitbox management
local function startHitbox(duration)
-- Stop any existing hitbox first
pcall(function() newHitbox:HitStop() end)
if activeHitboxConnection then
task.cancel(activeHitboxConnection)
activeHitboxConnection = nil
end
-- Start new hitbox
newHitbox:HitStart()
-- Use a single consistent timer
activeHitboxConnection = task.delay(duration, function()
pcall(function() newHitbox:HitStop() end)
activeHitboxConnection = nil
end)
end
--// Equip
local function Tool_Equipped()
Equipped = true
updateCharacterReferences()
if not Animator then return end
Clicked.Value = false
loadedIdle = Animator:LoadAnimation(IdleAnim)
loadedPullout = Animator:LoadAnimation(PulloutAnim)
loadedAttacks = {}
for i, data in ipairs(animData) do
loadedAttacks[i] = Animator:LoadAnimation(data.anim)
end
Body.Transparency = 1
task.wait(0.2)
Body.Transparency = 0
--Equipped.Value = true
loadedPullout:Play()
task.wait(loadedPullout.Length)
loadedIdle:Play()
Clicked.Value = true
Count.Value = 0
end
--// Unequip
local function Tool_Unequipped()
Equipped = false
if loadedIdle then loadedIdle:Stop() end
if loadedPullout then loadedPullout:Stop() end
for _, a in ipairs(loadedAttacks) do
a:Stop()
end
-- Clean up hitbox properly
pcall(function() newHitbox:HitStop() end)
if activeHitboxConnection then
task.cancel(activeHitboxConnection)
activeHitboxConnection = nil
end
--Equipped.Value = false
Count.Value = 0
Inspect_Ready.Value = true
task.wait(0.5)
loadedIdle:Stop()
end
--// Play attack with chain window
local function playAttack(index)
local data = animData[index]
local animTrack = loadedAttacks[index]
-- Stop any other attack animation currently playing
for _, a in ipairs(loadedAttacks) do
if a.IsPlaying then
a:Stop()
end
end
-- Stop any existing hitbox before starting new attack
pcall(function() newHitbox:HitStop() end)
if activeHitboxConnection then
task.cancel(activeHitboxConnection)
activeHitboxConnection = nil
newHitbox:HitStop()
end
script.Parent.Parent.Swing:Play()
animTrack:Play()
-- Single timing system for hitbox
task.delay(data.hitboxDelay, function()
-- Record attack window
local startT = tick()
table.insert(attackWindows, {
start = startT,
finish = startT + HIT_WINDOW,
number = index
})
-- Start hitbox with consistent timing
newHitbox:HitStop()
startHitbox(HIT_WINDOW)
end)
-- Allow chaining early
task.delay(data.chainTime, function()
Clicked.Value = true
end)
animTrack.Stopped:Connect(function()
if Count.Value >= #animData then
Count.Value = 0
end
end)
end
--// Main attack handler
local function Tool_Activated()
updateCharacterReferences()
if not Character or Character:GetAttribute("Stunned") then return end
if not (Clicked.Value) then return end
if Equipped == true then
cleanupWindows()
Clicked.Value = false
Count.Value = Count.Value + 1
if Count.Value > #animData then
Count.Value = 1
end
playAttack(Count.Value)
end
end
--// Hit detection
newHitbox.OnHit:Connect(function(hitPart, hitHum)
local now = tick()
local foundNumber
for i = #attackWindows, 1, -1 do
local w = attackWindows[i]
if now >= w.start and now <= w.finish then
foundNumber = w.number
break
end
end
foundNumber = foundNumber or 1
local finalHit = (foundNumber == #animData)
-- VFX
local vfx = game.StarterPlayer.StarterPlayerScripts["Replicator(combat)"].HitVFX.Blood_Attack:Clone()
vfx.Parent = hitHum.Parent.HumanoidRootPart
game.Debris:AddItem(vfx, 1)
for _, v in ipairs(vfx:GetChildren()) do
if v:IsA("ParticleEmitter") then
v:Emit(v:GetAttribute("EmitCount"))
end
end
onHitEvent:FireServer(hitHum, isSharp, baseDmg, foundNumber, finalHit)
end)
--// Cleanup loop
task.spawn(function()
while Tool.Parent do
task.wait(3)
cleanupWindows()
end
end)
--// Connections
Tool.Equipped:Connect(Tool_Equipped)
Tool.Unequipped:Connect(Tool_Unequipped)
Mouse.Button1Down:Connect(Tool_Activated)
I know raycasthitbox does have a sort of inaccuracy issue. Only solution I have for you is to increase the amount of attachments. Also ensure you turn on the debug mode on to see if the rays are actually hitting them.
I know this answer is not what youâre looking for, but ShapecastHitbox also has a raycast option, and requires very minor API changes to migrate to. Accuracy should be improved there.
certainly just detect the body part name and then detect the motor 6d matching it⌠then you just destroy that motor6d and there you go the body part falls of
This is my problem with the Raycast V4:
- NPCs that are already exist in the workspace with the script inside it that handles and create the raycasthitbox.new(Tool) things, works normally
- due to the huge amount of NPC which need to be spawned, I have written an only script for all NPCs also apply the raycasthitbox.new(Tool)
- I will explain using the picture
- Every NPCs spawned has this bug
- without the raycast, spawned NPCs canât perform more actions
