Raycast Hitbox 4.01: For all your melee needs!

So should I create a connection and then disconnect it once getmarkerreached runs once? Because the first time it happens the hitbox.hit thing hasn’t run yet, but when it does the boolean is nil. (the first time it runs it’s true, times after that it’s nil). Keep in mind this happens in just one swing.

Correct, that is the basis for how to use it. Basically you would call HitStart/Stop whenever you want to turn on the hitbox (to detect enemies) and respectively, turn off the hitbox (to prevent hit detection). Now, people ask me what’s the best way to use it but honestly it depends on your own game. So at the end of the animation is ideal, also at the end of a swing as well, so its what you think feels right.

Sorry if I don’t understand, but could you clarify this point? It may be just late and I’m tired lol.


@0therw0rldly

You can possibly flip the positions of HitStart and OnHit event (which is what I do and encourage to do as it basically guarantees the event to be created by the time the hit detection starts).

--- This order instead

Hitbox.OnHit:Connect()
   -- blah
end)
Hitbox:HitStart()

Yeah, you can disconnect it once EnableHit is called, though might be best to disconnect it when the animation has stopped instead (the same place you put HitStop()) in case your animation has multiple EnableHits you want to utilize.

1 Like

Yeah, but even on the first swing this happens and my animation only has one enable hit.

Hmm, not sure. I just tested it with the revised ordering (as indicated from my last post) and the boolean is detected, regardless of its actually nil or an actual value.

If you are still stuck and don’t mind sharing a little bit of your system with me, you can send a simple repo place with the problem and I’ll be happy to diagnose it for you.

Alright, so here’s what it’s outputting. First, it runs once and prints it as true (keep in mind I just swung it in the air) then it’s on the same line but somehow runs three more times even though the swing function has only run once, and it prints nil those last three times.

function module.Swing(AnimTable, Tool, Damage, UserHumanoid, Hitbox, Special)
	local Handle = Tool:FindFirstChild("Handle")
	if Hitbox then
		local ChosenAnim = #AnimTable > 1 and AnimTable[math.random(1, #AnimTable)] or AnimTable[1]
		local TouchConnection
		ChosenAnim:Play()
		print(Special)
		ChosenAnim:GetMarkerReachedSignal("EnableHit"):Connect(function()
			print(Special)
			TouchConnection = Hitbox.OnHit:Connect(function(hit, Hum)
				print(Special)
				if Special == true then
					print("YEE")
					if WeaponSpecials[Tool.Name] then
						WeaponSpecials[Tool.Name](Hum)
					end
				end
				Hum:TakeDamage(Damage)
				HitSound(Hum.Parent)
			end)
			Hitbox:HitStart()
		end)
		ChosenAnim.Stopped:Connect(function()
			Hitbox:HitStop()
		end)
	end
end

Currently the output I’m speaking of is the line below ChosenAnim:GetMarkerReachedSignal

Not sure why it’s running multiple times, I only have one animation event in there.

@TeamSwordphin uuhh hello? Sorry to bother, just wondering if you know.

Good Module for now I can just double damage mobs which is kinda good but here is my question can I make the rays even longer than its current length?

Sorry, was busy. I would recommend trying to replicate this in a separate, empty place with just the swing module and a simple tool and see if the problem persists (the problem does not show itself on my end at least).

Without video footage it’s a bit harder to visualize but I assume the Special gets printed once, then an additional 3 times (making it x4 in total). Again, I recommend disconnecting the GetMarkerReachedSignal once the animation stops (though admittedly I have not used that function a lot so it is maybe different from KeyframeReached).

There a few solutions that you can try.

  1. Double check if there are multiple EnableHit markers on your animation by accident
  2. Does the problem persist when you remove the OnHit event and leave it to print merely by reaching the EnableHit marker?

This problem seems to be out of the scope of this module so if there is still some persistent problems, I’ll be happy to help over in DMs instead.


@FerbZides Refer to the end of this post on how this module works, there is not really a determined length that you can easily change.

Though I guess if you want to scale up the distance (ie. overshoot the rays a little), you can go into the MainHandler script and go to around line 56:

local raycastResult = workspace:Raycast(rayStart, rayDir, Object.raycastParams)

You can probably do something like rayDir * LENGTH or something.

2 Likes

I noticed the red ray that comes out of the weapon I use this on, does it show up in-game?

Those are the debug rays. They are meant to show you the position of them. Objects within those red lines are considered hit.

Yes, they will show up in the game. It’s on by default because most of the time scripters need to see where they start and end.

You can disable it in the main module, scroll down till you see the version and debugmode bool, and turn it false to disable it.

1 Like

Hey, I have a question regarding the API. Does the .OnHit event have some sort of delay? I am asking because for a knife system that I am creating, there is a delay on .OnHit when it touches a part. This is especially concerning with a knife throw system I am currently creating. When the knife hits the part, the knife should get anchored so that it creates a stuck-to the wall effect, but due to the delay the knife passes through the wall before being anchored. Is there something that I am missing or doing incorrectly?

Thanks,
-Nick

Is the OnHit server or client side? You can use the RaycastResult the OnHit returns to reposition the knife upon being anchored as well.

1 Like

All the knife system is handled from the server, I only use the client to detect mouse input for the actual throw. I use .OnUpdate to constantly update a position variable, and I set the position to it after anchoring the knife as you suggested, but it is fairly choppy. That’s why I was wondering if there is a better solution, to make it look smooth.

If the server is lagging, that will be its longest delay. The module uses Heartbeat, so it will check for collision between frames. If there is lag, Heartbeat will stall and update less often, which will in turn also make OnHit not as accurate.

Handling anything server sided is choppy because replication runs at around 15 - 20hz (versus the buttery smooth 60hz on the client). If smoothness is the priority, I would opt to run the knife throw on the client side and have other clients replicate the same knife going out of the user, making the actual throwing portion smooth and hit detection a bit more accurate (though you will need to put a bit more server sanity checks to prevent people from just cheating the system).

Server sided knife throw
This choppiness you refer to is the server latency and there is not much you can do about it. You can try tweening to make it a bit smoother.

Client sided knife throw
Preferably, all hit detection should be done on the client with the server doing sanity checks to see if the client is cheating or not. This makes the experience a lot better and makes your game much more responsive in turn for less security.


Alternatively, instead of using OnUpdate to update the position, I would use RaycastResults, and it probably will be more performance efficient since it activates on the hit. This is what I basically used for the server example above.

hitbox.OnHit:Connect(function(hit, _, raycastResult)
     local normal = raycastResult.Normal
     local position = raycastResult.Position

     myKnife.Anchored = true
     myKnife.Position = position
end)
4 Likes

As you just showed, client sided throw is way more smooth. Are you basically recommending that I handle the hitbox including :HitStart() and :HitStop() as well as the tool activation events on the client and fire the server to deal damage/check if the hit was possible? I handled it on the server assuming giving the client control of a hitbox would open up a variety of vulnerabilities.

Alternatively, I set network ownership of the knife from the server, and fired the client to add body movers/ hooked up a touch event as well. When the touch event fired, I anchored the knife, which would replicate to the server. It is my first time using this API, and it’s pretty good, but I chose to do this on the server due to the example game + my own perception.

Yeah, preferably everything on the clients (includes hitstart/stop). Then you can tell other clients to draw the projectile on their screen too.

It won’t be as vulnerable if you do proper sanity checks, it’s just a bit more work but the payoff is worth it. One easy sanity check is to make sure if the client tells the server they hit the target, don’t trust them, instead do a raycast between the aggressor and the hit target to ensure that nothing is between them. You can also do a magnitude check as well, so if the aggressor is a 100 studs away from the target, and your throwing skills should only be around 20 studs, then that’s a red flag. You would also want to check for activation/cooldown speed as well, (don’t want people to be spamming the remote event). These are just a few examples but it all depends on what makes sense in your game.

4 Likes

Hello @TeamSwordphin,

I’m using this amazing module for a game I’m working for. It’s working great but there’re some problems I have.

I have some kind of rush attack where a character will punch multiple times in one go.
I modified the module so there’s a setting where you can disable/enable the feature that the hit box will always take a fresh humanoid. That part works fine. However, sometimes I do the attack, the damage points/red parts are not aligned with the attachments. You can see that in this GIF:

https://gyazo.com/b21d042678a109f63222100c240e36ad

As you can see the damage points are nowhere close to the hands/arms, where it should be. Sometimes it works fine, but most of the time it does this.

Here’s a GIF of whenever it does work, which happens rarely:

https://gyazo.com/6e84c9874d996bf6b9c166c86e480cb7

And here’s an image of the positions of the attachments, which are connected to the hands respectively:

image

Any idea what I did wrong or what’s causing this?
If you need to see the scripts, please DM me.

3 Likes

Is the hitboxing clientside or serverside? Double check the stand’s position on the server side. A previous user with a similar stand had the same issue as you where the raycasts were not following the animation of the stand when using this module server sided.

We found out that the animations and positions doesn’t really replicate properly (still unsure of the source of this problem, either because the stand was a descendant of the player or the player owns the physics of the stand).

The hit box is server sided. Is there a solution?