godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.81k stars 20.14k forks source link

TileMap's clip_children does not work #72611

Open qwe3121 opened 1 year ago

qwe3121 commented 1 year ago

Godot version

Godot 4 beta 17

System information

Windows 11, Vulcan, GTX 1050 TI (driver geforce game ready 528.24)

Issue description

TileMap's clip_children does not work

Steps to reproduce

1) Create Tilemap 2) Add Sprite2D as a child (or TextureRect) 3) Try to use clip_children

Minimal reproduction project

TileMapClipChildren.zip

CodestarGames commented 10 months ago

https://github.com/godotengine/godot/issues/84501 Looks to be a duplicated issue

BrixsterPlanet commented 10 months ago

@KoBeWi's comment on my duplicate issue should be noted:

Same issue as https://github.com/godotengine/godot/issues/31413 TileMap uses internal Canvasitems, which affects some rendering features.

dastmo commented 4 months ago

It appears that #31413 was fixed and merged. Has anyone tested if that fix addresses this issue as well?

akien-mga commented 4 months ago

This doesn't seem to be fixed in latest master (86bf8354a06ab7b23a0ff6a81b48fd015e92ac94).

CC @groud @KoBeWi @clayjohn

groud commented 4 months ago

I don't think this is fixable. The problem is that clip_children relies on the CanvasItem hierachy in the RenderingServer, and each TileMap / TileMapLayer nodes does have several of those (one or more per quadrant). This is done that way for performance reason and cannot be changed.

Internally, the hierarchy looks like this:

- TileMapLayer's built-in CanvasItem -> unused, nothing is drawn there
   - Quadrant 0 's internal CanvasItem 0 -> used to draw the tiles on quadrant 0, for the first material found
   - Quadrant 0 's internal CanvasItem 1 -> used to draw the tiles on quadrant 0, for the second material found and so on
   - Quadrant 1 's internal CanvasItem 0
   - Quadrant 2 's internal CanvasItem 0
   - Quadrant 3 's internal CanvasItem 0
   - etc...
   - Child nodes CanvasItems -> this is where child nodes end up in the hierarchy.    

Basically, there's nothing drawn on the TileMapLayer's built-in CanvasItem, which make it impossible to clip the children.

I can't think of a way to work this around, so I would probably document somewhere the property won't work (or disable it in the inspector IDK)

dastmo commented 4 months ago

Well, I have found a hacky workaround:

hunterloftis commented 4 months ago

I've also been working around this issue:

image

Obviously, not a fun workaround, but it allows you to continue editing the tilemap in godot with realtime updates to the map visuals, physics layers, and mask.

However, this is a common use-case and I wonder if it really is unsolvable based on Godot's architectural choices for CanvasItems and TileMap. It seems like a naive solution might copy the contents of the internal CanvasItems into the TileMapLayer's main CanvasItem. This may not be efficient, but neither are the workarounds that are necessary to overcome this limitation. I would happily accept a yellow warning tooltip - "Clipping TileMaps negates many TileMap rendering optimizations; performance will suffer" - rather than just have the feature totally break as it does today.

groud commented 4 months ago

However, this is a common use-case and I wonder if it really is unsolvable based on Godot's architectural choices for CanvasItems and TileMap. It seems like a naive solution might copy the contents of the internal CanvasItems into the TileMapLayer's main CanvasItem. This may not be efficient, but neither are the workarounds that are necessary to overcome this limitation. I would happily accept a yellow warning tooltip - "Clipping TileMaps negates many TileMap rendering optimizations; performance will suffer" - rather than just have the feature totally break as it does today.

Whether this is common enough has to be debated, but the solution you describe here shouldn't be too hard to implement. Making clip_children forcing the drawing on the main canvas item sounds like a good idea to me.

hunterbk commented 4 months ago

This is fixable, imo the best way to do it would to be adding functionality for each tile's properties to have the clip contents property, since they already have most of the other properties of CanvasItem