Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collision exceptions don't work with TileMap node #17090

Closed
Tracked by #45334
nmearl opened this issue Feb 27, 2018 · 6 comments
Closed
Tracked by #45334

Collision exceptions don't work with TileMap node #17090

nmearl opened this issue Feb 27, 2018 · 6 comments

Comments

@nmearl
Copy link

nmearl commented Feb 27, 2018

Godot version:
v3.0.1.stable.official

OS/device including version:
elementary OS 0.4.1 Loki
Ubuntu 16.04.3 LTS
Linux 4.13.0-36-generic

Issue description:
Using the add_collision_exception_with method of a KinematicBody2D when the other Node is a TileMap does not result in collisions being excepted.

Expected behavior that KinematicBody2D falls through TileMap.

Steps to reproduce:

  • Generate Tileset from scene with hierarchy
+ Node2D
  + Sprite
    + StaticBody2D
      - CollisionPolygon2D
  • Create new scene with a TileMap and KinematicBody2D.
  • Add Tileset to TileMap and create a platform for the KinematicBody2D.
  • On key event, attempt to add collision exception between TileMap and KinematicBody2D using add_collision_exception_with(get_node("../TileMap"))
@davi2205
Copy link
Contributor

I have the same problem :/

@KoBeWi
Copy link
Member

KoBeWi commented Jul 14, 2020

Still valid in 07db4d5

Here's MRP:
ReproductionProject.zip

EDIT:
For the record, this is also an issue with raycasts: #22891

@jakefriend-dev
Copy link

For anyone coming across this and looking for a mid-term solution for raycasting past a TileMap, I worked around this with a process of replacing TileMap-based exception addds with shifting the Raycast2D along its own length, then shortening the length.

So, instead of adding an exception, the Raycast2D is moved along its length by a set increment (and shortened, so that the initial distance doesn't get extended). You continue to loop as if there's an exception, and eventually you'll either get past the TileMap collision, see something else, or run out of length to increment. Seems to work fine in practice! You do need to remember to reset the raycast's length at the start of your loop.

@knightofiam
Copy link

Confirming issue still exists in 3.5 stable with RayCast2D.

knightofiam added a commit to forerunnergames/coa that referenced this issue Aug 17, 2022
Problem:

  - Player can't drop down through frozen waterfall ground. This is
    caused by a known bug in Godot that doesn't allow RayCast2D to add
    collision exceptions for TileMaps. Because of this bug, the player's
    feet raycasts can't detect both the normal cliff ground and the
    frozen waterfall ground at the same time because they are at the
    exact same height, but both must be disabled to allow dropping down
    through the frozen waterfall ground.

Solution:

  - Add workaround in Dropdown.cs to allow RayCast2D to ignore TileMap
    collisions in order to disable both the cliff ground and the frozen
    waterfall ground that are at the same exact height. This was
    supposed to be fixed by #66 "Fix multi-ground dropdown bug", but it
    only addressed multiple non-overlapping ground colliders being
    side-by-side at the same height, where the player's feet raycasts
    were colliding with multiple, horizontally-parallel ground
    colliders. This completes the fix for #66 by addressing the player's
    feet raycasts colliding with multiple ground colliders overlapping
    each other at the same height.

  - The workaround involves looping RayCast2D collisions multiple
    times per frame to get all of them instead of just the first one it
    hits:

      1. In the loop, check if the collision object is a TileMap & if so
         add it manually to a custom list of TileMap exceptions.

      2. Each iteration check if the collision object is both a TileMap
         & in the exception list & if so ignore it.

      3. Force the raycast to update in the same frame using
         RayCast2D#ForceRaycastUpdate

      4. Clear the TileMap exception list outside of & before the loop.

Miscellaneous:

  - Improve clarity of logging message in TileMapDropdownable.cs to help
    with debugging.

See godotengine/godot#17090 "Collision
exceptions don't work with TileMap node" for more information.
knightofiam added a commit to forerunnergames/coa that referenced this issue Aug 17, 2022
Problem:

  - Player can't drop down through frozen waterfall ground. This is
    caused by a known bug in Godot that doesn't allow RayCast2D to add
    collision exceptions for TileMaps. Because of this bug, the player's
    feet raycasts can't detect both the normal cliff ground and the
    frozen waterfall ground at the same time because they are at the
    exact same height, but both must be disabled to allow dropping down
    through the frozen waterfall ground.

Solution:

  - Add workaround in Dropdown.cs to allow RayCast2D to ignore TileMap
    collisions in order to disable both the cliff ground and the frozen
    waterfall ground that are at the same exact height. This was
    supposed to be fixed by #66 "Fix multi-ground dropdown bug", but it
    only addressed multiple non-overlapping ground colliders being
    side-by-side at the same height, where the player's feet raycasts
    were colliding with multiple, horizontally-parallel ground
    colliders. This completes the fix for #66 by addressing the player's
    feet raycasts colliding with multiple ground colliders overlapping
    each other at the same height.

  - The workaround involves looping RayCast2D collisions multiple
    times per frame to get all of them instead of just the first one it
    hits:

      1. In the loop, check if the collision object is a TileMap & if so
         add it manually to a custom list of TileMap exceptions.

      2. Each iteration check if the collision object is both a TileMap
         & in the exception list & if so ignore it.

      3. Force the raycast to update in the same frame using
         RayCast2D#ForceRaycastUpdate

      4. Clear the TileMap exception list outside of & before the loop.

Miscellaneous:

  - Improve clarity of logging message in TileMapDropdownable.cs to help
    with debugging.

See godotengine/godot#17090 "Collision
exceptions don't work with TileMap node" for more information.
@knightofiam
Copy link

For anyone coming across this and looking for a mid-term solution for raycasting past a TileMap, I worked around this with a process of replacing TileMap-based exception addds with shifting the Raycast2D along its own length, then shortening the length.

So, instead of adding an exception, the Raycast2D is moved along its length by a set increment (and shortened, so that the initial distance doesn't get extended). You continue to loop as if there's an exception, and eventually you'll either get past the TileMap collision, see something else, or run out of length to increment. Seems to work fine in practice! You do need to remember to reset the raycast's length at the start of your loop.

There's a simpler TileMap workaround in case you're looping RayCast2D collisions multiple times per frame to get all of them instead of just the first one it hits:

  1. In the loop, check if the collision object is a TileMap and if so add it manually to a custom list of TileMap exceptions.

  2. Each iteration check if the collision object is both a TileMap and in the exception list and if so ignore it.

  3. Force the raycast to update in the same frame using RayCast2D#ForceRaycastUpdate.

(Don't forget to clear the exception list first, outside the loop.)

You can see my full working code for this here.

@akien-mga
Copy link
Member

Closed by #73851.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants