無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 の CanvasItem の _draw イベント関数を派生クラスで定義して、 draw_rect などを使って様々な図形や文字を描画する際に、グローバル座標の Vector2, Rect2 などの値を、そのノードのローカル座標に変換する手順とスクリプト例と結果を紹介します。
※ GodotEngine 4.3 を使用しています。.NET 版ではありません。
※スクリプトは自己責任でご使用ください。
グローバル座標で描画すると位置がずれたりサイズが異なる例
以下のスクリプトでは、CanvasItem 派生クラスで利用できる _draw イベント関数内で CanvasItem の draw_rect メンバ関数を使って自身が接触しているタイルの枠線を描画しています。
func _draw():
# デバッグ用。キャラクターが接触しているタイルの枠線を描画します。
for draw_info in SakuraCrowdTileMapLayer.debug_get_entered_tiles_info:
# キャラクターが接触しているタイルの矩形(グローバル座標)を描画します。
var global_rect2: Rect2 = draw_info.rect2
draw_rect(global_rect2, draw_info.color, false, 3, false)
return
しかし、タイルの枠線の位置はローカルではなくグローバル座標であり、_draw イベント関数を実行する操作キャラクター( GodotSan クラス, GodotEngine のアイコン)のノードは、位置がグローバル座標の原点 (0, 0) とは異なる位置にあり、大きさも 0.125 倍に縮小されています。
そのため、描画する際に大きさが 0.125 倍に縮小され、ノードの現在の位置を原点とするため枠の位置もタイルとは一致しません。
_draw の関数はノードのローカル座標やノードのスケールに依存するので、座標を指定する場合はノードのローカル座標に変換する必要があります。
また、グローバル座標でのサイズで描画する場合は、Scale.x, y の逆数を掛けるなどして見た目の大きさを 1.0 倍に戻す必要があります。
Rect2 型のローカル・グローバル座標の変換の例
以下は、 Rect2 型の矩形の座標をノードのローカル座標からグローバル座標へ、グローバル座標からノードのローカル座標へ変換する自作関数です。
左上と右下の座標を position と end から得て、それを Node2D.to_local, to_global 関数でそのノードのローカル座標や、グローバル座標へ変換しています。
## Rect2 の座標とサイズを node のローカル座標からグローバル座標に変換します。
static func rect2_to_global(rect2: Rect2, node: Node2D) -> Rect2:
var global_pos: Vector2 = node.to_global(rect2.position)
var global_end: Vector2 = node.to_global(rect2.end)
return Rect2(global_pos, global_end - global_pos)
## Rect2 の座標とサイズをグローバル座標から node のローカル座標に変換します。
static func rect2_to_local(rect2: Rect2, node: Node2D) -> Rect2:
var local_pos: Vector2 = node.to_local(rect2.position)
var local_end: Vector2 = node.to_local(rect2.end)
return Rect2(local_pos, local_end - local_pos)
グローバル座標をローカル座標に変換して _draw で描画した結果
前述の rect2_to_local 関数を使って矩形の座標をノードのローカル座標に変換する処理を追加しました。
また、枠線の太さは 3 / scale.x と scale.x の逆数を掛けることと同じ割り算をすることで、指定した 3 ピクセルの幅で表示されるようにしました。
func _draw():
# デバッグ用。キャラクターが接触しているタイルの枠線を描画します。
for draw_info in SakuraCrowdTileMapLayer.debug_get_entered_tiles_info:
# 本ノードの原点がグローバル座標の (0, 0) と異なっていたり、 scale が 1.0 ではない場合、
# debug_get_entered_tiles_info に格納されたグローバル座標の rect2 を描画すると
# ローカル座標として扱ってしまい位置がずれて大きさの異なる矩形が描画されてしまうので
# グローバル座標をローカル座標に変換します。
var local_rect2: Rect2 = SakuraCrowdUtil.rect2_to_local(draw_info.rect2, self)
draw_rect(local_rect2, draw_info.color, false, 3 / scale.x, false)
return
実行すると、操作キャラクターに接しているタイルと同じ位置とサイズに 3 ピクセルの指定通りの幅の枠線が描画されました。
まとめ
今回は、無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 の CanvasItem の _draw イベント関数を派生クラスで定義して、 draw_rect などを使って様々な図形や文字を描画する際に、グローバル座標の Vector2, Rect2 などの値を、そのノードのローカル座標に変換する手順とスクリプト例と結果を紹介しました。
参照サイト Thank You!
- Godot Engine – Free and open source 2D and 3D game engine
- 2Dカスタム描画 — Godot Engine (4.x)の日本語のドキュメント
- CanvasItem — Godot Engine (4.x)の日本語のドキュメント #method-draw
- Node2D — Godot Engine (4.x)の日本語のドキュメント
記事一覧 → Compota-Soft-Press
コメント