Hello there. I have a question for everyone who is reading this - it regards to my hitbox system.
I have a hitbox system that supports every type of character (free R15 usage) - it welds tall part named “HitBox” to the player, letting it be the hitbox of player.
And for attacks themselves I spawn a part and make a check trough :GetPartsInPart().
The issue that I encountered is performance - while singular hitboxes do well, when I try to do a hitbox that attacks multiple times - FPS (even if player’s character is outside of hitbox) strongely drops, and server gets a little bit influenced. While the server’s problem is not critical as it was playtested in a dungeon - FPS is pretty annoying, and I wish to get rid of that. (maybe it’s visually because i use TweenService for 3D VFX and with server performance it influences VFX too, but I am not sure)
For hitbox - I have script (server script, not client one) that starts like this
local EveryoneInBox = game.Workspace:GetPartsInPart(script.Parent)
local Pluy = game.Players:GetPlayerFromCharacter(script.Parent.Parent.Parent)
for i, Obj in ipairs(EveryoneInBox) do
if Obj.Name == "HitBox" then
if Obj.Parent ~= script.Parent.Parent.Parent then
print("Okay, I hit you now")
-- Then there goes all the stuff related to damaging, debuffs, velocity - those are simple enough and probably do not influence performance, as lags happen if I hit nothing in front of me
end
end
end
end
I thought that letting it first check the name of the “HitBox” would help the issue - while it was at the very start of the system I made, it doesn’t help. Neither did help making almost all character parts “CanQuery” to false, which also includes all VFX, unneeded decorations at map (bushes and e.t.c.), weapon models and other stuff.
While I can kinda understand that it happens because I loop trough script for 10 times with 0.1 seconds pause between each loop, I still do not get the idea why it hits performance so much even when I hit air. Maybe there is some method to optimize it with some sort of table or something like that?
I would strongly suggest using overlap parameters as they can be incredibly optimizing over dense or large areas. I needed to get all the parts over a 1600x1600x1600 area ( not every frame) and it could obliterate your FPS. Overlap parameters resulted in it only dropping by 30% which is huge compared to the 90% from before
The server first should keep a list of all players’ hitbox parts. Make sure you update this accordingly whenever a hitbox part gets destroyed or created (i.e. when a player’s character dies or respawns).
Then, when you want to use GetPartsInPart, pass in an OverlapParams object with FilterDescendantsInstances set to that hitbox part table and FilterType = Enum.RaycastFilterType.Whitelist. The query will then only consider those hitbox parts, and not unnecessary world geometry.
I’ve used GetPartsInPart before in a RunService.Heartbeat loop (so around 60 times per second), and I don’t recall any performance issues. Maybe there’s another cause?
I am not sure myself what could be the reason - my hitbox is just being repeated 10 times in 1 second. After all the checks shown above it does some other checks (if enemy is a player or NPC, PVP value is on and if a person is in a party with player)
Creates BodyVelocity in target’s HRP (HumanoidRootPart) and destroys old one if it exists
Creates reward value in enemy if it is not present
Deals damage (literally 1 line formula) to their separate NumberValue of HP (I do not use original Roblox HP)
Clones sound from itself into target’s HRP and plays it
Other than that there are no functions that could be looped way too much, and I even disabled “CanQuery” for all character’s accessories and body parts (not including HRP, UpperTorso and LowerTorso jus tin case), that also includes models of weapons and all models that are not required for any RayCasting (not using it yet) and other stuff.
As for “OverlapParams” - I am reading into them, so do I just put all the hitboxes that exist in the game in the table for OverlapParams (I will just get all hitboxes from players and NPCs from Workspace by :FindFirstChild(“HitBox”)) and that’s it? Because “Descendants” word confuses me a little of what I should write in the table.
Regarding performance, it all depends on what the script is having to execute. Normally in games, continuous hitboxes (DPS) have a delay time for each activation, so what you can see is all the processing that your script is having to do each time the hitbox checks who was hit. Try to reduce the processing cost by using some variables and tables.
A valuable tip for this would be to separate the possible targets of that Hitbox. Are they players? Then just create a table, store all the player characters and from there have the Hitbox check if the characters are close enough.
Try different things, because maybe GetPartsInPart might not be the best function for this, especially if your game has several parts in the workspace. (My guess is that with each call to GetPartsInPart, the function does a for loop in all the workspace instances, which can be very costly for the server if executed 10 times in about 1 second)