Is it possible to have it only keep on returning humanoids if it hits them? I have a sword that does a “double slash”(it hits all the body parts) and I don’t know if it will detect it twice.
None of the DetectionModes fit my usage
Is it possible to have it only keep on returning humanoids if it hits them? I have a sword that does a “double slash”(it hits all the body parts) and I don’t know if it will detect it twice.
None of the DetectionModes fit my usage
Use Bypass to make your own hit filtering system, and check to see if the humanoid exists once you hit a part.
hitbox.DetectionMode = RaycastHitbox.DetectionModes.Bypass
hitbox.OnHit:Connect(function(hit)
local humanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
if humanoid then
--- Do stuff. The same humanoid will also keep being returned per frame.
end
end)
Bypass is pretty much the raw hit detection, you can make anything out of it.
Is there some sort of internal api that I can use for filtering? Or should I just recast the hitbox every time its hit.
edit: ill just check for one part
Use tables to keep track of humanoids it hit. For example,
local doubleSlashTargets = {}
hitbox.DetectionMode = RaycastHitbox.DetectionModes.Bypass
hitbox.OnHit:Connect(function(hit)
local humanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
if humanoid then
--- Record humanoids hit
if not doubleSlashTargets[humanoid] then
doubleSlashTargets[humanoid] = 1 --- Set it to 1 since we just hit them the first time
else
doubleSlashTargets[humanoid] += 1 --- Add one to the amount of times we hit them
end
--- Ignore additional hits if we reach over 2
if doubleSlashTargets[humanoid] > 2 then
return
end
humanoid:TakeDamage(100)
end
end)
I’m not sure how your double slash works but another easy way to make it slash twice is to call :HitStop() once the first slash ends (this resets the targets from the internal filtering), then call HitStart() once the second slash comes out.
In my game, I have a lot of moves that multi-hits, and I use the above strategy of just hitstopping parts that is considered a new slash in the move and works just as well.
Yeah, I thought of this but I thought it would be janky
This might be a problem with my code or with the way I handle my tool animation, but for some reason, the Hitbox points are being offset by quite a bit.
Here is my code for setting up the hitbox:
function Weapon:SetUpHitbox()
local HitboxParams = RaycastParams.new()
HitboxParams.FilterDescendantsInstances = {self.Character}
HitboxParams.FilterType = Enum.RaycastFilterType.Blacklist
local Hitbox = RaycastHitbox.new(self.Tool.Handle)
Hitbox.RaycastParams = HitboxParams
Hitbox:SetPoints(self.Tool.Handle, {Vector3.new(0, 0, 1), Vector3.new(0, 0, 2), Vector3.new(0, 0, 3)})
return Hitbox
end
Here is my code for the player swinging:
function Weapon:Swing()
if self.SwingDebounce then return end
self.SwingDebounce = true
if self.LastSwing == 3 then
self.LastSwing = 1
self.CurrentSwingAnimation = self.Animations["Swing1"]
else
self.LastSwing += 1
self.CurrentSwingAnimation = self.Animations["Swing"..self.LastSwing]
end
self.Hitbox:HitStart()
table.insert(self.PlayingAnimations, self.CurrentSwingAnimation)
self.CurrentSwingAnimation:Play()
local CurrentAnimationStopped
CurrentAnimationStopped = self.CurrentSwingAnimation.Stopped:Connect(function()
if not self.IsEquipped then return end
table.remove(self.PlayingAnimations, table.find(self.PlayingAnimations, self.CurrentSwingAnimation))
self.Hitbox:HitStop()
self.SwingDebounce = false
CurrentAnimationStopped:Disconnect()
end)
end
I am using this method to animate my tool handle, but it shouldn’t interfere with the hitbox.
Thanks!
Is this server-sided? If it is, check and see if the server sees your character/tool in a different place. Sometimes this can be a problem when you are teleported somewhere or you teleport the tool.
My weapon system is in fact server sided. However, the tool is not being teleported, and the weapon creation happens after the player is teleported (a new weapon object is created, and then a cloned tool is parented to the player). Also, I checked to make sure that all the parts of the sword are in the right place, which they are. I did notice the offset stays the same, any suggestions?
Hi, if you don’t mind, would you be able to DM me a barebones repo place containing the weapon and the scripts that you used to parent it to the player? Just to make sure if it’s something I can fix or a user script error that I can help diagnose.
Sure, no problem! Thanks for being so supportive and responsive. I really appreciate it!
ya be kinda speaking some fax
@TeamSwordphin Hello there! I am using your raycast hitbox for my melee mechanics, but when I slash with the tool it will damage myself and THEN damage someone else. Is there a way to blacklist myself so it won’t detect a local player?
You can use RaycastParams.
hitbox.RaycastParams = RaycastParams.new()
hitbox.RaycastParams.FilterDescendantsInstances = {myCharacter}
hitbox.RaycastParams.FilterType = Enum.RaycastFilterType.Blacklist
Solved! Just used CFrame rather than position to teleport the player and it worked like a charm. Not sure why thought .
I don’t actually use this module, I like it a lot, I find it pretty good, I don’t use it because I don’t work with front-end stuff.
I wonder why you went with still having a “Signal” module anyway? It doesn’t behave like a normal event, it can only have one connection, it doesn’t have any other features like :Wait
, they’re more like a callback, so why not just go with a normal callback?
I know you might have you know, keep some things similar to older versions, but I feel like it was kind of a missed opportunity with the release of 4.0, I know that you made that Signal to be as instant as possible, obviously, but in that case you could just make it into a normal callback,
and it would be even faster to call too.
function Hitbox.OnHit(hit)
print(hit)
end
--// Fire
local _onHit = self.OnHit
if _onHit then
task.spawn(_onHit, hit) --\\ You can use `task.defer` too, it will run later though of course. Don't know how that affects your use-case.
end
If you were to go with an actual signal instead of just making it into a callback, then I recommend GoodSignal or FastSignal
GoodSignal is interesting for your use-case because it has routine recycling which is really cool for use-cases like yours which might require it to fire super quickly.
How would i convert my v3 to v4?
local plr = script.Parent.Parent.Parent
local char = plr.Character
local idle = char.Humanoid:LoadAnimation(script.Animations.Idle)
local equipped = false
local attacking = false
local RaycastHitbox = require(game.ServerScriptService.RaycastHitboxV2)
local Hitbox = RaycastHitbox:Initialize(script.Parent.Weapon)
durability = 7
local attack1 = char.Humanoid:LoadAnimation(script.Animations.Attack1)
local broken = false
Hitbox.OnHit:Connect(function(hit, humanoid)
if humanoid.Parent ~= char and humanoid.Parent.Handler.Infected.Value == true then
script.Parent.Weapon.Hit:Play()
local damage = math.random(15,35)
local Speed = 25
local Force = 40000
local TotalForce = Force
local KnockBack = Instance.new("BodyVelocity",hit.Parent:FindFirstChild("Torso"))
KnockBack.MaxForce = Vector3.new(TotalForce,TotalForce,TotalForce)
KnockBack.Velocity = plr.Character:FindFirstChild("HumanoidRootPart").CFrame.LookVector * Speed -- based on the direction YOUR character is facing.
game.Debris:AddItem(KnockBack,0.1)
humanoid:TakeDamage(damage)
humanoid.Parent.Actions.Stunned.Value = true
if durability == 0 then
Hitbox:HitStop()
script.Parent.Weapon.Transparency = 1
script.Parent.Weapon.B:Play()
script.Parent.Weapon.ParticleEmitter:Emit(50)
game.ReplicatedStorage.EditGUI:FireClient(plr,"text","Your baseball bat broke.")
broken = true
idle:Stop()
attack1:Stop()
wait(2)
script.Parent:Destroy()
end
durability = durability - 1
end
end)
script.Parent.Equipped:Connect(function()
if not plr.Character.Actions.Stunned.Value == true and not broken then
idle:Play()
equipped = true
else
plr.Character.Humanoid:UnequipTools()
end
end)
script.Parent.Unequipped:Connect(function()
idle:Stop()
equipped = false
end)
script.Parent.Activated:Connect(function()
if not attacking and equipped and not plr.Character.Actions.Stunned.Value == true and durability >= 0 then
attack1:Play()
attacking = true
script.Parent.Weapon.Prepare:Play()
wait(0.16)
Hitbox:HitStart()
script.Parent.Weapon.Swing:Play()
wait(0.4)
Hitbox:HitStop()
wait(2)
attacking = false
wait(0.4)
end
end)
plr.Character.Actions.Stunned.Changed:Connect(function()
plr.Character.Humanoid:UnequipTools()
end)
Good point. I already have a newer version utilizing GoodSignal and task which both supports the single callback and multiple connections (not sure when I’ll update), but thanks for the heads up. I’ve been meaning to get rid of the older signal module for a while now but I decided to wait until tasks were officially released.
@DogGuyTheThird You tried looking at the main post? I put some instructions on how to convert it.
I couldnt find it? can you show it to me?
The bottom of this post contains the new APIs, basically, you just need to switch out the old methods with the new ones. It shouldn’t take too long.
so since:
got removed do I have to:
RaycastHitbox.new
Hitbox:Destroy?