Need help with accurate collision detection

You can write your topic however you want, but you need to answer these questions:

I am making a fighting game with combos and such, I need accurate hit detection so that I can make the player slam into walls to take damage and make vfx debris and such.

All the methods that I have tried so far are not very accurate, this is mainly what I need help with

I’ve tried .Touched which was pretty garbage considering it only worked around 50 percent of the time, I used raycasts pointing towards the victims velocity as they move through the air, but it is very weird and inaccurate. Pretty sure I tried a few other things too cant recall though, been at this for quite a while now.

Any help will be much appreciated :smiley:

Hello Baby_Goroth2!

ROBLOX actually just recently released a new API similar to :GetTouchingParts(). Check it out below, it should be pretty good for this purpose if you run it every frame while an attack is in progress, just make sure you clean up your connections well!

https://developer.roblox.com/en-us/api-reference/function/WorldRoot/GetPartsInPart

This function looks pretty good, but how would I implement it? Would I just loop for every part that the player can collide with? If so, that seems pretty taxing on the server because I have a pretty large map with lots of parts…

Im not sure if this is correct but open a baseplate and add a part and add a script in the part

Make the script say

while wait(1) do

print(script.Parent:GetTouchingParts()

end

If I remember correctly, GetTouchingParts is a very expensive function. Instead, you should probably use a bunch of raycasts to simulate a hitbox.

The function that arccitecc proposed is a new function by roblox that is not :GetTouchingParts, and because it is new i don’t think it will be that laggy, the only reason it would be laggy in my game however is because looping through hundreds of part 3-8 times simultaneously would be pretty taxing…

According to kleptonaut, it’s basically the same in terms of performance:

I see… Well, if that is too taxing, especially for my game, how would I go about my goal of accurately detecting collisions of the player?

Do a line of raycasts, or have a module do it for you:

1 Like

Hmm, seems like a pretty good module, but I don’t think it’ll work in my case. I’d have to add attachments to all the players in my game through a script if I don’t wanna use startercharacter and seems like a hassle to do. I feel that raycasts are the answer however, but how would I go about that? I tried making the raycasts go in the direction of the players velocity, but it is always really wonky and sometimes goes in strange directions.

Hello BabyGoroth2!

If you manage your connections correctly, this should have no effect on performance as it would only be running :GetPartsInPart() while the attack is in progress. I have written you some sample code on how to implement something like this; note that this is a very raw and incomplete implementation and you could do caching to make sure attacks can’t double-register for a single player.

As long as you manage all connections (as I did below), performance should not take a hit.

local part = script.Parent -- change this to the path of your part
local connections = {}
local attackingvalue = script.Parent.Values.Attacking
local runservice = game:GetService("RunService")
local cooldown = os.clock()
--
attackingvalue:GetPropertyChangedSignal("Value"):Connect(function()
	if attackingvalue.Value then
		table.insert(connections,runservice.RenderStepped:Connect(function()
			local parts = game.Workspace:GetPartsInPart(part,OverlapParams.new()) -- you can add a table of settings inside this overlapparams, for example, to excluse the players own character
			for i,v in pairs(parts) do
				local player = game.Players:GetPlayerFromCharacter(v.Parent)
				if player then
					if os.clock() - cooldown >= 1 then
						print(player.Name,"was struck by melee weapon")
					end
				end
			end
		end))
	else
		for i,v in pairs(connections) do
			v:Disconnect()
			connections[i] = nil
		end
	end
end)

This seems like a pretty good script, currently it only detects what one part is touching correct? if so, all I think I would need to add is a for loop to cycle through all the parts in the map. Is this correct? Also, what is the attacking value? Would that be in the victim’s character or the player’s? Also also, the victims root part base position is not going inside of the wall so would it even detect the collision? Also also also, I would need the exact position that the victim collided with the part so that I can have a point to originate the debris from.

Hello Baby_Goroth2!

:GetPartsInPart() detects all the parts that are currently inside that part, even by .001 studs. I provided the sample code for handling debounce + finding the character.