Kinematic object collision with tilemap when using set_tile?

Hello, I have a kinematic player object and a level tilemap with its collision shape set to itself. If the player is at rest and I set an overlapping tile to now be an enemy tile, I expected to see a collision. But I don’t see one. Am I doing something wrong here? Or is there a way to force collision detection on unmoving kinematic objects when using set_tile?

I modified this sample project with a demonstration. A bee enemy blinks on and off at the player’s spawn point, and there are no collisions as long as the player doesn’t move: GitHub - thumbty/sample-pixel-line-platformer at tile-collision · GitHub

Might be the player’s collision object going into a “sleeping” state where it doesn’t detect the new tile. You can try manually waking the object up using physics.wakeup()/b2d.body.set_awake(), or disable sleeping with b2d.body.enable_sleep().

1 Like

It is this bug: Tilemap collision object adressing (DEF-3623) · Issue #3167 · defold/defold · GitHub
You can avoid it by moving the collision object out of game-object ‘level’.

1 Like

Thank you. I tried both solutions (b2d wake, and moving the collision object out of level), and I still don’t see a collision in either case.

Any other ideas on how to work around this?

I suggest you create a cut down version of the game containing only the issue and be specific with the details of the issue. Currently anyone looking to debug it has to spot that they need to check out your branch, search around to see what you have done, then work out what should or should not happen, and then add the fix that the bug I pointed out requires.

2 Likes

If you enable physics debug, do the collision shapes overlap visually?

If collision objects overlap you will see this if debug is on.

The collision shapes do overlap visually when physics debug is enabled.

Here is a minimal project showing the issue. If I move go_tilemap’s collision object out of go_tilemap, I still don’t see any collisions. I must be making a mistake while trying to implement the fix.

Here is the setup in this project:

  1. go_player has a kinetic collision object with group player_collision
  2. There is a tiles.tilemap inside go_tilemap , and its tile at x=1,y=1 overlaps the player
  3. go_tilemaphas a static collision object with its shape is set to tiles.tilemap
  4. The tile at x=1,y=1 in tiles.tilemap is set to tile index 2, which has a collision group tile_collision
  5. Once every second, I use set_tile to toggle this tile between tile index 2 and index 3 (tile index 3 is a blank tile with no collision group).

I would expect to see collisions get printed. I see no collisions printed.

If you press the left or right arrow keys while the two objects overlap, the player moves and you will see collisions start to print. But once you let the player object rest again, there will be no more collisions, even when set_tile(1,1,2) happens every other second.

Interestingly, if you open tiles.tilemap in the editor and change tile x=1,y=1 to be tile index 3 (a blank tile) and start the game, you will then see collisions printed the first time set_tile(1,1,2) occurs. The collisions then continue until the first time set_tile(1,1,3) occurs. After that point, there are no more collisions even when set_tile(1,1,2) happens again

set_tile_collision.zip (7.2 KB)

Looks like this issue: Make tilemap.set_tile()/factory.create() physics/collider update to be instant · Issue #9390 · defold/defold · GitHub

Edit, also, look through these: GitHub · Where software is built

and cast a vote: Defold pain points survey

Thanks. Issue 9390 seems to be about collisions being deferred. I think this may be separate, since in my case the collisions never happen at all. I didn’t see other issues similar to mine when searching

It is 9390 (might be other things as well I don’t know).

There is a logic hole in the physics update; for the case where set_tile places a tile over the player, a collision is not detected until the player moves.