Godot4 _draw イベント関数で描画する際にローカル座標に変換する例

無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4CanvasItem_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 倍に縮小されています。

Godot4 _draw 関数の描画はそのノードのローカル座標で描画内容を指定します.拡大率も影響をうけます.

そのため、描画する際に大きさが 0.125 倍に縮小され、ノードの現在の位置を原点とするため枠の位置もタイルとは一致しません

Godot4 _draw 関数の描画の位置をグローバル座標で指定すると、ローカル座標として扱われてずれてしまいます..

_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 ピクセルの指定通りの幅枠線描画されました。

Godot4 _draw 関数の描画の位置をグローバル座標からローカル座標に変換して大きさを scale の逆数をかけて1倍に戻すとグローバル座標の指示と同じように描画されました...

まとめ

今回は、無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4CanvasItem_draw イベント関数を派生クラスで定義して、 draw_rect などを使って様々な図形や文字を描画する際に、グローバル座標の Vector2, Rect2 などの値を、そのノードのローカル座標に変換する手順とスクリプト例と結果を紹介しました。

参照サイト Thank You!

記事一覧 → Compota-Soft-Press

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました