|
| 1 | +--- |
| 2 | +tags: physics, box2d |
| 3 | +title: Box2D Sensors |
| 4 | +brief: Create Box2D sensors from static collision shapes. |
| 5 | +author: Defold Foundation |
| 6 | +scripts: sensor_box2d_v3.script, sensor_box2d_v2.script, spawn.script |
| 7 | +thumbnail: thumbnail.webp |
| 8 | +--- |
| 9 | + |
| 10 | +This example shows how to utilize the Box2D scripting API to operate with sensors (triggers). |
| 11 | +It spawns dynamic physics balls from slightly different random positions near the top of the scene, |
| 12 | +and gravity pulls each ball down, and these pass through two collision objects. |
| 13 | + |
| 14 | +## What You'll Learn |
| 15 | + |
| 16 | +- How to get a Box2D body from a collision object with `b2d.get_body()`. |
| 17 | +- How to turn a Box2D V2 fixture into a sensor with `b2d.fixture.set_sensor()`. |
| 18 | +- How to recreate a Box2D V3 shape as a sensor with `b2d.body.create_shape()`. |
| 19 | +- How to count V2 sensor overlaps from `trigger_response` enter/exit messages. |
| 20 | +- How to poll V3 sensor overlaps with `b2d.shape.get_sensor_overlaps()`. |
| 21 | + |
| 22 | +## Setup |
| 23 | + |
| 24 | +The collection contains one `controller` game object with `spawn.script` and a `ball_factory`. |
| 25 | +The factory creates `ball.go` - a small prototype with one sprite and one dynamic circle collision object. |
| 26 | + |
| 27 | +The two sensor game objects both contain: |
| 28 | + |
| 29 | +- `sensor_box2d_v3.script` - for Box2D V3 example handling |
| 30 | +- `sensor_box2d_v2.script` - for Box2D V2 example handling |
| 31 | +- A sprite, label, and static collision object with component id `collisionobject`. |
| 32 | + |
| 33 | +The collision objects are of type `Static` in the editor. |
| 34 | + |
| 35 | +All sensors use the `sensor` collision group and mask the `ball` group. |
| 36 | +The spawned ball belongs to the `ball` collision group and masks the `sensor` group, |
| 37 | +so the sensor overlaps only include spawned balls. |
| 38 | + |
| 39 | + |
| 40 | + |
| 41 | +The `game.project` currently uses `/box2d_v3.appmanifest`. |
| 42 | +To test V2 locally, change `Native Extensions -> App Manifest` to `/box2d_v2.appmanifest`. |
| 43 | +Gravity set in `game.project` causes the falling motion. |
| 44 | + |
| 45 | +## How It Works |
| 46 | + |
| 47 | +The controller spawns a ball repeateadly with `factory.create()`. |
| 48 | +Each ball is spawned at a random X position near the center, and is deleted after a short delay. |
| 49 | +The spawned balls pass through the sensor's collision object shapes. |
| 50 | + |
| 51 | +Each sensor has two backend scripts (V2 and V3), but only one runs processing depending on a choosen Box2D version. |
| 52 | +Each script checks `b2d.get_version().major` in `init()` and returns immediately when the active backend does not match. |
| 53 | + |
| 54 | +At startup, the active Box2D script changes the static collision geometry into a sensor (trigger) through the `b2d` API. |
| 55 | +Box2D V2 and V3 expose this through different scripting APIs: |
| 56 | + |
| 57 | +- V2 uses fixtures and Defold trigger messages. |
| 58 | +- V3 uses shapes and can poll a sensor shape's current overlaps directly. |
| 59 | + |
| 60 | +In Box2D V2, `sensor_box2d_v2.script` gets the body with `b2d.get_body("#collisionobject")`, |
| 61 | +reads the first fixture with `b2d.body.get_fixtures()`, and calls `b2d.fixture.set_sensor()`, |
| 62 | +so the fixture no longer blocks the balls. V2 fixture sensors do not expose a `get_sensor_overlaps()` polling API. |
| 63 | +But Defold still sends `trigger_response` messages when another collision object enters or exits the sensor, |
| 64 | +and the script maintains a Lua table of current overlapping ball ids. |
| 65 | + |
| 66 | +In Box2D V3, `sensor_box2d_v3.script` uses the shape API. |
| 67 | +It reads the first editor-authored shape with `b2d.body.get_shapes()` and `b2d.shape.get_shape()`, |
| 68 | +destroys that solid shape, and creates a replacement with `b2d.body.create_shape()` using the same geometry and `sensor = true`. |
| 69 | +The V3 script then calls `b2d.shape.enable_sensor_events()` for the new sensor shape. |
| 70 | +In `update()`, it polls the current overlaps with `b2d.shape.get_sensor_overlaps()`. |
| 71 | +This returns shape info tables for the shapes currently overlapping the sensor. |
| 72 | + |
| 73 | +Both scripts gives us the same result: each sensor sprite scales up while at least one ball overlaps it, |
| 74 | +and the label shows the current overlap count reported by the active backend path. |
0 commit comments