Open yhwhey opened 2 years ago
You mean you want to place the same tile on 2 layers? But wouldn't one layer be fully covered by the higher one? Some images could be helpful.
Also your custom data approach is possible if you don't need the tiles in the editor or at least not immediately. You can iterate all placed tiles with a script and mirror them on another layer.
This screenshot should help illustrate what I mean. the leftmost tile is composed of 3 separate sprites across 3 layers. the entity sits between those. you can see the two separate sprites required. the two 'grass' sprites are always set on the same tile together and must be on different layers
I came up with this script:
@tool
extends TileMap
var UPPER_LAYER = 1
var LOWER_LAYER = 0
var previous_used_cells: int
func _ready() -> void:
if Engine.is_editor_hint():
create_tween().set_loops().tween_callback(mirror_cells).set_delay(0.5) # Avoid updating too often.
func mirror_cells():
var used_cells = get_used_cells(LOWER_LAYER)
if used_cells.size() != previous_used_cells:
clear_layer(UPPER_LAYER)
previous_used_cells = used_cells.size()
for cell in used_cells:
var tile = get_cell_atlas_coords(LOWER_LAYER, cell)
if tile == Vector2i(0, 0):
set_cell(UPPER_LAYER, cell, 0, Vector2i(1, 0))
https://user-images.githubusercontent.com/2223172/189772722-439f73df-439c-4559-aaa7-ed7e8c78d407.mp4
This is a great solution thanks. Will definitely make use of it. It is a workaround though and I wonder if there is value in having a more obvious solution built into the tilemap node
This proposal is interesting but seems like quite a specific need, and would be very tedious to implement. It's likely better as a plugin unless a lot of people ask for it.
My use case is quite specific for sure. Generalising it to: "enabling arbitrary code to be executed when a cell is set" would have broad usage imo
@yhwhey Tilemap.changed
is emitted when a cell is set (which its description does not make clear).
Not great performance wise, though. I think either a private function like "_on_set_cell" or emitting a signal would be good (maybe you want to do things like deleting or moving other nodes if a wall is placed on top of them). I'd like a signal that emits a list of changed cells best, because you can change multiple tiles per frame and that would be better performance-wise if you want to do something like custom auto-tiling.
Describe the project you are working on
A 2D grid-based tactics game with heavy used of layered graphics to create depth (Godot 4 latest alpha)
Describe the problem or limitation you are having in your project
This is specifically a level design workflow problem although could be extended to be useful during game execution.
I have several tilemap layers for allowing entities to be sandwiched between background and foreground graphics layers For example some of the layers i have which are sorted by y offset: GROUND GROUND_DECORATION (e.g. long_grass_background) EFFECT <----- entities go here GROUND_DECORATION_FOREGROUND (e.g. long_grass_foreground) EFFECT_FOREGROUND
The tile sprites that are used for the background and foreground are related, they are always set together. What this means is if i want to place some long grass in a map, I need to manually set the GROUND_DECORATION layer with the background sprite and the GROUND_DECORATION_FOREGROUND layer with the foreground sprite. This is an extremely tedious and error prone process.
I have considered using the tileset custom data to associate the fore and back ground sprites and when the background sprite is set, use a tool script to automatically set the foreground sprite on the correct layer. However, as far as I can tell there is no facility for custom behaviour when setting a cell via the editor. I tried overriding the set_cell method but this is not possible see 65685
Describe the feature / enhancement and how it helps to overcome the problem or limitation
I'm not sure the best way to achieve this but I can see a couple of options. I'm sure there are others
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
implement a tilemap_cell_set signal which is emitted when a cell is set. not sure how performant this would be if setting lots of tiles all at once
Or
Allow overriding the set_cell method
If this enhancement will not be used often, can it be worked around with a few lines of script?
I have spent time investigating and researching how this could otherwise be achieve and I couldn't find a way to do it
Is there a reason why this should be core and not an add-on in the asset library?
This facility would be widely useful for triggering custom logic based on setting tiles