- Edited
Oh, that sounds like exactly what I need! I will try that, thank you! Will it still work with TileMapLayers?
Edit:
Sorry for being a bit thick, but how can I copy tiles between tilemaps?
Oh, that sounds like exactly what I need! I will try that, thank you! Will it still work with TileMapLayers?
Edit:
Sorry for being a bit thick, but how can I copy tiles between tilemaps?
Tomkun With tile map layers you need to implement _tile_data_runtime_update()
I am really going around in circles with this. Would someone be kind enough to give me some pseudo-code about how this might look?
I have a main scene with two TileMapLayers called "HiddenFloorLayer" and "RevealedFloorLayer".
HiddenFloorLayer has the complete level layout, but is hidden.
RevealedFloorLayer has visible but empty.
I have a "Hero" who projects a raycast in front of him and sends the coords to the _update_tile function in RevealedFloorLayer.
In RevealedFloorLayer, I have the functions:
_update_tile(coords)
_use_tile_data_runtime_update(coords: Vector2i)
_tile_data_runtime_update(coords: Vector2i, tile_data: TileData)
I use the _update_tile() function to sort whether the tile needs to be updated and pulls the tiledata from it. So far, so good. I can output the data to the terminal, so I know it's working.
However, from there I don't understand how to use the other functions to copy the tiledata to the RevealedFloorLayer... All the examples I've seen online, for example here: Can’t get the _tile_data_runtime_update() function to work never seem to pass any data to the functions so I can't figure out how to do it?
Sorry if I'm being thick, but I feel like I'm this close....
Tomkun Maintain a list of tile coords that need to get visible. In _use_tile_data_runtime_update()
check if the passed coord is in that list. If yes pop it from the list and return true. Otherwise return false.
In _tile_data_runtime_update()
use the coords you get to get the data from hidden layer and set that data to received TileData
object.
xyz
Wow, that was fast!
Here's what I have so far:
extends TileMapLayer
@onready var hiddenfloorlayer: TileMapLayer = $"../HiddenFloors"
func _reveal_tile(collision_point: Vector2i):
var tile_pos = hiddenfloorlayer.local_to_map(collision_point)
var tile_id = hiddenfloorlayer.get_cell_source_id(tile_pos)
var tile_data = hiddenfloorlayer.get_cell_tile_data(tile_pos)
if tile_data:
_use_tile_data_runtime_update(tile_pos)
_tile_data_runtime_update(tile_pos,tile_data)
func _use_tile_data_runtime_update(coords: Vector2i) -> bool:
if coords:
return true
else:
return false
func _tile_data_runtime_update(coords: Vector2i, tile_data: TileData) -> void:
print(coords)
At the moment it's just printing the coords out, but is that on the right lines?
Tomkun _use_tile_data_runtime_update()
and _tile_data_runtime_update()
are callbacks that the engine calls. Like _process()
or _input()
. You just need to implement them. They're not supposed to be called by your code. You may not even need those here. Try doing just set_cell()
from _reveal_tile()
Okay, I'll try that.
How can setcell() copy one cell to another tilemaplayer though?
Never mind, I found out how. There isn't a direct copy it seems but you can extract all the info you need for setcell() with different functions and use them.
However, unfortunately it seems like I am out of luck here.
I am using BetterTerrain to place my tiles and I can't seem to reproduce them faithfully as their rotation and mirroring are randomised and I can't find a way to duplicate that.
Thank you for all your help though. I have learned a lot!
Tomkun How about this instead. Make the full version of the map completely visible. Put an additional tile map layer over that. Fill this layer with full square tiles in a background color, effectively masking what's underneath. As you progress, just delete those mask cells for the cells in the map that have been revealed.
xyz
Yes, that would work but I have a background texture.
Basically, my dungeon is supposed to look like it was sketched on paper, so there is a background paper texture.
If I could duplicate that on the top layer and make sections transparent, that could work but I'm not sure if that's possible to do.
Tomkun Hm, apparently the common canvas item children clipping doesn't work with tilemaps. You can render it into a separate viewport and use that viewport texture as an alpha mask. Alternatively you can slap your background texture over the tilemap by using a simple custom shader that draws the texture.
I think custom shaders are going to be a little advanced for me. I'm struggling as is. I will give the viewport idea a go.
Tomkun But wait. There's a simple way still using _tile_data_runtime_update()
with just the original map. Maintain a list of invisible cell coordinates. Return true from _use_tile_data_runtime_update()
if received coord is in that list. In _tile_data_runtime_update()
simply set tile_data.modulate.a
to 0.
Tomkun Example:
extends TileMapLayer
var invisibles: Array[Vector2i]
func _ready():
for i in 5:
invisibles.push_back(Vector2i(i,i))
func _use_tile_data_runtime_update(coords):
return coords in invisibles
func _tile_data_runtime_update(coords, tile_data):
tile_data.modulate.a = 0
With this you can even animate fading in of the tiles as they become visible.