I want to cast a ray that finds all parts that obstruct its path. Here is my current code:
local frac = 360 / numRays
for angle = frac, 360, frac do
local ray = getRayAtAngle(rootPart, angle, searchDistance )
local part = game.Workspace:FindPartOnRayWithIgnoreList( ray, { rootPart } )
if part ~= nil then
if part.Parent.Name == "Dummy" then
game.ReplicatedStorage.Events.DamageReplication:FireServer(game.Players.LocalPlayer,part.Parent.Humanoid ,"Player", 45)
end
end
end
The 15 is the damage indicator for my game, so as shown in the picture it only shows up once because the ray stops upon hitting the first enemy
The purpose of this is because after realizing how unreliable the touch event was, I decided to create a hitbox by casting multiple rays around the player. However, I am creating a shockwave AoE attack and that’s when the problem lies. If there’s an enemy behind another enemy, the damage will only be dealt with by the enemy in front because the ray stops upon hitting its first part. So I was wondering if there was a way for the ray to continue casting and find the obstructing parts, or maybe suggest a different way to deal with reliable hitboxes for AoE attacks.
Use magnitude they are really really good and efficient do checks on both client and server so the server take less stress.
You have to have an array of enemies which you could iterate through it and get the magnitude
Use a folder to put all of your enemies into. then get children
Ex.
local mag = (pos - pos1).Magnitude
if mag <= 5 then
--Code
end
From what I can remember, there’s isn’t a built in function that does this with a ray, you need to create some custom implementation to do that, you can try this
function findAllPartsOnRay(ray)
local targets = {}
repeat
local target = game.Workspace:FindPartOnRayWithIgnoreList(ray, targets)
if target then
table.insert(targets, target)
end
until not target
return targets
end
That I found from this post and it was marked as the solution
It will require you to make a change in your code to accustom for receiving a table, something like this if had to guess, would be this after inserting the function in your script
local frac = 360 / numRays
for angle = frac, 360, frac do
local ray = getRayAtAngle(rootPart, angle, searchDistance )
local parts = findAllPartsOnRay(ray)
for i,hitpart in pairs(parts) do
if hitpart.Parent.Name == "Dummy" then
game.ReplicatedStorage.Events.DamageReplication:FireServer(game.Players.LocalPlayer,hitpart.Parent.Humanoid ,"Player", 45)
end
end
end
instead of doing raycasts, you could check the distance between rootparts like this
local distance = (myHumanoiRootPart.Position - TargetRootPart.Position).Magnitude
if distance <= range then
--do something
end
then you could make a raycast to see if there are any objects between the 2 players. Also you need to verify the position for every player/dummy so for I,v in ipairs() do might be needed.
A trick I learned from shader dev is that you can represent a point on a line segment as
p = origin+(direction*t)
To make it work for rays just make sure t is positive. T is basically like how far to travel across. What I am trying to get from this is you could like get the surface normal of a part then get a point on it somehow, maybe some size offset with position crap. If you can get a test point on the thing you can just implicitly set up the algebraic problem like
Just make sure that normal:Dot(direction) is a positive number else u will get projection errors. From there now u can do a simple aabb check with the verticies on the face. Now we have a way of checking how many parts were intersected (have 1 plane per part or have a checker ig)
This video tells pretty much the same math except he uses triangles instead btw