Layers and contact callbacks
Open the live demo · Read the source · View on GitHub
Two colliders are tested against each other only when each is in the
other's mask. Which bit means what is not this package's business: it ships
one constant, Layers.all, and a game names the rest itself.
Step 1: A zone that only wants one layer #
A trigger blocks nothing and only reports. Its mask names the one layer it cares about, so a collider outside that layer is never even tested against it, whatever mask that other collider carries.
// The zone's mask names one layer, so only a collider carrying that bit
// is ever considered for it, whatever mask that collider carries itself.
final Collider zone = Collider(
shape: CollisionSphere(0.6),
position: _zoneCentre,
kind: ColliderKind.trigger,
mask: _kPlayerLayer,
listener: _listener,
);
_world.add(zone);
Step 2: Two movers, two layers #
The player carries the layer the zone's mask names. The enemy does not. Both start well away from the zone.
_player = _world.add(
Collider(
shape: CollisionBox(Vector3(0.3, 0.3, 0.3)),
position: _away,
kind: ColliderKind.kinematic,
layer: _kPlayerLayer,
userData: 'player',
),
);
_enemy = _world.add(
Collider(
shape: CollisionBox(Vector3(0.3, 0.3, 0.3)),
position: _away,
kind: ColliderKind.kinematic,
layer: _kEnemyLayer,
userData: 'enemy',
),
);
_world.update();
Step 3: Walk both of them in #
Moving a collider is only ever moveTo; the world does the rest the next
time it is asked to update.
// Both walk into the same spot. Only the one carrying the layer the
// zone's mask names will be heard.
_player.moveTo(_zoneCentre);
_enemy.moveTo(_zoneCentre);
_world.update();
Step 4: Who gets heard #
Only the player's arrival should reach the listener. The enemy touches exactly the same point in space and is never even considered, because the zone's mask never named its layer.
if (_listener.started.length != 1 || _listener.started.first != 'player') {
throw StateError(
'only the player should have entered the zone, got ${_listener.started}',
);
}
Note.
CollisionListeneris a mixin with three defaults, all empty. Almost everything overrides onlyonCollisionStart;onCollisionfires on every step two colliders keep overlapping, andonCollisionEndonce they stop.