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
