Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How to determine if a model is within a cylinder?

Asked by 10 years ago

For my Bleach RPG, I am creating a Cero beam attack that will launch out and damage enemies. It's pretty much a basic cylinder mesh that launches forward (like a Kamehameha from Dragon Ball), and will damage whatever enemy character is within the beam. I managed to get it to work, but I feel that there is a better way to do this.

Here's what I did so far...

function clamp(n, bound)
    if n > bound then
        return bound
    elseif n < -bound then
        return -bound
    end
    return n
end

_G.ClosestPointOnPart = function(point, part)
    local p = part.CFrame:vectorToObjectSpace(point-part.Position)
    local hz = part.Size/2
    local pointOnPart = Vector3.new(clamp(p.x, hz.x), clamp(p.y, hz.y), clamp(p.z, hz.z))
    return part.Position + part.CFrame:vectorToWorldSpace(pointOnPart)
end

--[[
CheckCylinderCollisions returns a table of every enemy within the cylinder.

table targets - Variable contains every enemy model we want to check for collisions
Vector3 base - The start position of the cylinder
int dist - How long the cylinder is (not used)
Vector3 lv - The direction the cylinder is pointing
int max_dist - The radius of the cylinder

]]

_G.CheckCylinderCollisions = function(targets,base,dist,lv,max_dist)
    local new_targets = {}
    for i,v in pairs(targets) do
        local h = v:findFirstChild("Humanoid")
        if h and h.Health > 0 then
            local pos = _G.ClosestPointOnPart(base,v.Torso)
            --local dist2 = (base-pos).magnitude
            --local A = CFrame.new(base,pos).lookVector
            --local B = lv --*dist
            --local d = math.sqrt(dist2^2-A:Dot(B)^2)
            local p1 = (base-pos)
            local p2 = (p1:Dot(lv))*lv
            local d = (p1-p2).magnitude

            if d <= max_dist then
                local tab = {Target = v, Position = pos}
                table.insert(new_targets,tab)
            end
        end
    end
    return new_targets
end

1 answer

Log in to vote
0
Answered by
modFrost 130
10 years ago

The more efficient way to do this is to use raycasting, cast a ray from the intial position the the end position. After that use FindPartOnRay() to return the hit parts.

Ad

Answer this question