Skip to main content

CollisionEvent

3D collision event types.

TypeNameInterface Description
VariablesEnter: UserEventType

Function: Fired once when this collider is found colliding with another collider for the first time. In 3D, APJS computes this by comparing the current contact set with the previous update.

VariablesExit: UserEventType

Function: Fired once when a collider that was colliding on the previous update is no longer colliding.

VariablesStay: UserEventType

Function: Fired on each update while this collider continues colliding with the same other collider.

Functionsconstructor()

Examples

constructor()

let obj = new APJS.CollisionEvent();

Use Case

Example 1 — 3D physics collision event handler. Listens on BoxCollider/SphereCollider for Enter/Stay/Exit events.

@component()
export class CollisionHandler3D extends APJS.BasicScriptComponent {
private collider: APJS.Collider;
private inited = false;
private hitCount = 0;

private onEnter = (event: APJS.IEvent) => {
this.hitCount++;
const infos = event.args[0] as APJS.CollisionInfo[];
for (const info of infos) {
if (info.otherObject) {
console.log("[Collision] Enter #" + this.hitCount + ": " + info.otherObject.name);
console.log(" point: " + info.point.x.toFixed(2) + ", " + info.point.y.toFixed(2) + ", " + info.point.z.toFixed(2));
console.log(" normal: " + info.normal.x.toFixed(2) + ", " + info.normal.y.toFixed(2) + ", " + info.normal.z.toFixed(2));
}
}
};

private onExit = (event: APJS.IEvent) => {
console.log("[Collision] Exit");
};

// RecordStart: only the script-owned hitCount accumulator needs reset; this example
// does not move any RigidBody, so no Physics3D reset block is needed. See GameState SKILL.
private onRecordStart = (_event: APJS.IEvent) => {
this.hitCount = 0;
};

onStart(): void {
APJS.EventManager.getGlobalEmitter().on(APJS.EventType.RecordStart, this.onRecordStart);
}

onUpdate(dt: number): void {
if (!this.inited) {
const obj = this.getSceneObject();
if (!obj) return;

// Try BoxCollider first, then SphereCollider
this.collider = obj.getComponent("BoxCollider") as APJS.BoxCollider;
if (!this.collider) {
this.collider = obj.getComponent("SphereCollider") as APJS.SphereCollider;
}
if (!this.collider) return;
this.inited = true;

this.collider.emitCollisionEvent = true;

// CRITICAL: pass collider, NOT sceneObject
const emitter = APJS.EventManager.getObjectEmitter(this.collider);
emitter.on(APJS.CollisionEvent.Enter, this.onEnter, this);
emitter.on(APJS.CollisionEvent.Exit, this.onExit, this);
}
}

onDestroy(): void {
if (this.collider) {
const emitter = APJS.EventManager.getObjectEmitter(this.collider);
emitter.off(APJS.CollisionEvent.Enter, this.onEnter, this);
emitter.off(APJS.CollisionEvent.Exit, this.onExit, this);
}
APJS.EventManager.getGlobalEmitter().off(APJS.EventType.RecordStart, this.onRecordStart);
}
}

Example 2 — Play a sound effect when a 2D physics object collides — uses CollisionEvent2D.Enter on collider's object emitter

@component()
export class CollisionSoundEffect extends APJS.BasicScriptComponent {
@serializeProperty
sfxPlayer!: APJS.SceneObject;

private sfxAudio!: APJS.AudioComponent;
private collider!: APJS.BoxCollider2D;
private initialized = false;
private collisionCallback!: (event: APJS.IEvent) => void;

onUpdate(dt: number): void {
if (this.initialized) return;
if (!this.sfxPlayer) return;

this.sfxAudio = this.sfxPlayer.getComponent("AudioComponent") as APJS.AudioComponent;
// Get any 2D collider on this object (BoxCollider2D or CircleCollider2D)
this.collider = this.getSceneObject().getComponent("BoxCollider2D") as APJS.BoxCollider2D;
if (!this.sfxAudio || !this.collider) return;

// CRITICAL: enable collision events before registering listener
this.collider.emitCollisionEvent = true;

this.collisionCallback = (event: APJS.IEvent) => {
// Play SFX on each collision
this.sfxAudio.stop();
this.sfxAudio.loopCount = 1;
this.sfxAudio.play();
};

// Use object emitter on the COLLIDER (not global emitter)
const emitter = APJS.EventManager.getObjectEmitter(this.collider);
emitter.on(APJS.CollisionEvent2D.Enter, this.collisionCallback, this);
this.initialized = true;
}

onDestroy(): void {
if (this.collider && this.collisionCallback) {
const emitter = APJS.EventManager.getObjectEmitter(this.collider);
emitter.off(APJS.CollisionEvent2D.Enter, this.collisionCallback, this);
}
}
}
Copyright © 2026 TikTok. All rights reserved.
About TikTokHelp CenterCareersContactLegalTerms of ServicePrivacy PolicyCookies