Im making a soccer game and For my game hitbox, Im using a Square Part welded to my player character and inside of it , there is script that have a touched function that detect The ball whenever its touching the Hitbox
its working fine but Now the Issue that is annoying me is that there is a delay when the Goalkeeper want to catch the ball that is moving at high velocity
the hitbox is reacting Way too slow that the ball enter the net before the hitbox does anything
Now im wondering what is the best hitbox for stuff like that, idk if touched is the best way to be honest
Im thinking to make the hitbox client side but i guess it will be easy to exploit. What do you guys think?
I’d look into using this. It returns a list of parts, but if you limit the maximum amount returned to just 1 and apply a filter to only check for the soccerball, a simple check to see if they’re touching can be like this:
-- Beginning of the script somewhere
local Hitbox = -- Put it here.
local Ball = -- Soccer Ball here.
local OP = OverlapParams.new()
OP.MaxParts = 1
OP.FilterType = Enum.RaycastFilterType.Include
OP.FilterDescendantsInstances = {Ball}
-- Later in the script
local BallFound = workspace:GetPartsInPart(Hitbox, OP)
if (BallFound) then
local SoccerBall = BallFound[1] -- It will always be the first thing in the list
end
From my experience I’ve found this to be way better and consistent than .Touched. In reality, you should probably never use touch and always opt to use something better.
I’m sure there’s plenty of ways to do hitboxes, (and I’m not even sure if this is super performant or the best way) but this should work well.
I’m not sure what your goal is performance-wise but a potentially faster method for detecting if the ball is where it needs to be is to check its magnitude frame by frame on the server and if its a set distance register it as a “hit”. I would recommend playing around with this idea first to make sure it works as I have not actually done something like that.
you could improve performance and only perform the check when the ball gets kicked and is expected to hit the net or goalkeeper.
Yes, you would need a loop. There’s a lot of ways to optimize it, and some that I can think of would be doing everyone all at once in a single heartbeat on the server (I do this in a lot of my games). This way you don’t have individual loops running all doing the same thing, rather just one big one that handles all of the players. Once every frame or every other frame is sufficient and shouldn’t stress the game.
To make it more performant, make sure your hitboxes have everything physics related turned off besides CanQuery. Only scan for the ball if the soccerball is x amount of studs from the character. If you’re doing this radius check, make it large to accommodate those high-velocity scenarios. 30 Studs would be a good distance to continuously check for parts. Since you’re only using spatial queries on 2 parts at a time (the hitbox and the ball) it’s already pretty performant of a check.
Depending on your game, you might only want to check for touches at certain times within a game. Make sure to keep that in mind and use it to your advantage for more performance.
I will try your solution tommorow, But one thing, How can i make one single loop that check for All Players hitbox, Should I add the hitboxes into an array and make the loop check for every hitbox in that array?
-- In your server script
local RS = game:GetService("RunService")
local Characters = {}
-- Use Player Added / Leaving Events to insert their characters into the table.
--[[ Example:
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(char)
table.insert(Characters, char)
end)
end)
]]
RS.Heartbeat:Connect(function(dt)
for i, Character in pairs(Characters) do
end
end)
You can use the modulus operator (%) to run checks at a slower rate, i.e every other frame.
ok so I tried it, and it only work if the ball is not moving, if the ball is moving at high speed, its dosent even react to it, touched event was working better but it had a delay
im confused , what is wrong ? im really lost on what should i use for hitbox at this point
Could I see your code for your loop? Maybe there are some improvements to make. If spatial queries don’t work out, I’d definitely give magnitude checks a try instead like @mantorok4866 suggested.
I actually found a way to fix this issue, I decided to make only the gk mechanics client side (which reduce the delay a little bit) but there is still a small delay and the ball will go inside the net before the hitbox react, so what i did, i made the net goal detection wait 1 second and check again if the ball is still inside, this way if there is delay, it will not count it as a goal, and if the gk actually didn’t catch the ball, the ball will stay inside for at least 1 second , which means its a goal