Is it even possible to have an accurate weapon hitbox that grabs all touching parts (including noncollide)?

Alright, so before everyone spams this thread with “use .Touched or :GetTouchingParts()”, I’ll go over why I am not using them;

  • .Touched is easily exploitable due to replication, to the point where the client could straight-up delete the transmitter and it’d prevent them from taking any damage on the server (even if exists for the briefest moment).

  • :GetTouchingParts() is what I currently use, but it sadly doesn’t grab CanCollide parts. Having a collidable sword brings about a whole ordeal of trouble, from flinging to a hacky mess.

  • Rays could be useful here as they don’t require any loops and generally dont lag much, but I’m unsure how accurately they would grab parts & how I’d do it. I’m also unsure about the lag aspect of it, depending on the amount of math needed.

  • Magnitude would require lots of math to check if a part is slightly within a part, but I’ll probably retort to this measure or the previous one if I dont find a solution.

  • Region3s wouldn’t work due to them not supporting rotation (using the previous two would be better).

So, what do I want to achieve?

Well, as the thread title says, I want to accurately grab all the parts that a sword is touching but also have the sword non-collidable, with minimal math / lag.

I tried setting the sword to cancollide true, but whenever slashing into a wall it pushed me very abruptly away from it (it should be clear as to why).
I am thinking about somehow utilizing collision groups, but I’m unsure about that.

I looked through a lot of threads and sites and even asked a lot of my friends, but none of them could come up with a plausible answer other than math.
If math would be the answer, please do help me with it, I barely know a thing or to about it :slightly_smiling_face:

Thank you for reading!

5 Likes

I’m not an expert with this, although I do think rays are a possibility.

I think that some sort of collision group system can achieve what you’re trying to achieve, it’ll have to be a bit hacky, but it’s the simplest solution I can recommend to get around the get touching parts collide issue.

Yeah, I’ll be testing out rays in a moment.
Kind of sad that theres no parameter for GetTouchingParts to also grab non-collidable parts.

You should ask it as an engine addition honestly, I don’t see it being a complicated method to be implemented (probably one line of code).

I think the collision group method will fit better, it’s just a bit harder to get the logic.

I think I have a solution, actually.
Simply run 4 rays that follow along the tip of the sword to the bottom of it.
Visualized, it’d be something like this:
image
The sword would be the rectangle and the arrow would be the ray.
I think it’d only need minimal math, so I hope this works when I test it out.

This could also allow for easy editing of the hitbox.

1 Like

Hello, have you ever considered taking a look at Raycast Hitbox 4.01: For all your melee needs! ?

It’s the perfect thing for you to use in this specific case, however if you do not want to use the module directly then I suggest forking it and just remaking what you want in your code style, I think that’s the best method of doing it!

2 Likes

Never really been a fan of big module scripts, especially when I don’t know how the code works.
It’s much easier for me to work with code I am familiarized it, especially considering how this code is object oriented (mine isn’t).

Remaking it would take too long, as I’d also have to re-read through the code several times to understand how it works.

What I would do is use both :GetTouchingParts() and :Touched.

I’ve read in another thread how to get parts with can collide false hitboxes:

So basically you create a touched event and disconnect it after :GetTouchinfParts is called:

local Hitbox = -- the hitbox

local Connection = Hitbox.Touched:Connect(function() end)
local Parts = Hitbox:GetTouchingParts()
Connection:Disconnenct()

Although these are things that you don’t want, it works perfectly fine.

As I said, I am making a sword for PvP, so using the Touched event would just lead to people exploiting it and thus giving themselves god-mode, even if it exists for the briefest moment.

Otherwise this would be a good answer, though.
Very sad that it’s exploitable :slightly_frowning_face:

1 Like

This is actually a weird behaviour of how GetTouchingParts work. If there is not a TouchTransmitter within the part, it won’t pick up anchored and non collide parts. A simple solution is to connect an empty .Touched event before calling GetTouchingParts, and then disconnect it later. In the case of a sword it would make sense to hold a global connection and never disconnect until the sword is dequipped. This is more efficient than connecting and disconnecting for each GetTouchingParts call.

Please refer to my thread and the post above; I’ve stated why it’s not a good idea to use it.

I don’t see what you’re referring to. What I described above addresses the issue with non collide parts. Like I said, the reason it doesn’t capture non collide parts is because this behaviour requires a TouchTransmitter to be available in the part. The Touched event itself is only used to create a TouchTransmitter.

1 Like

I clearly stated that exploiters can delete said connection (the TouchTransmitter), which would lead to them not being affected by the .Touched event whatsoever (due to it not even registering them in the first place).

Deleting the TouchTransmitter is the same as stopping the event.

1 Like

Hmm. This is something I didn’t think of. You’re correct that, due to the TouchTransmitter instance existing within the character it can be deleted. In this case, you can actually detect its removal and recreate it. Another solution would be to give the player a hitbox outside of their Character and simply move this on Heartbeat to match their character’s position. You could use a block scaled/moved to their model’s GetBoundingBox. This would solve the other issue, and setting the part to non collide/anchored would ensure a client can’t tamper with it.

Additionally, here’s an experimental idea that may or may not work which could slightly improve performance and network cost: Because Camera instances isolate their children from replicating to the client you could place the hitboxes on the server within a Camera instance per player. Physics would not execute, however, assuming a TouchTransmitter is in existance it would allow GetTouchingParts to work properly despite Touched never ever actually firing.

Believe it or not, but with the stupidity of roblox, deleting touchtransmitters even outside of the character would replicate…

This wouldn’t be as efficient as using rays, they’re made to be lightweight and there is no reason for us not to use them here.

I think what @avozzo said in his fourth post is the best way to approach this, you should totally look at it!

1 Like

Hmm. This is very strange behaviour if this is true. In this case, you might as well attempt the Camera idea. This would prevent the TouchTransmitter from being visible to the client, thus preventing it from being destroyed by the client.

I’d be better of just using the ray idea I posted as BasedFX said above, it’d just be too complex at that point.

Yep, this is definitely true. It’s just up to personal preference I suppose, and there are definitely issues with GetTouchingParts (and apparently even some I was unaware of originally).

I think the ray solution would work best. You may be able to use four rays, one traveling along top to bottom, one traveling bottom to top. You could do this for the left and right side of the part, and this would ensure that the edges of the sword always detect a hit no matter the angle. You’d need to do this on Stepped (or Heartbeat, you’ll still get similar results) to get visually accurate hits (Note: Heartbeat runs immediately before physics are calculated, and Stepped runs after physics are calculated, and before replication)

Also the reason you’d go top to bottom is due to the back side of triangles not being hit by a ray. When a ray is cast it only will hit the outside faces of parts, but if the ray starts within the part you won’t detect a hit (for example if the player’s arm is within the tip, or base of the sword). It’s definitely not necessary, and it’s up to you if you prefer that accuracy over the performance cost it creates.

Just a comment after some testing it appears that if the touchinterest is under your character the other clients are not able to destroy it. However if the part is under workspace and you do not set the network ownership to the server then it the client can destroy it.

It’ll not “replicate”, I believe it’s because of how network ownership behaves, since the client closest the part in this case your client, it’ll be the one emulating the physics for that specific part and therefore it’ll be the one that tells the server that the part is touching/the TouchTransmitter fired.