Overlap Detection is a physics engine feature used to detect all overlapping colliders within a specified region. Unlike shape casting which performs dynamic detection along a direction, overlap detection checks for all objects overlapping with a specified geometric shape at a static position.
Galacean Physics Engine provides three overlap detection functions:
Common applications of overlap detection in game development:
Detects all colliders overlapping with a specified cubic region.
overlapBoxAll(
center: Vector3,
halfExtents: Vector3,
orientation: Quaternion = new Quaternion(),
layerMask: Layer = Layer.Everything,
shapes: ColliderShape[] = []
): ColliderShape[]
import { Vector3, Quaternion, Layer, ColliderShape } from "@galacean/engine";
// Get physics scene
const physicsScene = scene.physics;
// Example 1: Basic overlap detection
const center = new Vector3(0, 0, 0);
const halfExtents = new Vector3(2, 1, 2); // Box half-size
const allOverlapping = physicsScene.overlapBoxAll(center, halfExtents);
console.log(`Detected ${allOverlapping.length} overlapping objects`);
allOverlapping.forEach((shape, index) => {
console.log(`${index + 1}. ${shape.collider.entity.name}`);
});
// Example 2: Building system - check if area is occupied
const buildCenter = new Vector3(5, 0, 3);
const buildSize = new Vector3(1.5, 1, 1.5);
const buildingLayerMask = Layer.Layer0 | Layer.Layer1; // Use actual existing layers
const obstacleShapes: ColliderShape[] = [];
const obstacles = physicsScene.overlapBoxAll(
buildCenter,
buildSize,
new Quaternion(), // Use new quaternion instance instead of non-existent IDENTITY
buildingLayerMask,
obstacleShapes
);
if (obstacles.length === 0) {
console.log("Area is free, can build");
placeBuildingAt(buildCenter);
} else {
console.log("Area is occupied, cannot build");
obstacles.forEach(shape => {
console.log(`Obstacle: ${shape.collider.entity.name}`);
});
}
// Example 3: Rotated box detection
const rotatedOrientation = new Quaternion();
Quaternion.rotationY(Math.PI / 4, rotatedOrientation); // Use correct API
const rotatedOverlap = physicsScene.overlapBoxAll(
center,
halfExtents,
rotatedOrientation,
Layer.Everything
);
Detects all colliders overlapping with a specified spherical region.
overlapSphereAll(
center: Vector3,
radius: number,
layerMask: Layer = Layer.Everything,
shapes: ColliderShape[] = []
): ColliderShape[]
// Example 1: Explosion damage detection
const explosionCenter = new Vector3(0, 1, 0);
const explosionRadius = 5.0;
const targetLayer = Layer.Layer0; // Use actual existing layer
const affectedTargets = physicsScene.overlapSphereAll(
explosionCenter,
explosionRadius,
targetLayer
);
affectedTargets.forEach(shape => {
const entity = shape.collider.entity;
const distance = Vector3.distance(explosionCenter, entity.transform.position);
const damage = calculateExplosionDamage(distance, explosionRadius);
console.log(`${entity.name} takes ${damage} explosion damage`);
applyDamage(entity, damage);
});
// Example 2: Collectible item system
const playerPosition = new Vector3(2, 0, 1);
const collectRadius = 1.5;
const itemLayer = Layer.Layer2; // Use actual existing layer
const collectibleItems = physicsScene.overlapSphereAll(
playerPosition,
collectRadius,
itemLayer
);
collectibleItems.forEach(shape => {
const item = shape.collider.entity;
console.log(`Collected item: ${item.name}`);
collectItem(item);
});
// Example 3: AI perception system
class AIPerception {
private readonly _detectedShapes: ColliderShape[] = [];
checkVisionRange(aiPosition: Vector3, visionRadius: number): Entity[] {
this._detectedShapes.length = 0; // Clear array
const detectedShapes = physicsScene.overlapSphereAll(
aiPosition,
visionRadius,
Layer.Layer0 | Layer.Layer1, // Use actual layer combination
this._detectedShapes
);
return detectedShapes.map(shape => shape.collider.entity);
}
}
Detects all colliders overlapping with a specified capsule region, particularly suitable for humanoid character range detection.
overlapCapsuleAll(
center: Vector3,
radius: number,
height: number,
orientation: Quaternion = new Quaternion(),
layerMask: Layer = Layer.Everything,
shapes: ColliderShape[] = []
): ColliderShape[]
// Example 1: Character attack range detection
const characterCenter = new Vector3(0, 1, 0);
const attackRadius = 1.0;
const attackHeight = 2.0;
const enemyLayer = Layer.Layer3; // Use actual existing layer
const attackTargets = physicsScene.overlapCapsuleAll(
characterCenter,
attackRadius,
attackHeight,
new Quaternion(), // Use new quaternion instance
enemyLayer
);
if (attackTargets.length > 0) {
console.log(`Attack hit ${attackTargets.length} targets`);
attackTargets.forEach(shape => {
const enemy = shape.collider.entity;
applyMeleeDamage(enemy, 50);
});
}
// Example 2: Portal detection
const portalCenter = new Vector3(10, 0, 5);
const portalRadius = 0.8;
const portalHeight = 2.5;
const characterLayer = Layer.Layer0; // Use actual existing layer
const charactersInPortal = physicsScene.overlapCapsuleAll(
portalCenter,
portalRadius,
portalHeight,
new Quaternion(), // Use new quaternion instance
characterLayer
);
charactersInPortal.forEach(shape => {
const character = shape.collider.entity;
console.log(`${character.name} entered portal`);
teleportCharacter(character, destinationPosition);
});
// Example 3: Elevator detection system
class ElevatorDetector {
private readonly _passengersBuffer: ColliderShape[] = [];
detectPassengers(elevatorCenter: Vector3): Entity[] {
this._passengersBuffer.length = 0;
const passengers = physicsScene.overlapCapsuleAll(
elevatorCenter,
1.2, // Elevator width
2.0, // Elevator height
new Quaternion(), // Use new quaternion instance
Layer.Layer0 | Layer.Layer4, // Use actual layer combination
this._passengersBuffer
);
return passengers.map(shape => shape.collider.entity);
}
}
Layer.Everything
)All detection functions return a ColliderShape[]
array containing all overlapping collider shapes.
layerMask
// Performance optimization example
class OverlapDetector {
private static readonly _resultBuffer: ColliderShape[] = [];
private static readonly _targetLayer = Layer.Layer0 | Layer.Layer3;
static detectTargetsInRange(center: Vector3, radius: number): Entity[] {
// Clear reused array
this._resultBuffer.length = 0;
// Use pre-allocated array and layer filtering
const shapes = physicsScene.overlapSphereAll(
center,
radius,
this._targetLayer,
this._resultBuffer
);
// Convert to entity array
return shapes.map(shape => shape.collider.entity);
}
}
// Usage example
const nearbyTargets = OverlapDetector.detectTargetsInRange(playerPosition, 10.0);
Feature | Overlap Detection | Shape Casting |
---|---|---|
Detection Method | Static region detection | Dynamic directional casting |
Return Results | All overlapping objects | First collision object |
Use Cases | Area triggers, range attacks | Movement prediction, path detection |
Performance Cost | Medium | Medium |
Result Count | Multiple | Single |
Overlap detection provides powerful support for area-based game logic, particularly suitable for implementing triggers, range attacks, collection systems, and other functionality. Combined with appropriate performance optimization strategies, it can efficiently handle complex spatial query requirements.