重叠检测(Overlap Detection)是物理引擎中用于检测指定区域内所有重叠碰撞器的功能。与 形状投射 沿方向进行动态检测不同,重叠检测在静态位置检查与指定几何形状重叠的所有物体。
Galacean 物理引擎提供三种重叠检测功能:
重叠检测在游戏开发中的常见应用:
检测与指定立方体区域重叠的所有碰撞器。
overlapBoxAll(
center: Vector3,
halfExtents: Vector3,
orientation: Quaternion = new Quaternion(),
layerMask: Layer = Layer.Everything,
shapes: ColliderShape[] = []
): ColliderShape[]
import { Vector3, Quaternion, Layer, ColliderShape } from "@galacean/engine";
// 获取物理场景
const physicsScene = scene.physics;
// 示例1: 基础重叠检测
const center = new Vector3(0, 0, 0);
const halfExtents = new Vector3(2, 1, 2); // 盒子半尺寸
const allOverlapping = physicsScene.overlapBoxAll(center, halfExtents);
console.log(`检测到 ${allOverlapping.length} 个重叠物体`);
allOverlapping.forEach((shape, index) => {
console.log(`${index + 1}. ${shape.collider.entity.name}`);
});
// 示例2: 建造系统 - 检查区域是否被占用
const buildCenter = new Vector3(5, 0, 3);
const buildSize = new Vector3(1.5, 1, 1.5);
const buildingLayerMask = Layer.Layer0 | Layer.Layer1; // 使用实际存在的层
const obstacleShapes: ColliderShape[] = [];
const obstacles = physicsScene.overlapBoxAll(
buildCenter,
buildSize,
new Quaternion(), // 使用新四元数实例代替不存在的 IDENTITY
buildingLayerMask,
obstacleShapes
);
if (obstacles.length === 0) {
console.log("区域空闲,可以建造");
placeBuildingAt(buildCenter);
} else {
console.log("区域被占用,无法建造");
obstacles.forEach(shape => {
console.log(`障碍物: ${shape.collider.entity.name}`);
});
}
// 示例3: 旋转盒子检测
const rotatedOrientation = new Quaternion();
Quaternion.rotationY(Math.PI / 4, rotatedOrientation); // 使用正确的 API
const rotatedOverlap = physicsScene.overlapBoxAll(
center,
halfExtents,
rotatedOrientation,
Layer.Everything
);
检测与指定球形区域重叠的所有碰撞器。
overlapSphereAll(
center: Vector3,
radius: number,
layerMask: Layer = Layer.Everything,
shapes: ColliderShape[] = []
): ColliderShape[]
// 示例1: 爆炸伤害检测
const explosionCenter = new Vector3(0, 1, 0);
const explosionRadius = 5.0;
const targetLayer = Layer.Layer0; // 使用实际存在的层
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} 受到 ${damage} 点爆炸伤害`);
applyDamage(entity, damage);
});
// 示例2: 收集道具系统
const playerPosition = new Vector3(2, 0, 1);
const collectRadius = 1.5;
const itemLayer = Layer.Layer2; // 使用实际存在的层
const collectibleItems = physicsScene.overlapSphereAll(
playerPosition,
collectRadius,
itemLayer
);
collectibleItems.forEach(shape => {
const item = shape.collider.entity;
console.log(`收集道具: ${item.name}`);
collectItem(item);
});
// 示例3: AI 感知系统
class AIPerception {
private readonly _detectedShapes: ColliderShape[] = [];
checkVisionRange(aiPosition: Vector3, visionRadius: number): Entity[] {
this._detectedShapes.length = 0; // 清空数组
const detectedShapes = physicsScene.overlapSphereAll(
aiPosition,
visionRadius,
Layer.Layer0 | Layer.Layer1, // 使用实际层组合
this._detectedShapes
);
return detectedShapes.map(shape => shape.collider.entity);
}
}
检测与指定胶囊区域重叠的所有碰撞器,特别适合人形角色的范围检测。
overlapCapsuleAll(
center: Vector3,
radius: number,
height: number,
orientation: Quaternion = new Quaternion(),
layerMask: Layer = Layer.Everything,
shapes: ColliderShape[] = []
): ColliderShape[]
// 示例1: 角色攻击范围检测
const characterCenter = new Vector3(0, 1, 0);
const attackRadius = 1.0;
const attackHeight = 2.0;
const enemyLayer = Layer.Layer3; // 使用实际存在的层
const attackTargets = physicsScene.overlapCapsuleAll(
characterCenter,
attackRadius,
attackHeight,
new Quaternion(), // 使用新四元数实例
enemyLayer
);
if (attackTargets.length > 0) {
console.log(`攻击命中 ${attackTargets.length} 个目标`);
attackTargets.forEach(shape => {
const enemy = shape.collider.entity;
applyMeleeDamage(enemy, 50);
});
}
// 示例2: 传送门检测
const portalCenter = new Vector3(10, 0, 5);
const portalRadius = 0.8;
const portalHeight = 2.5;
const characterLayer = Layer.Layer0; // 使用实际存在的层
const charactersInPortal = physicsScene.overlapCapsuleAll(
portalCenter,
portalRadius,
portalHeight,
new Quaternion(), // 使用新四元数实例
characterLayer
);
charactersInPortal.forEach(shape => {
const character = shape.collider.entity;
console.log(`${character.name} 进入传送门`);
teleportCharacter(character, destinationPosition);
});
// 示例3: 电梯检测系统
class ElevatorDetector {
private readonly _passengersBuffer: ColliderShape[] = [];
detectPassengers(elevatorCenter: Vector3): Entity[] {
this._passengersBuffer.length = 0;
const passengers = physicsScene.overlapCapsuleAll(
elevatorCenter,
1.2, // 电梯宽度
2.0, // 电梯高度
new Quaternion(), // 使用新四元数实例
Layer.Layer0 | Layer.Layer4, // 使用实际层组合
this._passengersBuffer
);
return passengers.map(shape => shape.collider.entity);
}
}
Layer.Everything
)所有检测函数都返回 ColliderShape[]
数组,包含所有重叠的碰撞器形状。
layerMask
只检测相关的碰撞器层// 性能优化示例
class OverlapDetector {
private static readonly _resultBuffer: ColliderShape[] = [];
private static readonly _targetLayer = Layer.Layer0 | Layer.Layer3;
static detectTargetsInRange(center: Vector3, radius: number): Entity[] {
// 清空复用数组
this._resultBuffer.length = 0;
// 使用预分配数组和层过滤
const shapes = physicsScene.overlapSphereAll(
center,
radius,
this._targetLayer,
this._resultBuffer
);
// 转换为实体数组
return shapes.map(shape => shape.collider.entity);
}
}
// 使用示例
const nearbyTargets = OverlapDetector.detectTargetsInRange(playerPosition, 10.0);
特性 | 重叠检测 | 形状投射 |
---|---|---|
检测方式 | 静态区域检测 | 动态方向投射 |
返回结果 | 所有重叠物体 | 第一个碰撞物体 |
适用场景 | 区域触发、范围攻击 | 移动预测、路径检测 |
性能消耗 | 中等 | 中等 |
结果数量 | 多个 | 单个 |
重叠检测为区域性的游戏逻辑提供了强大的支持,特别适合实现触发器、范围攻击、收集系统等功能。结合合适的性能优化策略,可以高效地处理复杂的空间查询需求。