Class: GrabSystem
Defined in: packages/core/src/grab/grab-system.ts:61
Manages interactive object grabbing and manipulation for VR/AR experiences.
Remarks
- Uses the
@pmndrs/handlelibrary for precise multitouch manipulation. - Automatically creates handle instances for entities with grabbable components.
- Supports three types of grab interactions: one‑hand, two‑hand, and distance grabbing.
- Automatically cleans up handle instances when grabbable components are removed.
Examples
// Add to your world to enable grab interactions
world.addSystem(GrabSystem)
// Create a grabbable box
const box = world.createEntity()
box.addComponent(OneHandGrabbable, {})// Create an object that can be scaled with two hands
const sculpture = world.createEntity()
sculpture.addComponent(TwoHandsGrabbable, {
scaleMin: [0.5, 0.5, 0.5],
scaleMax: [3, 3, 3]
})See
Extends
System<{useHandPinchForGrab: {default:false;type:Boolean; }; }, {distanceGrabbables: {required:Component<{detachOnGrab: {default:false;type:Boolean; };movementMode: {default:string;enum: {MoveAtSource:string;MoveFromTarget:string;MoveTowardsTarget:string;RotateAtSource:string; };type:Enum; };moveSpeedFactor: {default:number;type:Float32; };returnToOrigin: {default:false;type:Boolean; };rotate: {default:true;type:Boolean; };rotateMax: {default: [number,number,number];type:Vec3; };rotateMin: {default: [number,number,number];type:Vec3; };scale: {default:true;type:Boolean; };scaleMax: {default: [number,number,number];type:Vec3; };scaleMin: {default: [number,number,number];type:Vec3; };targetPositionOffset: {default: [number,number,number];type:Vec3; };targetQuaternionOffset: {default: [number,number,number,number];type:Vec4; };translate: {default:true;type:Boolean; };translateMax: {default: [number,number,number];type:Vec3; };translateMin: {default: [number,number,number];type:Vec3; }; }>[]; };handles: {required:Component<{instance: {default:any;type:Object; }; }>[]; };oneHandGrabbables: {required:Component<{rotate: {default:true;type:Boolean; };rotateMax: {default: [number,number,number];type:Vec3; };rotateMin: {default: [number,number,number];type:Vec3; };translate: {default:true;type:Boolean; };translateMax: {default: [number,number,number];type:Vec3; };translateMin: {default: [number,number,number];type:Vec3; }; }>[]; };twoHandsGrabbables: {required:Component<{rotate: {default:true;type:Boolean; };rotateMax: {default: [number,number,number];type:Vec3; };rotateMin: {default: [number,number,number];type:Vec3; };scale: {default:true;type:Boolean; };scaleMax: {default: [number,number,number];type:Vec3; };scaleMin: {default: [number,number,number];type:Vec3; };translate: {default:true;type:Boolean; };translateMax: {default: [number,number,number];type:Vec3; };translateMin: {default: [number,number,number];type:Vec3; }; }>[]; }; },this>
Constructors
Constructor
new GrabSystem(
_w,_qm,_p):GrabSystem
Defined in: node_modules/.pnpm/elics@3.4.2/node_modules/elics/lib/system.d.ts:76
Parameters
_w
_qm
QueryManager
_p
number
Returns
GrabSystem
Inherited from
createSystem( { oneHandGrabbables: { required: [OneHandGrabbable], }, twoHandsGrabbables: { required: [TwoHandsGrabbable], }, distanceGrabbables: { required: [DistanceGrabbable], }, handles: { required: [Handle], }, }, { /** * Controls whether hand pinch gestures are forwarded as squeeze events for grab interactions. * Set to `false` to disable pinch-to-grab and require the physical squeeze button instead. * @default false */ useHandPinchForGrab: { type: Types.Boolean, default: false }, }, ).constructor
Properties
camera
readonlycamera:PerspectiveCamera
Defined in: packages/core/src/ecs/system.ts:63
Inherited from
cleanupFuncs
readonlycleanupFuncs: () =>void[]
Defined in: packages/core/src/ecs/system.ts:66
Returns
void
Inherited from
config
config:
SystemConfigSignals<S>
Defined in: packages/core/src/ecs/system.ts:49
Inherited from
createEntity()
createEntity: () =>
Entity
Defined in: packages/core/src/ecs/system.ts:81
Returns
Entity
Inherited from
globals
globals:
Record<string,any>
Defined in: packages/core/src/ecs/system.ts:54
Inherited from
input
readonlyinput:InputManager
Defined in: packages/core/src/ecs/system.ts:61
Inherited from
isPaused
isPaused:
boolean
Defined in: packages/core/src/ecs/system.ts:48
Inherited from
player
readonlyplayer:XROrigin
Defined in: packages/core/src/ecs/system.ts:58
Inherited from
playerEntity
readonlyplayerEntity:Entity
Defined in: packages/core/src/ecs/system.ts:59
Inherited from
playerHeadEntity
readonlyplayerHeadEntity:Entity
Defined in: packages/core/src/ecs/system.ts:60
Inherited from
priority
priority:
number
Defined in: packages/core/src/ecs/system.ts:53
Inherited from
queries
queries:
Record<keyofQ,Query>
Defined in: packages/core/src/ecs/system.ts:50
Inherited from
queryManager
queryManager:
QueryManager
Defined in: packages/core/src/ecs/system.ts:52
Inherited from
renderer
readonlyrenderer:WebGLRenderer
Defined in: packages/core/src/ecs/system.ts:64
Inherited from
scene
readonlyscene:Scene
Defined in: packages/core/src/ecs/system.ts:62
Inherited from
visibilityState
readonlyvisibilityState:Signal<VisibilityState>
Defined in: packages/core/src/ecs/system.ts:65
Inherited from
world
world:
World
Defined in: packages/core/src/ecs/system.ts:51
Inherited from
xrFrame
xrFrame:
XRFrame
Defined in: packages/core/src/ecs/system.ts:56
Inherited from
xrManager
xrManager:
WebXRManager
Defined in: packages/core/src/ecs/system.ts:55
Inherited from
Methods
forceRelease()
forceRelease(
entity):void
Defined in: packages/core/src/grab/grab-system.ts:198
Force-release entity if it is currently being held.
Parameters
entity
Entity
Returns
void
Remarks
Cancels every active pointer on the entity's grab handle, which causes update() on the next frame to remove the Grabbed tag. Safe to call when the entity is not held or has never been grabbable — a no-op in those cases.
Useful for game-state changes that need to drop held items: level resets, weapon swaps, death/respawn, cinematics, etc.
Example
const grab = world.getSystem(GrabSystem);
grab.forceRelease(weaponEntity);getHolderHand()
getHolderHand(
entity):"left"|"right"
Defined in: packages/core/src/grab/grab-system.ts:228
Identify which controller is currently holding entity.
Parameters
entity
Entity
Returns
"left" | "right"
'left' or 'right' when a single hand holds the entity, null when the entity is not held (or has no grab handle).
Remarks
For two-handed grabs (both controllers active on the same entity), the left hand is reported. Callers needing per-hand state for two-handed interactions should track grab/release events themselves rather than polling this method.
Useful for hand-aware behaviors: recoil/animation that should react to the holding controller, hand-specific UI prompts, etc.
Example
const grab = world.getSystem(GrabSystem);
const hand = grab.getHolderHand(gunEntity);
if (hand) {
playRecoilOn(hand);
}init()
init():
void
Defined in: packages/core/src/grab/grab-system.ts:85
Returns
void
Overrides
play()
play():
void
Defined in: packages/core/src/ecs/system.ts:79
Returns
void
Inherited from
stop()
stop():
void
Defined in: packages/core/src/ecs/system.ts:80
Returns
void
Inherited from
update()
update(
delta,time):void
Defined in: packages/core/src/grab/grab-system.ts:136
Per-frame tick. Both arguments are in seconds (Three.js Clock convention), not milliseconds.
Parameters
delta
number
Seconds since the previous frame.
time
number
Accumulated Clock.elapsedTime (seconds since the render loop started ticking the clock); monotonic across frames within a session.
Returns
void