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 #
| Option | Type | Default | Description |
|---|---|---|---|
ref | RefObject<Object3D> | — | Required. Ref to the Actor's group |
collider | ColliderDef | — | Required. Collider shape definition |
name | string | "" | Name for identification in collision events |
userData | Record<string, unknown> | {} | Arbitrary data passed through to events |
layer | number | 0xFFFFFFFF | Collision layer bitmask |
mask | number | 0xFFFFFFFF | Layers this collider checks against |
sensor | boolean | false | Trigger mode (detects overlap, no response) |
onCollisionEnter | CollisionCallback | — | First frame of overlap |
onCollisionExit | CollisionCallback | — | Last frame of overlap |
onCollisionStay | CollisionCallback | — | Every frame while overlapping |
enabled | boolean | true | Toggle this collider on/off |
Return Value #
| Property | Type | Description |
|---|---|---|
isOverlapping(name) | (string) => boolean | Check 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:
| Field | Type | Description |
|---|---|---|
otherName | string | Name of the other collider |
otherUserData | Record<string, unknown> | The other collider's userData |
otherRef | RefObject<Object3D> | The other collider's Object3D ref |
isSensor | boolean | Whether 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.