skeleton:hitTest()¶
functionOverview¶
Tells which bounding-box attachments (Spine “hit areas”) of the skeleton contain a point, top-most first.
x and y are content coordinates, like a touch event’s event.x and event.y. hitTest converts
them once with skeleton:contentToLocal() to skeleton space: the skeleton object’s local coordinates, with y
growing downwards, the space of bone.worldX and bone.worldY. The skeleton object’s position, scale and
rotation and those of its parent groups are taken into account.
The bounding boxes are tested in draw order, last drawn first, so a draw order changed by an animation changes
the order of the hits. This differs from Spine’s SkeletonBounds.containsPoint, which returns the first box in
slot order.
Without a listener, hitTest returns the hit table of the top-most box containing the point, or nil. With a
listener, it calls the listener with a hit table for every box containing the point, top-most first, like touch
propagation: a listener that returns true stops the walk. hitTest then returns true if a listener stopped
the walk, else false. The walk also ends, with no further listener call, when a listener removes the skeleton or
changes its skin or any slot’s attachment. An error raised in the listener reaches the hitTest caller.
Only geometry counts: a slot whose bone is inactive (for example a skin bone while its skin is not set) is skipped,
and the slot’s current attachment is used. isVisible = false, alpha 0 and hidden slots do not prevent a hit,
unlike Solar2D touch.
hitTest reads the current world transform, the one recalculated by spine.create(), skeleton:updateState() and
skeleton:draw(). A bone moved with bone:setWorldPosition() or bone.x is hit at its new position after the next
updateState or draw.
After skeleton:split(), split slots are still tested in the skeleton object’s space and draw order. They hit correctly only while their split group has the same content transform as the skeleton object; move the split group and its bounding boxes are still tested where the skeleton object would draw them.
Raises when the skeleton was removed, when x or y is not a number, and when listener is neither a
function nor nil.
Syntax¶
local hit = skeleton:hitTest(x, y)
local handled = skeleton:hitTest(x, y, listener)
Parameters¶
x,y(required):number– The point in content coordinates.
listener(optional):function– Called with a hit table for each box containing the point, top-most first. Returntrueto stop.
Hit table¶
slotName:string– The name of the bounding box’s slot.attachmentName:string– The name of the bounding-box attachment.target: the skeleton object.x,y:number– The content coordinates passed tohitTest.localX,localY:number– The same point in skeleton space.
Example¶
Top-most hit¶
local function onTouch(event)
if event.phase == "began" then
local hit = skeleton:hitTest(event.x, event.y)
if hit and hit.attachmentName == "head" then
print("Head tapped")
end
end
return true
end
skeleton:addEventListener("touch", onTouch)
Every hit¶
local function onTouch(event)
if event.phase == "began" then
skeleton:hitTest(event.x, event.y, function(hit)
print("Hit", hit.slotName, hit.attachmentName)
if hit.slotName == "shield" then
return true -- stop here: the boxes below are not reported
end
end)
end
return true
end
skeleton:addEventListener("touch", onTouch)