It doesn’t seem like the delay is caused by your module, as it’s only delayed for about a frame or slightly more.
Also, could you help me with an error I’m facing that wasn’t present before using your module?
local Success = false
local newHitbox, connected
newHitbox, connected = HitboxModule.new(HitboxParams)
newHitbox:Start()
newHitbox:WeldTo(Character.HumanoidRootPart, CFrame.new(0,0,-4))
newHitbox.HitSomeone:Connect(function(hitChars)
for i,v in pairs(hitChars) do
local Hit = Dmg:executeDamage(v) --> returns true when damage is registered
if Hit then
Success = true
print(Success) --> prints true
end
end
end)
print(Success) --> printed true before but now prints false
Okay, so what I’d do first of all is set up all your connections and methods prior to starting the hitbox.
So weld and connect to the HitSomeone signal before running the Start method at the end. That might be why there’s a couple frames of delay on your server-sided hitbox.
Make sure your code is actually returning true, the signal should guarantee at least one model with a humanoid whenever it’s fired so it should definitely be running the loop just fine.
Seems like putting the methods before starting the hitbox fixed the delay, but the real problem is that my script does return true and it even prints true for success but outside the for i,v in pairs it doesn’t. Also is it a good idea to make projectile hitboxes with this?
Very cool and thank you for sharing, but i believe a few other modules like this already exist. What are the benefits of using this over something like MuchachoHitbox or FastCast?
Looks like you’re printing right after connecting to the signal, which hasn’t been fired yet, which means Success hasn’t been changed to true yet either. Try printing Success after a delay of a few seconds and try and hit something with the hitbox within that time like so.
Here’s the code I used to test it.
local HitboxModule = require(ReplicatedStorage.HitboxClass)
local HitboxTypes = require(ReplicatedStorage.HitboxClass.Types)
local Success = false
local newHitbox, connected
local hitboxParams = {
SizeOrPart = 5,
DebounceTime = 1,
} :: HitboxTypes.HitboxParams
newHitbox, connected = HitboxModule.new(hitboxParams)
newHitbox:WeldTo(Character.HumanoidRootPart, CFrame.new(0,0,-4))
newHitbox.HitSomeone:Connect(function(hitChars)
for i,v in pairs(hitChars) do
local Hit = true
if Hit then
Success = true
print(Success) --> prints true
end
end
end)
newHitbox:Start()
print(Success) --> this prints false because you print directly after connecting to the signal
task.delay(3, function()
print(Success) --> since I delayed Success to be printed, in that span of time the signal was fired, changing this to true
end)
Sorry, I assumed you printing at the end was meant to be somewhere else printing, and not directly after haha
Yes, you can make projectile hitboxes with it just fine. I use it for ranged slashes and other projectiles like bullets (to give them more leeway than just raycasting) and some fireball-type moves, just remember if the projectile is on the server, turn off velocity prediction since you’re not attaching it to a player, which can run its own simulation of the game which would call for velocity prediction.
I’d recommend you make the projectile on the client and then just handle the hitbox on the client. When the client responds, you can take the time it took for them to respond with the time the projectile started, get the direction and speed it was going, and then use that to figure out the approximate location of the projectile in order to verify hits. You can check out the logic on my other thread here: Network Efficient and Safe Practices with Projectiles.
FastCast is used for raycasting, which is great for smaller projectiles that you want to be really accurate like bullets in an FPS. But for larger things you normally see in fighting games and RPGs that include magic like fireballs, a lot of those projectiles are simply too large for raycasting to be a feasible solution, since if you’d want to cover a large projectile, you could easily start firing 80+ raycasts just to cover the impact surface. You also run into an issue where they’re too accurate, giving players some leeway in their hits enables a more responsive experience.
Again, for stuff like an FPS game where accuracy is a must, FastCast is absolutely the best choice.
MuchachoHitbox is a great resource, however, it’s not type-checked, and it doesn’t allow easy access to client-sided hitboxes like HitboxClass does. Unless you change the hitboxes on the client in some way, hitboxes are entirely synced, and all you had to do was require it, set the UseClient parameter to the player that’ll run the calculations, and then use it exactly like a normal hitbox.
HitboxClass also gives you access to a couple more methods of detection, like GetPartsInPart and magnitude. You can also easily check dot-products for magnitude via the DotProductRequirement option in the HitboxParams. You can use that to cut down your magnitude hitbox into parts of a sphere. You could, for instance, ensure magnitude hitboxes only hit in front of the player rather than behind them by checking for a dot-product of 0.
Awesome. Also, would it be more or less optimal to use this for stationary hitboxes than using region3s? I have a hitbox function that uses region3s for detection, and its just a simple call of :GetPartsInBoundBox(). If i were to use HitboxClass instead would it be more or less performant? I mainly use this function for repeated attacks like punches and kicks, so it needs to be able to be called multiple times in a row without performance issues.
HitboxClass’s Hitbox objects connects to Heartbeat, then the performance really depends on what detection method you use. Magnitude is the most performant, as it’s just distance checks, while GetPartsInPart is the most expensive, checking the entire geometry. GetPartBoundsInBox/Radius is kinda in the middle.
The performance gain of using your method is entirely dependent on how you use it. If you call your Region3 method exactly when you need it, and you only call it a single time, the performance is technically more optimal, since you risk less empty checks, and that also means less cycles. If you connect to heartbeat and allow the hitbox to be checking for a certain amount of time, then HitboxClass provides the exact same thing without using a deprecated method. Just use the InBox option in the SpatialOption parameter in the HitboxParams.
You can stop the Hitbox object using the Stop method, which would allow you to give the players some leeway in their hits if you allow the hitbox to be out for a certain amount of time. Like if one of your kicks checks for hits for 0.15 seconds, stop the hitbox after 0.15 seconds.
So it’s really up to you. IMHO the performance gain/take isn’t very substantial and negligible, it entirely depends on what detection method you use and whether or not you want it to be incredibly precise by checking once, or giving the players some leeway by checking for a certain amount of time. HitboxClass provides the exact same thing as Region3’s, except it’s intended to provide leeway by having you Start and Stop the hitbox when needed.
This method kind of worked but now the problem is that I need it to be true immediately. I tried to reduce the delay, but anything below 0.1 will be false. Is there any way to fix this.
That sounds like a logic issue, why do you need it to instantly be true? Why not spawn a separate thread, wait for it to be true, and then run your code asynchronously? Just cancel it when you don’t want it to be checking anymore.
Hey, are the hitboxes in your video client-sided or server-sided? How did you handle the hitbox for the projectile move? Can you add a feature that lets us detect when the hitbox hits an object itself and not necessarily a player since this feature can be used to add effects such as the object breaking or just some visual and auditory effects?
In the velocity prediction video, both are server-sided. For the video of my game, the melee one is client-sided since it relies on character movement, while the projectile one is server-sided.
For the projectile, I get where the player is aiming their mouse, I have a static formula that determines how long the potion will take to reach the destination, so after that certain amount of time I do the VFX and start 2 hitboxes, one for the explosion and the other for the poison floor.
Object-detection will likely come in a future update, since it shouldn’t be too troublesome to add.
Really well-made, currently using it for a project and it has been doing wonders, it has fixed nearly every issue I had with our previous hitbox system.
Fantastic resource, I look forward to future updates.
You can pass in any BasePart into the SizeOrPart parameter and use the InPart SpatialOption if you want to have a custom hitbox with a pre-determined shape. You can also cut spheres into sections via the DotProductRequirement parameter using Magnitude mode by leaving the SpatialOption blank and just passing in a number in the SizeOrPart parameter. HitboxClass also automatically creates areas/parts using the size given when a vector3 is passed in. You can find all its interactions on the documentation.
However, once the hitbox is made, the shape is immutable unless you wish to risk changing properties of the hitbox manually without using setters.
Yes, you’re required to use the Stop() method before the hitbox part instance is destroyed if you’re using the InPart option, because that part is required to perform a spatial query. It would likely cause errors if it doesn’t have a part to work with.
If you destroy the hitbox itself instead of the part, the hitbox will automatically destroy the part as well, so you could do that instead. Handling the hitbox through the Debris parameter automatically does this as well.