This document is about: QUANTUM 3
SWITCH TO

Quantum Physics Basics: Collisions, Triggers, and Overlap Queries

This page accompanies the Photon Quantum Physics Basics #2 - Collisions, Triggers & Overlap Queries video and explains how to detect trigger interactions, filter physics signals, configure callback flags, and use overlap queries in Quantum 3D physics.

Use this page when implementing gameplay interactions such as pressure plates, goals, pickups, damage zones, doors, or other systems that depend on collision and trigger detection.

Photon Quantum Physics Basics #2 - Collisions, Triggers & Overlap Queries

Overview

Quantum provides two main approaches for detecting physics interactions:

  • physics signals, which react to collisions or trigger events generated during the simulation;
  • physics queries, which explicitly search for colliders in a defined area.

This video demonstrates both approaches by building a small physics sample.

The player controls a soccer ball. Moving the ball through a button trigger destroys an obstacle. Once the obstacle is removed, the ball can enter a goal trigger.

The sample covers:

  • defining components for physics interactions;
  • creating a signal-only system;
  • handling ISignalOnTriggerEnter3D;
  • filtering global trigger signals by entity components;
  • configuring callback flags;
  • destroying an obstacle entity;
  • using Physics3D.OverlapShape;
  • configuring query options;
  • processing HitCollection3D;
  • detecting when the ball enters the goal.

Video Timeline

Time Section
00:00 Introduction
00:35 Scene overview
00:49 Goal of the sample
01:04 Creating components
01:46 Creating a SystemSignalsOnly system
02:29 Filtering the trigger
03:09 Signals similar to Unity callbacks
03:29 Assigning components and the system
03:42 Callback flags
04:20 Physics queries
05:24 Query options
06:08 Broadphase queries
06:34 Processing the hit result
06:50 Testing the result

Scene Setup

The sample scene contains:

  • a player-controlled soccer ball;
  • an interactable button;
  • an obstacle blocking the goal;
  • a goal made from static mesh colliders;
  • a trigger entity inside the goal.

The visible goal consists of two static mesh colliders:

  • the metal frame;
  • the net.

Inside the goal is an empty Quantum entity prototype with a PhysicsCollider3D configured as a trigger.

Sample Objective

The intended gameplay flow is:

  1. Move the soccer ball through the button trigger.
  2. Detect the trigger interaction.
  3. Destroy the obstacle in front of the goal.
  4. Move the ball into the goal.
  5. Detect the goal using an overlap query.
  6. Move or reset the ball after scoring.

The button interaction uses a physics signal.

The goal detection uses a physics overlap query.

Creating the Components

Open the existing QTN file:

TutorialPhysicsPlayground.qtn

Add three components:

  • TutorialPhysicsObstacle;
  • TutorialPhysicsInteractable;
  • TutorialPhysicsGoal.

Conceptually:

c#

component TutorialPhysicsObstacle {
}

component TutorialPhysicsInteractable {
}

component TutorialPhysicsGoal {
}

The exact declarations can include additional fields depending on the project.

Obstacle as a Singleton

For this sample, TutorialPhysicsObstacle is used as a singleton component.

This provides a simple way to retrieve the obstacle entity without searching through every entity in the frame.

The system can retrieve the singleton entity and destroy it when the button is activated.

This is suitable for the tutorial because only one obstacle exists.

For projects with multiple obstacles, doors, or switches, use explicit entity references or component data that links each interactable to its target.

Naming the Interactable Component

The component is named Interactable instead of Button.

This avoids possible name conflicts during code generation and allows the component to represent more than one type of interactive object.

For example, the same component could later be used for:

  • buttons;
  • pressure plates;
  • switches;
  • levers;
  • trigger zones.

It can also become part of a data-driven design where different interactables share common detection logic but use different configuration or behavior.

Creating a Signal-Only System

Create a new system under the project’s systems folder:

Create > Quantum > SystemSignalsOnly

Name it:

InteractableTriggerSystem

A signal-only system does not need a regular entity update loop. It reacts only to the signals represented by the interfaces it implements.

For this sample, implement:

c#

ISignalOnTriggerEnter3D

This signal is called when a physics collider enters a 3D trigger collider.

Trigger Signals Compared to Unity

ISignalOnTriggerEnter3D is conceptually similar to Unity’s OnTriggerEnter.

There is an important architectural difference.

In Unity, OnTriggerEnter is called on scripts attached to the specific GameObjects participating in the interaction.

In Quantum, a system that implements ISignalOnTriggerEnter3D receives every qualifying trigger-enter interaction in the simulation.

The system must determine which entities participated in the event and filter out interactions that are not relevant.

Trigger Interaction Data

The signal callback provides information about the two participating entities.

The exact field names depend on the signal information type, but the interaction generally contains:

  • the trigger entity;
  • the other entity entering the trigger;
  • physics interaction data.

In the sample:

  • the trigger entity must have TutorialPhysicsInteractable;
  • the other entity must be the soccer ball;
  • the interactable must not already have been activated.

Filtering the Trigger Signal

The first check verifies that the trigger entity contains the interactable component.

Conceptually:

c#

if (!frame.Has<TutorialPhysicsInteractable>(info.Entity)) {
    return;
}

Next, verify that the other entity is the ball.

For example:

c#

if (!frame.Has<TutorialPhysicsBall>(info.Other)) {
    return;
}

Finally, verify that the interactable has not already been used.

This prevents the obstacle destruction logic from running multiple times.

The specific implementation can use:

  • a boolean field in the interactable component;
  • removal of the interactable component;
  • a separate activated component;
  • destruction or disabling of the trigger.

Destroying the Obstacle

After validating the interaction, retrieve the entity associated with the obstacle singleton.

Check that the singleton exists before trying to destroy it.

Conceptually:

c#

if (frame.TryGetSingletonEntity<TutorialPhysicsObstacle>(
        out var obstacleEntity)) {
    frame.Destroy(obstacleEntity);
}

After the obstacle entity is destroyed, the path to the goal becomes available.

Other Physics Signals

Quantum provides signals for several types of physics interaction.

Common 3D signals include:

Signal Purpose
ISignalOnTrigger3D Called while a trigger interaction is active.
ISignalOnTriggerEnter3D Called when an entity enters a trigger.
ISignalOnTriggerExit3D Called when an entity leaves a trigger.
ISignalOnCollision3D Called while a collision is active.
ISignalOnCollisionEnter3D Called when a collision begins.
ISignalOnCollisionExit3D Called when a collision ends.

Equivalent signals are available for Quantum 2D physics.

Choose the signal based on whether the gameplay logic needs to react:

  • once when contact begins;
  • continuously while contact exists;
  • once when contact ends.

Assigning Components

Return to Unity and assign the new components to the appropriate entity prototypes.

Suggested setup:

Entity Component
Button trigger TutorialPhysicsInteractable
Blocking obstacle TutorialPhysicsObstacle
Goal trigger TutorialPhysicsGoal
Soccer ball Existing ball-identification component

Then add InteractableTriggerSystem to the Physics Playground Systems Config.

If the system is not registered, Quantum will not instantiate it and the signal handler will never run.

Callback Flags

Physics signals are not generated automatically for every possible interaction.

The relevant callback flags must be enabled on the entity prototype.

For the button trigger, enable:

OnDynamicTriggerEnter

This tells Quantum to generate the trigger-enter callback when a dynamic physics body enters the trigger.

Without this flag, ISignalOnTriggerEnter3D will not be called for the interaction.

Choosing Callback Flags

Enable only the callback flags required by the gameplay.

Callback generation has a simulation cost. Avoid enabling every collision and trigger callback on every collider without a specific need.

Select flags based on:

  • whether the other object is dynamic, kinematic, or static;
  • whether the interaction is a collision or trigger;
  • whether enter, continuous, or exit behavior is needed.

Testing the Button Trigger

After assigning components, registering the system, and enabling the callback flag:

  1. Enter Play Mode.
  2. Move the ball through the button trigger.
  3. Verify that the trigger signal is received.
  4. Confirm that the obstacle entity is destroyed.

The button portion of the sample is now complete.

Detecting the Goal with a Physics Query

The next step is detecting whether the soccer ball enters the goal.

Instead of using another trigger callback, the sample demonstrates a physics query.

The logic is added to the existing:

PlayerControllerSystem

Create a new method:

c#

CheckForBallEnteringGoal

Pass the current frame and the system filter into the method.

Conceptually:

c#

private void CheckForBallEnteringGoal(
    Frame frame,
    ref Filter filter) {
}

Physics3D Queries

Quantum 3D physics queries are available through:

c#

frame.Physics3D

Quantum 2D projects have a corresponding:

c#

frame.Physics2D

The sample uses:

c#

frame.Physics3D.OverlapShape

An overlap query checks which colliders overlap a specified shape at a specified position and rotation.

Creating the Overlap Shape

First, retrieve the ball’s transform.

Then create a sphere query matching the ball’s collider radius.

Conceptually:

c#

var transform = filter.Transform;
var collider = filter.PhysicsCollider;

var radius = collider->Shape.Sphere.Radius;
var shape = Shape3D.CreateSphere(radius);

Run the overlap query using:

  • the ball position;
  • the ball rotation;
  • the sphere shape;
  • the required query options.

Example structure:

c#

var hits = frame.Physics3D.OverlapShape(
    transform->Position,
    transform->Rotation,
    shape,
    queryOptions
);

Using the same radius as the ball collider makes the query represent the ball’s occupied space.

Query Options

The options parameter determines which collider types the query can detect and which information is calculated.

The sample needs to detect the goal trigger.

Use:

c#

QueryOptions.HitTriggers

Quantum requires this to be combined with the relevant body category.

For this sample, combine it with:

c#

QueryOptions.HitKinematics

Use the bitwise OR operator:

c#

var queryOptions =
    QueryOptions.HitTriggers |
    QueryOptions.HitKinematics;

The exact category required depends on how the target collider is represented in the physics world.

Detailed Hit Information

Basic overlap queries do not necessarily populate information such as:

  • hit position;
  • contact point;
  • surface normal;
  • other detailed collision data.

To request these values, include:

c#

QueryOptions.ComputeDetailedInfo

Example:

c#

var queryOptions =
    QueryOptions.HitTriggers |
    QueryOptions.HitKinematics |
    QueryOptions.ComputeDetailedInfo;

The goal detection only needs the entity reference, so detailed information is not required in this sample.

Avoid computing detailed information unless the gameplay actually uses it.

Query Results

OverlapShape returns:

c#

HitCollection3D

This collection contains the physics hits found by the query.

Iterate over the collection with a loop:

c#

for (var i = 0; i < hits.Count; i++) {
    var hit = hits[i];
}

For each hit, check whether the hit entity contains:

c#

TutorialPhysicsGoal

If it does, the ball is overlapping the goal trigger.

Processing the Goal Hit

Conceptually:

c#

for (var i = 0; i < hits.Count; i++) {
    var hit = hits[i];

    if (!frame.Has<TutorialPhysicsGoal>(hit.Entity)) {
        continue;
    }

    filter.Transform->Position = FPVector3.Up;
    return;
}

The tutorial moves the player to:

c#

FPVector3.Up

This corresponds to the position:

0, 1, 0

In a full game, scoring could instead:

  • increment a score;
  • reset the ball;
  • trigger an event;
  • play a view-side effect;
  • start a new round;
  • update match state.

Broadphase Queries

When typing frame.Physics3D, the API also exposes methods with names similar to:

Add...Query

These are broadphase queries that are scheduled as part of the physics step.

They can benefit from parallel resolution and can be significantly faster than running a regular query after physics processing.

The query used in this tutorial is executed directly after physics and is sufficient for the sample.

For systems that perform many queries every frame, consider using the broadphase query APIs described in the Quantum Queries documentation.

Signals vs Queries

Signals and queries solve related but different problems.

Approach Best Used When
Trigger or collision signal Logic should react when a physics interaction begins, continues, or ends.
Overlap query A system needs to explicitly check an area at a chosen time.
Raycast or shape cast A system needs to test along a direction or movement path.
Broadphase query Many queries need to be scheduled efficiently during physics processing.

Use signals for event-driven behavior.

Use queries when the simulation needs to ask a specific spatial question.

Testing the Goal Detection

After implementing the query:

  1. Add TutorialPhysicsGoal to the goal trigger entity.
  2. Enter Play Mode.
  3. Move the ball through the button.
  4. Confirm that the obstacle is destroyed.
  5. Move the ball into the goal.
  6. Verify that the ball moves to FPVector3.Up.

This confirms that the overlap query detects the goal correctly.

Key Concepts

Concept Description
Physics signal Interface callback generated by Quantum for a physics interaction.
SystemSignalsOnly A system that reacts to signals without a regular update loop.
ISignalOnTriggerEnter3D Called when a collider enters a 3D trigger.
Callback flag Entity configuration that determines which physics callbacks Quantum generates.
OnDynamicTriggerEnter Enables trigger-enter callbacks involving a dynamic body.
Physics query Explicit request to search the physics world.
Physics3D.OverlapShape Finds colliders overlapping a specified 3D shape.
Shape3D.CreateSphere Creates a sphere shape for a physics query.
QueryOptions Controls which collider types and data the query returns.
HitCollection3D Collection of 3D physics query results.
Broadphase query Query scheduled as part of the physics step for more efficient processing.
Singleton component Component used to access a unique entity without searching all entities.

Best Practices

Use this checklist when implementing Quantum physics interactions:

  • Use signal-only systems for logic that only reacts to physics callbacks.
  • Treat physics signals as global and filter them by the participating entities.
  • Identify entities with components instead of relying on Unity GameObject names.
  • Enable only the callback flags that are required.
  • Confirm that the correct dynamic, kinematic, or static callback category is enabled.
  • Register every new system in the appropriate Systems Config.
  • Use trigger signals for event-driven interactions.
  • Use overlap queries for explicit area checks.
  • Match query shapes to the gameplay object where appropriate.
  • Request detailed query information only when needed.
  • Check hit entities for identifying components before processing them.
  • Use broadphase query APIs when performing many queries every frame.
  • Use explicit entity references instead of singletons when multiple targets can exist.
  • Keep simulation-side scoring logic separate from Unity-side sound, UI, and visual effects.

Common Pitfalls

Pitfall Why It Is a Problem
Assuming a trigger signal belongs only to one entity Quantum systems receive all qualifying interactions and must filter them.
Forgetting callback flags The physics signal will not be generated.
Checking the wrong interaction entity Trigger and other entity references must be interpreted correctly.
Not registering the signal system Quantum will not create or run the system.
Reusing generic names such as Button Names may conflict with other generated or framework types.
Using HitTriggers without the required body category The query may not include the intended collider.
Requesting detailed hit information unnecessarily Adds work when only an entity reference is needed.
Assuming overlap results contain only the goal Every result must be filtered by component or layer.
Using a singleton for a system with multiple obstacles A singleton represents only one instance and does not scale to multiple targets.
Running many immediate queries every frame Broadphase queries may be more efficient for query-heavy systems.

Summary

Quantum supports event-driven physics detection through signals and explicit spatial checks through physics queries.

The button interaction uses ISignalOnTriggerEnter3D. Because the signal system receives all trigger interactions, it filters the participants by their Quantum components before destroying the obstacle.

The goal detection uses Physics3D.OverlapShape with a sphere matching the player ball. The query is configured to detect trigger and kinematic colliders, then its HitCollection3D results are filtered for the goal component.

Together, signals and queries provide the core tools needed to implement gameplay systems based on collisions, triggers, and spatial detection.

Back to top