2020-07-23 11:00:46 +08:00
|
|
|
|
module es {
|
2020-06-16 09:10:09 +08:00
|
|
|
|
/**
|
2020-07-23 11:00:46 +08:00
|
|
|
|
* 移动器使用的帮助器类,用于管理触发器碰撞器交互并调用itriggerlistener
|
2020-06-16 09:10:09 +08:00
|
|
|
|
*/
|
2020-07-23 11:00:46 +08:00
|
|
|
|
export class ColliderTriggerHelper {
|
|
|
|
|
|
private _entity: Entity;
|
2020-11-26 17:26:49 +08:00
|
|
|
|
/** 存储当前帧中发生的所有活动交点对 */
|
|
|
|
|
|
private _activeTriggerIntersections: Set<Pair<Collider>> = new Set();
|
|
|
|
|
|
/** 存储前一帧的交点对,这样我们就可以在移动这一帧后检测到退出 */
|
|
|
|
|
|
private _previousTriggerIntersections: Set<Pair<Collider>> = new Set();
|
2020-07-23 11:00:46 +08:00
|
|
|
|
private _tempTriggerList: ITriggerListener[] = [];
|
|
|
|
|
|
|
|
|
|
|
|
constructor(entity: Entity) {
|
|
|
|
|
|
this._entity = entity;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2020-11-26 17:26:49 +08:00
|
|
|
|
* update应该在实体被移动后被调用,它将处理任何与Colllider重叠的ITriggerListeners。
|
|
|
|
|
|
* 它将处理任何与Collider重叠的ITriggerListeners。
|
2020-07-23 11:00:46 +08:00
|
|
|
|
*/
|
|
|
|
|
|
public update() {
|
2020-11-26 17:26:49 +08:00
|
|
|
|
// 对所有实体.colliders进行重叠检查,这些实体.colliders是触发器,与所有宽相碰撞器,无论是否触发器。
|
|
|
|
|
|
// 任何重叠都会导致触发事件
|
2020-07-23 11:00:46 +08:00
|
|
|
|
let colliders = this._entity.getComponents(Collider);
|
|
|
|
|
|
for (let i = 0; i < colliders.length; i++) {
|
|
|
|
|
|
let collider = colliders[i];
|
2020-06-16 00:04:28 +08:00
|
|
|
|
|
2020-07-27 16:10:36 +08:00
|
|
|
|
let neighbors = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers);
|
2020-11-26 17:26:49 +08:00
|
|
|
|
for (let j = 0; j < neighbors.size; j++) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
let neighbor = neighbors[j];
|
2020-11-26 17:26:49 +08:00
|
|
|
|
// 我们至少需要一个碰撞器作为触发器
|
2020-07-23 11:00:46 +08:00
|
|
|
|
if (!collider.isTrigger && !neighbor.isTrigger)
|
|
|
|
|
|
continue;
|
2020-06-16 00:04:28 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
if (collider.overlaps(neighbor)) {
|
|
|
|
|
|
let pair = new Pair<Collider>(collider, neighbor);
|
2020-11-26 17:26:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
|
|
|
|
|
|
let shouldReportTriggerEvent = !this._activeTriggerIntersections.has(pair) &&
|
|
|
|
|
|
!this._previousTriggerIntersections.has(pair);
|
2020-06-16 09:10:09 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
if (shouldReportTriggerEvent)
|
|
|
|
|
|
this.notifyTriggerListeners(pair, true);
|
2020-06-16 09:10:09 +08:00
|
|
|
|
|
2020-11-26 17:26:49 +08:00
|
|
|
|
this._activeTriggerIntersections.add(pair);
|
2020-07-23 11:00:46 +08:00
|
|
|
|
}
|
2020-06-16 09:10:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
ListPool.free(colliders);
|
2020-06-16 09:10:09 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
this.checkForExitedColliders();
|
|
|
|
|
|
}
|
2020-06-16 09:10:09 +08:00
|
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
|
private checkForExitedColliders() {
|
2020-11-26 17:26:49 +08:00
|
|
|
|
// 删除所有与此帧交互的触发器,留下我们退出的触发器
|
|
|
|
|
|
this.excepthWith(this._previousTriggerIntersections, this._activeTriggerIntersections);
|
2020-06-16 09:10:09 +08:00
|
|
|
|
|
2020-11-26 17:26:49 +08:00
|
|
|
|
for (let i = 0; i < this._previousTriggerIntersections.size; i++) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
this.notifyTriggerListeners(this._previousTriggerIntersections[i], false)
|
|
|
|
|
|
}
|
2020-11-26 17:26:49 +08:00
|
|
|
|
|
|
|
|
|
|
this._previousTriggerIntersections.clear();
|
|
|
|
|
|
|
|
|
|
|
|
// 添加所有当前激活的触发器
|
|
|
|
|
|
this.unionWith(this._previousTriggerIntersections, this._activeTriggerIntersections);
|
|
|
|
|
|
|
|
|
|
|
|
// 清空活动集,为下一帧做准备
|
|
|
|
|
|
this._activeTriggerIntersections.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private excepthWith(previous: Set<Pair<Collider>>, active: Set<Pair<Collider>>){
|
|
|
|
|
|
for (let i = 0; i < previous.size; i ++){
|
|
|
|
|
|
let previousDATA: Pair<Collider> = previous[i];
|
|
|
|
|
|
for (let j = 0; j < active.size; j ++){
|
|
|
|
|
|
let activeDATA: Pair<Collider> = active[j];
|
|
|
|
|
|
if (activeDATA.equals(previousDATA))
|
|
|
|
|
|
previous.delete(previousDATA);
|
2020-07-23 11:00:46 +08:00
|
|
|
|
}
|
2020-06-18 09:06:59 +08:00
|
|
|
|
}
|
2020-11-26 17:26:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private unionWith(previous: Set<Pair<Collider>>, active: Set<Pair<Collider>>) {
|
|
|
|
|
|
for (let i = 0; i < this._activeTriggerIntersections.size; i ++) {
|
|
|
|
|
|
if (!this._previousTriggerIntersections.has(this._activeTriggerIntersections[i]))
|
|
|
|
|
|
this._previousTriggerIntersections.add(this._activeTriggerIntersections[i]);
|
|
|
|
|
|
}
|
2020-06-16 16:35:17 +08:00
|
|
|
|
}
|
2020-06-16 09:10:09 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
private notifyTriggerListeners(collisionPair: Pair<Collider>, isEntering: boolean) {
|
2020-11-26 17:26:49 +08:00
|
|
|
|
TriggerListenerHelper.getITriggerListener(collisionPair.first.entity, this._tempTriggerList);
|
2020-07-28 16:25:20 +08:00
|
|
|
|
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
|
|
|
|
|
if (isEntering) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
this._tempTriggerList[i].onTriggerEnter(collisionPair.second, collisionPair.first);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this._tempTriggerList[i].onTriggerExit(collisionPair.second, collisionPair.first);
|
|
|
|
|
|
}
|
2020-06-16 09:10:09 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
this._tempTriggerList.length = 0;
|
2020-06-16 09:10:09 +08:00
|
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
|
if (collisionPair.second.entity) {
|
2020-11-26 17:26:49 +08:00
|
|
|
|
TriggerListenerHelper.getITriggerListener(collisionPair.second.entity, this._tempTriggerList);
|
2020-07-28 16:25:20 +08:00
|
|
|
|
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
|
|
|
|
|
if (isEntering) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
this._tempTriggerList[i].onTriggerEnter(collisionPair.first, collisionPair.second);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this._tempTriggerList[i].onTriggerExit(collisionPair.first, collisionPair.second);
|
|
|
|
|
|
}
|
2020-06-16 09:10:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
this._tempTriggerList.length = 0;
|
|
|
|
|
|
}
|
2020-06-16 09:10:09 +08:00
|
|
|
|
}
|
2020-06-16 00:04:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-07-23 11:00:46 +08:00
|
|
|
|
}
|