0 votes

I'm trying to set up a color-coding system on a tilemap. Each tile may require a different shape to color-code, and each tile may require a different color. There are around 10 distinct shapes and 15 distinct colors. My approach was to manually create sprites for each shape, and then use the modulate property to set the color. However, it seems as if I can't modulate an individual tile on a tilemap.

The most recent answers I could find stated this was not possible. However, the answers seemed to be for engine version 2.1. Is it possible to modulate a tile now, or do I have to use a different method? If so, what is a good alternative method?

in Engine by (124 points)

1 Answer

+1 vote
Best answer

SOLVED: I wrote an alternative tilemap

extends Node2D

export var tile_size_x = 32
export var tile_size_y = 32
export var tile_offset_x = 0
export var tile_offset_y = 0

export var paths_to_tiles = [""]
var tile_textures = []

var tiles = {}

func _ready():
    for tile in paths_to_tiles:
        tile_textures.append(load(tile))

func set_cell(x, y, index):
    if(index == -1):
        if(tiles.has(Vector2(x, y))):
            tiles[Vector2(x, y)].queue_free()
    elif(index >= 0):
        var sprite = Sprite.new()
        sprite.visible = false
        tiles[Vector2(x, y)] = sprite
        sprite.texture = tile_textures[index]
        sprite.position.x = (x * tile_size_x) + tile_offset_x
        sprite.position.y = (y * tile_size_y) + tile_offset_y
        sprite.visible = true
        add_child(sprite)
    else:
        get_tree().quit()

func set_cellm(x, y, index, col):
    if(index == -1):
        if(tiles.has(Vector2(x, y))):
            tiles[Vector2(x, y)].queue_free()
    elif(index >= 0):
        var sprite = Sprite.new()
        sprite.visible = false
        tiles[Vector2(x, y)] = sprite
        sprite.texture = tile_textures[index]
        sprite.position.x = (x * tile_size_x) + (tile_size_x / 2) + tile_offset_x
        sprite.position.y = (y * tile_size_y) + (tile_size_y / 2) + tile_offset_y
        sprite.modulate = col
        sprite.visible = true
        add_child(sprite)
    else:
        get_tree().quit()

func set_cell_modulate(x, y, col):
    if(tiles.has(Vector2(x, y))):
        tiles[Vector2(x, y)].modulate = col

Due to being based off of instanced sprites, it most likely has worse performance than the built-in tilemap. It also obviously has far less features. However, it works for what I need to do.

It exports 5 variables. tile_size_x and tile_size_y are pretty self-explanatory. tile_offset_x and tile_offset_y will move each cell a certain distance. paths_to_tiles is a list of strings, and functions as a crude TileSet. Unfortunately, the editor interface for this variable is very clunky, so users must manually select string to be the type of every single entry, and users must manually enter every path.

set_cell does the same thing as it does for the built-in TileMap. set_cellm is like set_cell, but it also sets the modulate of the cell. set_cell_modulate sets the modulate of a cell.

by (124 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.

Categories