useCollision

useCollision registers a lightweight collider on an Actor and fires callbacks when it overlaps with other colliders. No physics engine required — this is CarverJS's built-in collision system powered by the CollisionManager.

tsx
import { useCollision } from "@carverjs/core/hooks";

Quick Start #

tsx
import { useRef } from "react";
import { Actor } from "@carverjs/core/components";
import { useCollision } from "@carverjs/core/hooks";
import type { Group } from "@carverjs/core/types";

function Player() {
  const ref = useRef<Group>(null);

  useCollision({
    ref,
    name: "player",
    collider: { shape: "aabb", halfExtents: [0.5, 0.5, 0.5] },
    onCollisionEnter: (e) => console.log("hit", e.otherName),
  });

  return <Actor ref={ref} type="primitive" shape="box" color="blue" />;
}

Options #

OptionTypeDefaultDescription
refRefObject<Object3D>Required. Ref to the Actor's group
colliderColliderDefRequired. Collider shape definition
namestring""Name for identification in collision events
userDataRecord<string, unknown>{}Arbitrary data passed through to events
layernumber0xFFFFFFFFCollision layer bitmask
masknumber0xFFFFFFFFLayers this collider checks against
sensorbooleanfalseTrigger mode (detects overlap, no response)
onCollisionEnterCollisionCallbackFirst frame of overlap
onCollisionExitCollisionCallbackLast frame of overlap
onCollisionStayCollisionCallbackEvery frame while overlapping
enabledbooleantrueToggle this collider on/off

Return Value #

PropertyTypeDescription
isOverlapping(name)(string) => booleanCheck if currently overlapping with a named collider
getOverlaps()() => string[]Get all current overlap names

Collider Shapes #

AABB (Axis-Aligned Bounding Box) #

tsx
{ shape: "aabb", halfExtents: [0.5, 1, 0.5], offset: [0, 0, 0] }

Sphere (3D) #

tsx
{ shape: "sphere", radius: 0.5, offset: [0, 0, 0] }

Circle (2D) #

tsx
{ shape: "circle", radius: 0.5, offset: [0, 0, 0] }

Collision Event #

All callbacks receive a CollisionEvent:

FieldTypeDescription
otherNamestringName of the other collider
otherUserDataRecord<string, unknown>The other collider's userData
otherRefRefObject<Object3D>The other collider's Object3D ref
isSensorbooleanWhether the other collider is a sensor

Layer Filtering #

Use bitmask layers to control which colliders interact:

tsx
const LAYER_PLAYER = 1 << 0;  // 1
const LAYER_ENEMY  = 1 << 1;  // 2
const LAYER_PICKUP = 1 << 2;  // 4

// Player collides with enemies and pickups
useCollision({
  ref: playerRef,
  name: "player",
  collider: { shape: "aabb", halfExtents: [0.5, 0.5, 0.5] },
  layer: LAYER_PLAYER,
  mask: LAYER_ENEMY | LAYER_PICKUP,
  onCollisionEnter: (e) => { /* ... */ },
});

// Enemy only collides with player
useCollision({
  ref: enemyRef,
  name: "enemy",
  collider: { shape: "sphere", radius: 0.5 },
  layer: LAYER_ENEMY,
  mask: LAYER_PLAYER,
});

Sensor Mode #

Sensors detect overlap but don't imply any physics response. Useful for triggers, collectibles, and zones:

tsx
useCollision({
  ref: coinRef,
  name: "coin",
  collider: { shape: "sphere", radius: 0.3 },
  sensor: true,
  onCollisionEnter: (e) => {
    if (e.otherName === "player") collectCoin();
  },
});

Type Definitions #

See Types for UseCollisionOptions, UseCollisionReturn, ColliderDef, ColliderShape, CollisionEvent, and CollisionCallback.