Closed jeffbdavenport closed 1 month ago
Forgive me for my ignorance but I didn't actually check-out the project or run the tests, I just copied the TileMapDual.gd
file over. I was very interested in your project but took me like 30 minutes before I could figure out how to get it to work.
I wanted to make it more intuitive for me, so this was the approach that I took and I thought maybe I should at least share what I did.
The biggest issue with my approach right now is that using right click to delete placed tiles is very aggressive and seems to delete more than necessary and adding tiles where some have been removed does not always work (Because the top_left tile you are clicking on exists, even though the top_right one does not underneath. I haven't been able to figure out a good solution to either of these
@pablogila I checked out the tests and made everything work with the tests. I didn't realize that your code was automatically figuring out what tiles to use instead of relying on Godot's terrain Match Corner setup, I liked what you did much better because you don't have to configure every tileset you upload, so I switched it back to using that. Also that resolved the other two issues I mentioned before. You should just be able to paste in the code from TileMapDual, reopen the scene and it should work (So that _process() gets connected). On the Isometric scene I moved the TileMapDual outside of the TileMap.
Thank you for sharing this interesting approach. I like the idea of automatically creating the displaced TileMapLayer and I appreciate your work on this.
I've noticed a couple of bugs that might be worth discussing. First, the tilemap isn't updated at startup, so it appears empty at runtime. Also, there is no way to update the map in-game as the CursorDual node does not work.
However, I'm particularly interested in the decision to run this at _process. The main version has a focus on optimising performance, especially in the case of large maps and/or for lower-end devices. Maybe I'm missing something, but I still don't see the advantage of using _process over the API calls implemented in the main release for in-game updates. If you could please explain the reason for this, I'm all ears. From what I can see, maybe we could just update it through _process in the editor, while limiting to API calls in-game to improve performance.
Thanks!
@pablogila I made changes to fix the bugs that I could see with the startup not updating, and display issues with CusorDual.
I have to admit though, I am really confused. Before now, I didn't click play on these because I didn't realize what the CursorDual was. Upon doing this, I don't think I understand what this is for? It seems like CursorDual was created so that people could see live updates to their DualGrid editing. Which is what my changes allow for within the editor. I also don't really understand what the issue is with using _process as you are using _process in CursorDual? Wouldn't that have the same performance penalty? In the _process on the TileMapDual, it only does anything if the size of the tile_map_data has changed. Which will only happen in the editor.
Also, even on your main branch I am unable to successfully get the editor to actually show the updates I try to make in game, even if I click on "Update in Editor" how do you accomplish that?
I have made a PR to add a cell_changed signal for cell updates on Godot https://github.com/godotengine/godot/pull/97896 https://github.com/godotengine/godot-proposals/issues/10917
CursorDual is just an example of how to draw tiles inside the game. You just need to assign the corresponding tilemaps to it, and it will draw the tiles as you click. But it is just an example of how to use the API calls described in the README.
To update the tileset in-editor, you just have to create and configure your desired tilemap, and add a TileMapDual node with a reference to your tilemap. Then just click the update checkbox. It should work automatically, and it does indeed work for the available tests in the main branch. If that is not the case for you, could you please share the steps to reproduce it?
I am using godot 4.3 and I am trying to do it in the main branch with any and all of your test scenes. I do exactly as you decribe, run the game, paint some tiles, and then click on "Update in Editor" in the editor while the game is still running and nothing happens for me.
Mind that the tiles must be painted in the world TileMapLayer, not in the TileMapDual!
If I understood you correctly, you were trying to draw tiles in-game, but from the editor. But the Update button lnly works for tiles drawn indide thi editor. To draw in-game, you have to call the API, that's what CursorDual does. You just click with your mouse inside the game, and it paints the tiles.
Given the confusion it seems like a good idea to simplify this process.
No, I was trying to draw the tiles in the game and get the changes in game to show up in the editor. And yes I understand that is what CursorDual.gd is supposed to do. But I am not going to keep trying to figure it out because I don't need CursorDual for my games. I just needed a way to created my levels in the editor efficiently, and my changes work for that for me
Oh ok I get it now. Glad it works for your game! I am a bit busy these weeks, but I want to work a bit more in this direction. I thought about the implementation of both the stand-alone tilemap and the real-time update only inside the editor, it will take several modifications but it's definitely worth it. All said, let's merge to dev! Thanks Jeff for your contribution! :D
Sounds great, also there is a PR in Godot to add a _updates_tiles() callback to TileMapLayer that has the coords for all the changed tiles which can replace _process once it's available.
Great to know! I will follow it closely...
I have just merged a huge update to main. I simplified the code, now it only runs on process in the editor, while using signals in game for best performance. Very happy with this update, thanks again Jeff for your ideas!
Just checked it out, very nice! Much better than my implementation. I like it
Remove the need for 2nd
TileMap
and make updates happen in real time efficiently. Adds a slight memory overhead as we need to keep track of the used_cells in an array in order to make this possible.Just add the
TileMapDual
node and create aTileSet
for it, and just paint the tiles as normal and it will update properly.This is achieved by adding a child
TileMap
node inside of theTileMapDual
which is hidden from the users view.Also switched to use
get_neighbor_cell(cell, TileSet.CellNeighbor.CELL_NEIGHBOR_DIRECTION)
so that we don't need to calculate whether isometric or not manually