What would be the best way to make a hitbox?

I am working on a game where you cut trees with an axe and I was wondering if anyone had a good way to make a hitbox for the axe and the tree? Just wondering because I am trying to find the best method to make this work efficiently

Raycasts are not ideal for this as they stop as soon as they hit something instead of getting all the parts in a hitbox, they are more of a hit-line instead of a hitbox.

The most straightforward way of creating hitboxes is through one of the these methods:

  1. For box-shaped hitboxes: Workspace:GetPartBoundsInBox(cframe: CFrame, size: Vector3, overlapParams: OverlapParams)
  2. For sphere-shaped hitboxes: Workspace:GetPartBoundsInRadius(position: Vector3, radius: number, overlapParams: OverlapParams)

Here’s an example of how you do box-shaped hitboxes

Hitbox.server.luau (a server script parented to the axe Tool):

local Workspace = game:GetService("Workspace")

local HITBOX_SIZE = Vector3.new(4, 4, 4) -- This will be the size of your hitbox
local DISTANCE_FROM_CHARACTER = 4 -- This is how far in front of your character the hitbox will be centered
local TREE_PARTS = Workspace:WaitForChild("Trees") -- Parent of all the trees

local axe = script.Parent
assert(axe:IsA("Tool"), "Make sure the script is parented to a tool")

local overlapParams = OverlapParams.new()
overlapParams.FilterType = Enum.RaycastFilterType.Include
overlapParams.FilterDescendantsInstances = { TREE_PARTS }

local function onAxeActivated()
	local character = axe:FindFirstAncestorOfClass("Model")
	assert(character, "Character not found")
	local cframe = character:GetPivot() + (character:GetPivot().LookVector * DISTANCE_FROM_CHARACTER)
	local partBoundsInBox = Workspace:GetPartBoundsInBox(cframe,  HITBOX_SIZE, overlapParams)
	print("Parts in hitbox", partBoundsInBox)
	--[[ If you only want to handle one part in the hitbox we can use
		 if #partBoundsInBox < 1 return end
		 handlePartInHitbox(partBoundsInBox[1])
	]]
end

local function initialize()
	axe.Activated:Connect(onAxeActivated)
end

initialize()

They both return an array of BasePart that you can iterate through to deal with any part that was caught in the query.

Creator Docs Pages:

2 Likes

hello, Elaugh14

You’ll want to use collision-based hitboxes or raycasting to detect when the axe hits a tree.

  1. Attach a small invisible part** to the axe head (call it “HitPoint”)
  2. On swing (click or animation trigger)
local tool = script.Parent
local hitPoint = tool:WaitForChild("HitPoint")

tool.Activated:Connect(function()
	local rayOrigin = hitPoint.Position
	local rayDirection = hitPoint.CFrame.LookVector * 3

	local params = RaycastParams.new()
	params.FilterDescendantsInstances = {tool}
	params.FilterType = Enum.RaycastFilterType.Blacklist

	local result = workspace:Raycast(rayOrigin, rayDirection, params)

	if result and result.Instance then
		if result.Instance:IsDescendantOf(workspace.Trees) then
			print("Hit tree!")
			-- Add chop logic here
		end
	end
end)

1 Like

That’s a good way to make a hitbox but I think I would prefer GetPartsBounds since it is more of a hitbox like @yieldlua said

GetPartsInPart or GetPartsBoundInBox is definitely more hitbox-like, especially if you want physical overlap rather than just ray detection. I suggested raycasting since it’s fast and precise, but if you’re going for more of a swing zone feel, bounding box hit detection is a solid pick too.

2 Likes