TileMapLayer)特定のタイルの色を、任意のタイミングで変える方法
自分はかなり詰まってしまったため、記載しておきます。
以下のように、キャラクタ(棒人間)が家に入ると、家の壁や屋根が透けて、家の中が見える、というようにしたい、とします。
↓
■スクリプト
以下スクリプトを、半透明にしたいレイヤーにアタッチします。
(_on_area_in_house_1_area_entered、は、キャラクタが戸口に侵入した時のトリガーで実行されます)
extends TileMapLayer var modulated_cells:Dictionary func _ready() -> void: pass func _use_tile_data_runtime_update(coords: Vector2i) -> bool: return modulated_cells.has(coords) func _tile_data_runtime_update(coords: Vector2i, tile_data: TileData) -> void: tile_data.modulate = modulated_cells.get(coords, Color(1, 1, 1, 1)) func _on_area_in_house_1_area_entered(area: Area2D) -> void: if ( (area.name == "DamageBox") and (area.get_parent().editor_description == "MPC")): for x in range (463, 478): for y in range (455, 470): modulated_cells[Vector2i(x, y)] = Color(1, 1, 1, 0.1) notify_runtime_tile_data_update()
■実行タイミングがわかりづらい
_use_tile_data_runtime_updateと、 _tile_data_runtime_updateが、どのタイミングで実行されるのか、わかりづらいです。これはプログラム起動時と、notify_runtime_tile_data_update()、を行ったタイミングで実行されます。
以下は、プログラム起動時に実行される際の物です。
https://www.reddit.com/r/godot/comments/186fktw/tilemaps_modulating_single_tiles/
■何をしているのか?
・_use_tile_data_runtime_update
このルーチン内のcoords、をprint()で出力するとわかりやすいのですが、このスクリプトをアタッチしたlayerの、シーン内の全座標がcoordsです。
プログラムを起動した時点で処理されるようです。
modulated_cellsに、その座標があるかどうかチェック、あれば1を返し、なければnullを返します。
つまり、対象レイヤーの、どの座標を更新するのか?を検知する関数です。
・_tile_data_runtime_update
これも何をしているかわかりづらいです。tile_data、とは、シーン内のタイルではなく、シーンに配置する元となった、タイルセット(tileset)の方のタイルのことです。直接この関数をソース内で記載、呼び出し、更新する、ということをしても、同じことができます。その場合、coordsの座標も、tilesetの方の物になります。
しかし、それだとなぜか重い処理となってしまい、キャラクタが家に入るたびに、動作が0.5秒程度固まってしまいます。
コードの内容は理解できませんが、とりあえずこの書き方をしています。Color()は、初期値・規定値なので、この値で良いと思います。
・_on_area_in_house_1_area_entered
キャラが入口に入った時、トリガーで動きます。
以下ではready時にやっている内容に、notify_runtime_tile_data_update()、を追加して実行しています。
https://www.reddit.com/r/godot/comments/186fktw/tilemaps_modulating_single_tiles/
x(463,478)~y(455,470)は、シーン内の家のタイルのある座標範囲です。この範囲分について、modulated_cellsの値を、色を半透明(0.1の箇所。0:透明~1:不透明)にする値にセットします。
その後、notify_runtime_tile_data_update()、を実行すると、_use_tile_data_runtime_updateと、_tile_data_runtime_updateが実行され、家が半透明になります。
_tile_data_runtime_updateをソース内に記載して直接呼び出した時とことなり、動作はスムーズで、固まりません。
■難点
複数のレイヤーを一度に操作したい時もあると思います。
tilemapではそのような事もできたかもしれません(各関数の引数にlayerの指定項目がある)。しかし、現在推奨されているtilemaplayerは、layerごとにわかれています。
結果、各レイヤーにスクリプトをアタッチする、等、ちょっと面倒ですね・・・
コメント
コメントを投稿