Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sanchedev/tiny-engine/llms.txt

Use this file to discover all available pages before exploring further.

useEvent subscribes a callback to a named event on any node reference obtained from useRefNode. TypeScript infers the correct callback signature from the node type and the event name, so the compiler will catch mismatched parameters at build time. The subscription is registered when the component mounts and is automatically torn down when the owning node is destroyed — no manual unsubscription is needed.

Signature

useEvent<N extends PrimaryNode, K extends keyof Events<N>>(
  node: NodeReference<N>,
  eventName: K,
  listener: Events<N>[K],
): void

Parameters

node
NodeReference<N>
required
A node reference created with useRefNode. The reference determines which node the event is attached to and which event names are available.
eventName
K
required
The name of the event to subscribe to. TypeScript narrows the valid event names to those actually present on the node type N.
listener
Events<N>[K]
required
The callback function. Its parameter types are inferred from the node type and event name combination, so no explicit typing is needed in most cases.

Return value

voiduseEvent does not return a value.

Available events by node type

Node typeEvent nameCallback signature
CollidercolliderEntered(collider: Collider) => void
Collidercollided(collider: Collider) => void
CollidercolliderExited(collider: Collider) => void
Clickableclicked(position: Vector2) => void
ClickablemouseEntered() => void
ClickablemouseExited() => void
ClickablemouseOver(position: Vector2) => void
RayCastcolliderEntered(collider: Collider) => void
RayCastcolliderExited(collider: Collider) => void
Timertimeout() => void
TimertimeChanged(time: number) => void
All nodesstarted() => void
All nodesupdated(delta: number) => void
All nodesdrawed(delta: number) => void
All nodesdestroyed() => void

Examples

Collision detection on an enemy

Enemy.tsx
import { useRefNode, useEvent } from 'tiny-engine/hooks'
import { PrimaryNode, shapes } from 'tiny-engine'

function Enemy() {
  const collider = useRefNode(PrimaryNode.Collider)

  useEvent(collider, 'colliderEntered', (other) => {
    // `other` is inferred as Collider — no cast needed
    console.log('Enemy hit by:', other)
  })

  useEvent(collider, 'colliderExited', (other) => {
    console.log('No longer colliding with:', other)
  })

  return (
    <transform>
      <collider
        ref={collider}
        shape={shapes.circle(12)}
        group={['enemy']}
        collidesWith={['projectile', 'player']}
      />
      <sprite textureId={ENEMY_TEXTURE} />
    </transform>
  )
}

Hover and click feedback on a button

MenuButton.tsx
import { useRefNode, useEvent, useSignal } from 'tiny-engine/hooks'
import { PrimaryNode } from 'tiny-engine'

function MenuButton() {
  const btn = useRefNode(PrimaryNode.Clickable)
  const [hovered, setHovered] = useSignal(false)

  useEvent(btn, 'mouseEntered', () => setHovered(true))
  useEvent(btn, 'mouseExited', () => setHovered(false))
  useEvent(btn, 'clicked', (pos) => {
    console.log('Clicked at local position', pos.x, pos.y)
  })

  return (
    <clickable
      ref={btn}
      size={[128, 40]}
    >
      <sprite
        textureId={BUTTON_TEXTURE}
        brightness={() => hovered() ? 1.3 : 1}
      />
    </clickable>
  )
}

Reacting to a timer finishing

Countdown.tsx
import { useRefNode, useEvent } from 'tiny-engine/hooks'
import { PrimaryNode } from 'tiny-engine'

function Countdown() {
  const timer = useRefNode(PrimaryNode.Timer)

  useEvent(timer, 'timeout', () => {
    console.log('Time is up!')
  })

  return <timer ref={timer} duration={5} autoPlay />
}
Cleanup is automatic. When the component’s owning node is destroyed, every listener registered through useEvent is removed. You do not need to call .off() or store a reference to the subscription.
Use useEvent over direct .on() calls whenever possible. In addition to automatic cleanup, it gives you compile-time type checking for both the event name and the callback signature.

Build docs developers (and LLMs) love