Raycast Hitbox 4.01: For all your melee needs!

Yea the hit detection is done client side, here’s a little snippet on the order I call the events in:

(renamed the module “Kenjutsu_HitDetection”)

local Hitbox = Kenjutsu_HitDetection:Initialize(ServerHold, {plr.Character})
Hitbox:HitStart()
Hitbox.OnHit:Connect(function(hit, humanoid)
	if game.Players:GetPlayerFromCharacter(humanoid.Parent) then
		SentInfo["enemyPlr"] = game.Players:GetPlayerFromCharacter(humanoid.Parent)
		Kenjutsu_Events:WaitForChild("Damage_Request"):FireServer(SentInfo, workspace.Universal_Tick.Value)
	end
end)
local Used_Slash_Set = Slash_Moveset["Slash"..CurrentSlash]
				
local SlashAnim = MASTER_Anim_Module.Fire("Combat", Used_Slash_Set.."_Slash"..CurrentSlash)

SlashAnim.Stopped:wait()
Hitbox:HitStop()
Kenjutsu_HitDetection:Deinitialize(ServerHold)

Can you double-check if this portion of the code is being reliably fired? From my tests, Stopped sometimes does not work or does not call correctly (I’ve notified an engineer about this beforehand but I’m unsure of the outcome, I think they are still looking into it). Initialize will return the preexisting hitbox if it wasn’t deinitialized and if it does, it will see HitStop was never called which can explain why some of your hits don’t actually register.

Hello! I’m using this script as-shown in the API notes; however, I’m getting this error:
image

I have this script placed in the client (in the weapon that fires it), with the module as a child of said script. The debugger says the error occurs here: image

Here is my relevant code:

local RaycastHitbox = require(script.RaycastHitboxV3)
local hitRays = RaycastHitbox.Initialize(weapon, {player.Character})
...
local attacking = false

local function attack(actionName, inputState, inputObj)
	if not attacking then
		if inputState == Enum.UserInputState.Begin then
			attacking = true
			
			playAnimationForDuration(swing_1, calcStats.spd)
			
			--hitRays:DebugMode(true)

			hitRays.OnHit:Connect(function(hit, humanoid, results)
				humanoid:TakeDamage(calcStats.atk) -- will connect to the server later
			end)
			--

			-- testing!
			hitRays:HitStart()
			wait(swing_1.Length)
			hitRays:HitStop()

			attacking = false
		end
	end
end

Some notes:

  • The attachments are on a meshpart of the weapon and are called “DmgPoint” (which is what I still have it configured as)
  • Every part of the rest of the script works, and functions correctly when I use it with my less desirable hitbox system
  • There are objects other than parts in the weapon model, such as the script (I don’t think this would matter as the script searches for attachments)

I’m not really sure what’s going on, so if you could take a look and point me in the right direction, that’d be great! Let me know if you need anymore info.

1 Like

Unless you have edited the module, .Initialize() should be instead :Initialize(); with a colon symbol. Sometimes that error is caused by this.

Added a print to double check if that code was firing, and it still prints when the hits aren’t being properly detected.

SlashAnim.Stopped:wait()
print("slash anim stopped")
Hitbox:HitStop()
Kenjutsu_HitDetection:Deinitialize(ServerHold)

Hmm, if possible, can you try initializing once and never deinitializing? Is there a reason that you need to deinitialize? Seems like you are reusing the sword hitbox so you probably don’t need to do this. It will help with performance as well and it will guarantee the hitbox will be available and resetted without delay (deinitialize does not remove the hitbox immediately, it only removes it on the next heartbeat frame).

You also mentioned that putting more attachments didn’t work. Have you tried making the hitbox slightly wider? If none of these suggestions worked, I’ll diagnose it a bit further by reusing your script you’ve given me in my own tests to see if its a script or a module issue.

Alright, I’ve tried initializing once and never deinitializing, and also making the hitbox wider. The problem still persists.

Oh, I’ve also been wondering, do I need to deinitialize if the part that’s initialized is destroyed?

EDIT: I found the solution, just needed to add a wait() when ChildAdded is fired. Hitbox not firing occasionally still happens though, so this code may still be relevant to help you figure out what I’m doing wrong.

I actually tried a completely different approach with only having to initialize once every time the sword is actually created, and the hitbox doesn’t want to work at all now. I actually had to do some workarounds to get the first test going, and I thought this would fix that. It’s not throwing any errors and all the prints are printing as intended.

local Player_Swords_Folder = Runtime_Swords:WaitForChild(plr.Name)
Player_Swords_Folder.ChildAdded:connect(function(child)
	if child.Name == "ServerHold" then
		local ServerHold = child
		local Kenjutsu_Hitbox = Kenjutsu_HitDetection:Initialize(ServerHold, {plr.Character})
				
		local KenjutsuHitboxActivate_Connect
		KenjutsuHitboxActivate_Connect = Activate_KenjutsuHitbox:GetPropertyChangedSignal("Value"):connect(function()
			if Activate_KenjutsuHitbox.Value == true then
				print("start")
				Kenjutsu_Hitbox:HitStart()
				Kenjutsu_Hitbox.OnHit:Connect(function(hit, humanoid)
					if game.Players:GetPlayerFromCharacter(humanoid.Parent) then
						if SlashType == "Normal" then
							NormalSlashInfo["enemyPlr"] = game.Players:GetPlayerFromCharacter(humanoid.Parent)
							Kenjutsu_Events:WaitForChild("Damage_Request"):FireServer(NormalSlashInfo, workspace.Universal_Tick.Value)
						elseif SlashType == "Heavy" then
							HeavySlashInfo["enemyPlr"] = game.Players:GetPlayerFromCharacter(humanoid.Parent)
							Kenjutsu_Events:WaitForChild("Damage_Request"):FireServer(HeavySlashInfo, workspace.Universal_Tick.Value)
						end
					end
				end)
			elseif Activate_KenjutsuHitbox.Value == false then
				print("end")
				Kenjutsu_Hitbox:HitStop()
			end
		end)
		local DestroyedConnect
		DestroyedConnect = ServerHold.AncestryChanged:connect(function()
			if ServerHold.Parent == nil then
				print("de initialized")
				Kenjutsu_HitDetection:Deinitialize(ServerHold)
				Kenjutsu_Hitbox = nil
				if DestroyedConnect then
					DestroyedConnect:Disconnect()
					DestroyedConnect = nil
				end
				if KenjutsuHitboxActivate_Connect then
					KenjutsuHitboxActivate_Connect:Disconnect()
					KenjutsuHitboxActivate_Connect = nil
				end
			end
		end)
	end
end)

Here is the result: https://gyazo.com/25521d3fc9175b5f82a6a0cd9c3d389a

As you can see in the output, all the prints fire like the system is working as intended. Does anything I’ve done stick out to you as incorrect at all?

1 Like

You do not need to deinitialize if the part is already destroyed.

I don’t see anything out of the ordinary so far. Does anything from RaycastHitbox print anything when it initializes? Does it see your attachments?

1 Like

Yep just checked it’s working properly and detects my attachments, everything working perfectly now except for occasionally not detecting hits.

2 hours and I could not find this simple mistake. Thank you!

2 Likes

I have a feature request, or maybe its there but I couldn’t find how to do it in the API docs.

When I do hitBox:HitStart() it would be really nice to allow it to accept arguments that will be passed into the OnHit event. For example, I might want to name this particular :HitStart() like so:

hitBox:HitStart({Name = "Foo"})

now when I receive the OnHit event like so:

    hitBox:OnHit:Connect(function(hit, humanoid, rayCastResults, groupName,  myTable)
        if myTable.Name == "Foo" then
            -- do stuff
        end
    end)

I will give you an example use-case to go along with this. I am starting and stopping the hit to reset the de-bounce in a for loop. It would be amazing to be able to pass the for loops control variables into the hit. In this example I am looping the hit 3 times and on the third hit, I do double damage. Currently I think I have to construct a new hitbox and connect it fresh for each loop, or maybe just the third one. Being able to pass some parameter into HitStart and the resulting OnHit connection would greatly simplify this sort of thing.

This would make my life easier and also interesting! Thank you :slight_smile:

Heya, I don’t know if you still reply to this post but basically I have a question about the “ignoreList” in Beginner Examples · Swordphin/raycastHitboxRbxl Wiki · GitHub

Basically I’m making a brand new hitbox for projectiles and it works perfectly, though it damages the caster and I have no idea how to make it ignore the caster and not damage him, since this module is mainly used for swords.

Anything I can try that would fix it?

Hey, is it viable to use these hitboxes on the server, and have no hitbox detection on the client? (Would remove the need for me to add sanity checks etc)

Hi, I have a question. Once you use initialize does the hitbox only create once even if you try to create it multiple times?

Just go to mention that the hitbox is extremely accurate!
Thank you so much for this great module.

1 Like

Is there a way to control “How long can a ray last ?” cause if the character is moving so fast it still makes rays behind it that if someone hits the ray he still get damaged even though the caster is far away from him.

Hey all, sorry for the long replies! Long story short I had some health complications which ended up with multiple hospital visits. Though everything should be okay now so I should be back to having support here :slight_smile:

Anyone with the same questions above who ended up becoming unanswered should repost/reply underneath me so I can take a look at any problems that people are still having.


@ShokuTakahashi The rays only draw in one frame, and the positions are based on velocity. I don’t think there is a reliable way to tell time with the way the module works. I think a better solution is to have a range limit so even if you are trailing at light speed, you won’t have a lingering ray in your previous position. Perhaps you can try looking into the MainHandler in the heartbeat loop to see if you can implement this.

@Neotrinax The hitbox only creates once yes. Initialize will always return a pre-existing hitbox that has been created previously.

7 Likes

Good that you are okay. I failed trying to make it so maybe i can wait till you can add it in an update for the module. Thats too much advanced for me atm.

V.3.3 Stable

New Feature: Did you ever want the hitbox to turn off after a few seconds automatically? Don’t like wait()? Hate using more threads just so your script doesn’t yield? Featuring the new Hitbox Time Scheduler!

Additional information can be found here, though here is a summary from that page for those who don’t want to click onto Github:

Instead of using wait(), spawn(), or delay() which are prone to throttling, consider using RaycastHitbox’s internal custom time scheduler to automatically switch the hitbox off for you. Using this will allow you to continue the script without it yielding. It is extremely simple to use, all you need to do is give HitStart a number. The module will use its preexisting loop to calculate the time automatically with no added performance cost. No hassles and no additional threads created.

local turnOffAfterThisAmountOfSeconds = 5

Hitbox:HitStart(turnOffAfterThisAmountOfSeconds) --- Turns off after 5 seconds automatically

--- Does not yield the thread, the script will automatically continue
print("Hey! I still print!")

Calling HitStop prematurely will automatically cancel the timer as well.


Before anyone asks, once PostSimulation is released, I will update this module accordingly to supersede the now deprecated Heartbeat.

12 Likes