How would I create a hitbox in the shape of a cone?

I’ve got an attack that requires a triangular hitbox:

But I’m unsure of how to go about this as making multiple square hitboxes would not only be inaccurate but inefficient as well

4 Likes

you could look at this as a sector of a circle, which takes up a 90 degree angle.

then you can raycast/shapecast a line at every 1 degree angle or something similar

local length = 10
local sectorAngle = 90

local startPoint = CFrame.new(0, 5, 0)

local visuals = Instance.new("Folder")
visuals.Parent = workspace
visuals.Name = "visuals"

local rayFilter = RaycastParams.new()
rayFilter.FilterDescendantsInstances = {visuals}
rayFilter.FilterType = Enum.RaycastFilterType.Exclude

local objectsHit = {}

for angle = 1, sectorAngle do
	local xLength = math.cos(math.rad(angle)) * length
	local zLength = math.sin(math.rad(angle)) * length
	
	local endPoint = startPoint * CFrame.new(xLength, 0, zLength)
	local displacement = (endPoint.Position - startPoint.Position)
	
	-- raycast
	
	local rayHit = workspace:Raycast(startPoint.Position, displacement, rayFilter)
	if rayHit and not table.find(objectsHit, rayHit.Instance) then
		table.insert(objectsHit, rayHit.Instance)
	end
	
	-- visualization:
		
	local part = Instance.new("Part")
	part.Size = Vector3.new(0.5, 0.5, displacement.Magnitude)
	part.CFrame = CFrame.lookAt(startPoint.Position + displacement / 2, endPoint.Position)
	part.Anchored = true
	part.Parent = visuals
end

print(objectsHit)
1 Like

How many rays is too many?
The attack is quite large so I’d have to make the angle very small per array to avoid this:

Not sure, but to my knowledge rays are pretty performant so it’s worth giving it a shot and seeing if you encounter any performance issues.

maybe you can use workspace:GetPartsInPart()

yeah just tested spawning in a ton of rays, it should run fine thanks

1 Like

I just realized that multiple players standing in a line wouldn’t be detected as the ray would only hit the first one right? I may need to find an alternate solution

1 Like

Maybe you can use GetPartBoundsInBox and replace the raycast e.g:

local boundSize = Vector3.new(0.5, 0.5, displacement.Magnitude)
local boundCFrame = CFrame.lookAt(startPoint.Position + displacement / 2, endPoint.Position)
local touchingParts = workspace:GetPartBoundsInBox(boundCFrame, boundSize, overlapFilter)
for _, touchingPart in ipairs(touchingParts)do
	if not table.find(objectsHit, touchingPart) then
		table.insert(objectsHit, touchingPart)
	end
end
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.