Shape Casting is an advanced querying feature in physics engines that allows you to "cast" a three-dimensional shape along a specified direction to detect obstructions. Unlike raycasting which uses an infinitely thin line, shape casting uses geometric volumes for detection, providing more accurate and practical obstruction information.
Galacean Physics Engine provides three shape casting functions:
Shape casting has wide applications in game development:
Box casting projects a cube along a specified direction to detect intersections with colliders in the scene.
To improve usability, boxCast
provides multiple overload versions:
// Basic detection - returns only whether obstruction occurred
boxCast(center: Vector3, halfExtents: Vector3, direction: Vector3): boolean
// Get hit information
boxCast(center: Vector3, halfExtents: Vector3, direction: Vector3, outHitResult: HitResult): boolean
// Specify casting distance
boxCast(center: Vector3, halfExtents: Vector3, direction: Vector3, distance: number): boolean
// Specify distance and get hit information
boxCast(center: Vector3, halfExtents: Vector3, direction: Vector3, distance: number, outHitResult: HitResult): boolean
// Full parameter version
boxCast(
center: Vector3,
halfExtents: Vector3,
direction: Vector3,
orientation: Quaternion,
distance: number,
layerMask: Layer,
outHitResult?: HitResult
): boolean
import { Vector3, HitResult, Layer, Quaternion } from "@galacean/engine";
// Get physics scene
const physicsScene = scene.physics;
// Example 1: Basic obstruction detection
const center = new Vector3(0, 5, 0);
const halfExtents = new Vector3(1, 1, 1); // Box half-size
const direction = new Vector3(0, -1, 0); // Cast downward
if (physicsScene.boxCast(center, halfExtents, direction)) {
console.log("Obstruction detected!");
}
// Example 2: Get detailed hit information
const hitResult = new HitResult();
if (physicsScene.boxCast(center, halfExtents, direction, hitResult)) {
console.log(`Hit entity: ${hitResult.entity.name}`);
console.log(`Hit distance: ${hitResult.distance}`);
console.log(`Hit point: ${hitResult.point.toString()}`);
console.log(`Hit normal: ${hitResult.normal.toString()}`);
}
// Example 3: Character movement pre-check
const playerSize = new Vector3(0.5, 1, 0.5);
const moveDirection = new Vector3(1, 0, 0);
const moveDistance = 2.0;
if (!physicsScene.boxCast(playerPosition, playerSize, moveDirection, moveDistance)) {
// Path is clear, safe to move
playerPosition.add(moveDirection.scale(moveDistance));
}
// Example 4: Precise detection with full parameters
const orientation = new Quaternion(0, 0, 0, 1); // No rotation
const layerMask = Layer.Everything; // Check all layers
const maxDistance = 10.0;
const detailHit = new HitResult();
if (physicsScene.boxCast(
center,
halfExtents,
direction,
orientation,
maxDistance,
layerMask,
detailHit
)) {
console.log("Precise detection successful");
}
Sphere casting projects a sphere along a specified direction, suitable for scenarios requiring spherical detection areas.
// Basic detection
sphereCast(center: Vector3, radius: number, direction: Vector3): boolean
// Get collision information
sphereCast(center: Vector3, radius: number, direction: Vector3, outHitResult: HitResult): boolean
// Specify casting distance
sphereCast(center: Vector3, radius: number, direction: Vector3, distance: number): boolean
// Specify distance and get collision information
sphereCast(center: Vector3, radius: number, direction: Vector3, distance: number, outHitResult: HitResult): boolean
// Full parameter version
sphereCast(
center: Vector3,
radius: number,
direction: Vector3,
distance: number,
layerMask: Layer,
outHitResult?: HitResult
): boolean
// Example 1: Spherical object movement prediction
const ballRadius = 0.5;
const ballPosition = new Vector3(-5, 2, 0);
const rollDirection = new Vector3(1, 0, 0);
const rollDistance = 8.0;
const rollHit = new HitResult();
if (physicsScene.sphereCast(ballPosition, ballRadius, rollDirection, rollDistance, rollHit)) {
console.log(`Ball will hit ${rollHit.entity.name} at distance ${rollHit.distance}`);
}
// Example 2: Projectile path validation
Capsule casting projects a capsule shape along a specified direction, particularly suitable for humanoid character collision detection.
// Basic detection
capsuleCast(center: Vector3, radius: number, height: number, direction: Vector3): boolean
// Get collision information
capsuleCast(center: Vector3, radius: number, height: number, direction: Vector3, outHitResult: HitResult): boolean
// Specify casting distance
capsuleCast(center: Vector3, radius: number, height: number, direction: Vector3, distance: number): boolean
// Specify distance and get collision information
capsuleCast(center: Vector3, radius: number, height: number, direction: Vector3, distance: number, outHitResult: HitResult): boolean
// Full parameter version
capsuleCast(
center: Vector3,
radius: number,
height: number,
direction: Vector3,
orientation: Quaternion,
distance: number,
layerMask: Layer,
outHitResult?: HitResult
): boolean
// Example 1: Character jump detection
const characterCenter = new Vector3(0, 1, 0);
const characterRadius = 0.5;
const characterHeight = 1.8;
const jumpDirection = new Vector3(0, 1, 0);
const jumpHeight = 2.0;
if (!physicsScene.capsuleCast(characterCenter, characterRadius, characterHeight, jumpDirection, jumpHeight)) {
// Enough headroom, safe to jump
performJump();
}
// Example 2: Humanoid character movement detection
const moveDirection = new Vector3(1, 0, 0);
const stepDistance = 1.0;
const moveHit = new HitResult();
if (physicsScene.capsuleCast(
characterCenter,
characterRadius,
characterHeight,
moveDirection,
stepDistance,
moveHit
)) {
console.log(`Character movement will hit obstacle at distance ${moveHit.distance}`);
// Can implement sliding or other collision response
}
Number.MAX_VALUE
)Layer.Everything
)layerMask
to only check relevant collider layers// Performance optimization example
class PhysicsQuery {
private static readonly _hitResult = new HitResult();
private static readonly _playerLayerMask = Layer.Layer0 | Layer.Layer1;
static checkPlayerMovement(center: Vector3, direction: Vector3): boolean {
return scene.physics.capsuleCast(
center,
0.5, // Fixed radius
1.8, // Fixed height
direction,
2.0, // Limit detection distance
this._playerLayerMask, // Only check relevant layers
this._hitResult // Reuse result object
);
}
}
direction
parameter is a unit vectorFeature | Raycasting | Shape Casting |
---|---|---|
Detection Precision | Point precision | Volume precision |
Performance Cost | Low | Medium |
Use Cases | Picking, aiming | Movement prediction, path validation |
Shape casting provides more accurate obstruction information than raycasting, particularly suitable for scenarios that need to consider object volume. Combined with appropriate performance optimization strategies, it can maintain good runtime efficiency while ensuring precision.