Help with raycasting for melees?

So, I tried making a hitbox with gettouchingparts but I learned raycasting is a the best way to do this.
I’ve been trying to make my own with for a rpg also please do not link me other user’s assets I am trying to learn how to do this. here is my code:

rs.Remotes.Slash.OnServerEvent:Connect(function(plr,tool)
	if not debounce[plr.UserId] and tool and tool:FindFirstChild("Handle") and tool.Handle:FindFirstChild("DmgPoint") and tool.Handle:FindFirstChild("DmgPoint2") and game.ServerStorage.Tools:FindFirstChild(tool.Name) then
		debounce[plr.UserId] = true
		local stats = require(game.ServerStorage.Tools[tool.Name].Stats)
		local ray = Ray.new(tool.Handle.DmgPoint.WorldPosition,tool.Handle.DmgPoint.WorldPosition-tool.Handle.DmgPoint2.WorldPosition)
		local part,pos = workspace:FindPartOnRay(ray,plr.Character,false,true)
		if part and not game.Players:GetPlayerFromCharacter(part.Parent) and part.Parent:FindFirstChild("Humanoid") then
			print(part.Parent.Name)
		end
		wait(stats.rate)
		debounce[plr.UserId] = false
	end
end)

also here is a image of what dmg points are

I’m not quite sure what your issue is from your post. However, you might be having an issue because you only raycast once during the slash attack. If the target is not along the ray during that one cast, it will not count as a hit.

I’m sure others on the form may have other opinions and I admittedly don’t have a great deal of experience with weapons, but have you considered just listening to the Touched event on the weapon? You will want to keep track of when the slashing animation begins and stops to make sure you only cause damage during the attack. You will also want to store a list of the parts/models/humanoids that were damaged during the animation to ensure you only inflict damage on each hit enemy once per slash.

do u know a way i can do that? with the rays multiple times

If you still want to use rays, you can put a loop into the wait sequence that runs the raycast check multiple times during the attack. For example:

rs.Remotes.Slash.OnServerEvent:Connect(function(plr,tool)
	if not debounce[plr.UserId] and tool and tool:FindFirstChild("Handle") and tool.Handle:FindFirstChild("DmgPoint") and tool.Handle:FindFirstChild("DmgPoint2") and game.ServerStorage.Tools:FindFirstChild(tool.Name) then
		debounce[plr.UserId] = true
		local stats = require(game.ServerStorage.Tools[tool.Name].Stats)
    local waitedTime = 0
    while waitedTime < stats.rate do
      local ray = Ray.new(tool.Handle.DmgPoint.WorldPosition,tool.Handle.DmgPoint.WorldPosition-tool.Handle.DmgPoint2.WorldPosition)
      local part,pos = workspace:FindPartOnRay(ray,plr.Character,false,true)
      if part and not game.Players:GetPlayerFromCharacter(part.Parent) and part.Parent:FindFirstChild("Humanoid") then
        print(part.Parent.Name)
      end
		  waitedTime = waitedTimed + wait(.1) -- Shorter wait is less preformance but more accurate
    end
		debounce[plr.UserId] = false
	end
end)

I apologize for the wonky formatting on the code.

still doesn’t print after i hit a dummy

print the part before the if statement. Your day might be incorrect or your filter list may be incorrect.

so i got it to work whats the best amount to wait if im doing this? im going to try using a variable to check if it hit EDIT: variable worked so nvm

if part and not game.Players:GetPlayerFromCharacter(part.Parent) and part.Parent:FindFirstChild("Humanoid") then
    part.Parent.Humanoid:TakeDamage(stats.damage)
	if tool and tool:FindFirstChild("Handle") and tool.Handle:FindFirstChild("Sound") then
		tool.Handle.Sound:Play()
	end
end
1 Like

Some developers will suggest to run the check on heartbeat and others will say it’s not worth it. If you don’t have performance issues, attaching to heartbeat could work.

I would still use OnTouched personally but what you have certainly works.