触发体积
触发体积是不会阻挡运动、但在刚体进入和离开时发出事件的碰撞形状,适合检测进球、赛车冲线或玩家进入房间。
创建触发体积
触发器就是没有 rigidbody 的实体上的 collision。可以使用任意碰撞形状,包括网格和复合形状。下面创建盒形球门区域:
- 引擎
- 编辑器
- React
- Web Components
const goal = new pc.Entity('goal');
goal.addComponent('collision', {
type: 'box',
halfExtents: new pc.Vec3(2, 1, 0.5)
});
goal.setPosition(0, 1, -10);
app.root.addChild(goal);
为实体添加 Collision 并设置形状,不要添加 Rigid Body。编辑器在选中实体时显示形状,便于按场景调整尺寸。
<Entity name="goal" position={[0, 1, -10]}>
<Collision type="box" halfExtents={[2, 1, 0.5]} />
</Entity>
<pc-entity name="goal" position="0 1 -10">
<pc-collision type="box" half-extents="2 1 0.5"></pc-collision>
</pc-entity>
触发器没有刚体,因此可像普通实体一样,使用 setPosition、setRotation 和其他 Entity 变换 API 移动。物理引擎在下一步读取新变换。
监听触发事件
刚体开始重叠时,触发器 collision 发出 triggerenter,停止重叠发出 triggerleave。参数都是进入或离开的刚体实体:
goal.collision.on('triggerenter', (entity) => {
console.log(`${entity.name} has entered ${goal.name}.`);
});
goal.collision.on('triggerleave', (entity) => {
console.log(`${entity.name} has left ${goal.name}.`);
});
另一方刚体的 collision 和 rigidbody 也会收到相同事件,但参数为触发器实体,让刚体能够响应经过的区域:
player.rigidbody.on('triggerenter', (trigger) => {
if (trigger.tags.has('checkpoint')) {
lastCheckpoint = trigger.getPosition().clone();
}
});
订阅与碰撞事件相同:on 返回 EventHandle,调用其 off() 移除,或向组件 off(eventName, callback) 传入相同回调。碰撞事件展示各开发方式中代码的位置。
哪些对象能触发?
只有动态和运动学刚体触发事件。静态刚体不移动,因此不参与重叠测试,触发器之间也不能互相检测。事件没有触发时,检查经过区域的实体是否具有 Dynamic 或 Kinematic 类型的 rigidbody。
触发重叠不会发出 contact、collisionstart 或 collisionend,它们只用于刚体物理接触,见碰撞事件。