Godot4 ポリゴンの見た目と当たり判定領域を移動・回転・拡大後も一致させる

無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 で、 Polygon2D ノードのポリゴン情報を CollisionPolygon2D ノードにコピーして、見た目と当たり判定領域を一致させた前回のスクリプトでは、ノードの移動・回転・拡大に対応していなかったので、対応前の問題の確認改善したスクリプトによる結果を紹介します。
#以前参考にさせていただいたスクリプトは、そこまで対応する必要のない状況で使われていました。

Godot4 ポリゴンの見た目と当たり判定領域の位置のずれにより衝突判定が起きません.

※ GodotEngine 4.3 を使用しています。.NET 版ではありません。
※紹介するスクリプトは自己責任でお使いください。

前回の記事

前回は、Polygon2D ノードを使ってデザインした地形の上を、 CharacterBody2D ノードを使ったキャラクターが移動する実装の手順を紹介しました。

Godot4 Polygon2Dの地形で CharacterBody2D のキャラを動かした例

新しい地形を複製から作成

前回は、Polygon2D のポリゴン表示に合わせた CollisionPolygon2D による当たり判定によって、キャラクターが乗ることができる地形を作りました

今回は、その地形のノード群を複製後、編集して、新しい地形を作成します。
シーンドックで、複製したいノード(複数ある場合はその最上位のノード)を右クリックして表示されるメニュー「複製」を選択します。

Godot4 複製して新しいポリゴン地形を作成1

複製した Terrain ノードの下位にあるポリゴンの見た目を設定する Polygon2D を編集します。
※当たり判定領域の CollisionPolygon2D は前回のスクリプトにより開始時に自動的にポリゴン情報をコピーして設定されます。

不要な頂点は Delete キーで削除でき、頂点マウスドラッグして移動できます。

Godot4 複製して新しいポリゴン地形を作成2

複製することにより、簡単に地形を追加できました。

Godot4 複製して新しいポリゴン地形を作成3

Polygon2D ノードを移動すると当たり判定が一致しない

しかし、Polygon2D ノードのポリゴンの編集の際に、ポリゴンの頂点の移動ではなく、ノード全体を思わず移動したせいで、キャラクターが地形をすり抜けてしまう問題が発生しました。

Godot4 Polygon2Dの頂点の移動とノード全体の移動による原点の違い2

この原因は Polygon2D ノードの見た目のポリゴンと、 CollisionPolygon2D ノードの当たり判定のポリゴンの形は同じだけど、位置が異なることでした。

Godot4 ポリゴンの見た目と当たり判定領域の位置のずれにより衝突判定が起きません.

ポリゴンの頂点の移動では、ノード自体の位置変わりませんが、思わず移動してしまうとノードの位置がずれてしまいます

Godot4 Polygon2Dの頂点の移動とノード全体の移動による原点の違い

ノードの移動はよく行われるものなので、これに対応するために、ポリゴン情報をコピーするスクリプトに Polygon2D ノードの位置を CollisionPolygon2D にコピーする処理追加します。
※スクリプト全体はあとで紹介します。

	node_collision_pollygon2d.position = node_polygon2d.position

これにより、見た目の Polygon2D と、当たり判定領域の CollisionPolygon2D の位置が同じになり、地形をすりぬけないようになりました。

Godot4 Polygon2Dの頂点の移動とノード全体の移動による原点の違い3

回転・拡大にも対応

ツールバーには移動モードの他に、回転、拡大もあり、それらを変更すると、やはり見た目と当たり判定領域が一致しなくなりました。

Godot4 Polygon2DとCollisionPolygon2dの角度と拡大率の違いによる当たり判定の差3

移動よりは使わないかもしれませんが、地形のノードを回転・拡大する場合のことも考えて、Polygon2D ノードの回転・拡大の値CollisionPolygon2Dコピーするようにしました。

	node_collision_pollygon2d.scale = node_polygon2d.scale
	node_collision_pollygon2d.rotation = node_polygon2d.rotation
Godot4 ポリゴンの見た目と当たり判定領域の位置の他に、回転や拡大もコピーします.

以下は、Polygon2D ノードの移動・回転・拡大対応したスクリプトです。

以下のスクリプトは Polygon2D と CollisionPolygon2D の上位ノードの StaticBody2D (リネーム後 Terrain ) ノードに割り当てます。

extends StaticBody2D
class_name Terrain

# 下位にある Polygon2D ノード
var node_polygon2d: Polygon2D
# 下位にある CollsionPollygon2D ノード
var node_collision_pollygon2d: CollisionPolygon2D

# Called when the node enters the scene tree for the first time.
func _ready():
	# 下位にあるデフォルトの名前の2つのノードを取得します。
	node_polygon2d = get_node("Polygon2D")
	node_collision_pollygon2d = get_node("CollisionPolygon2D")
	
	# Polygon2D の見た目のポリゴンのデータを当たり判定を行う CollisionPolygon2D にコピーします。
	update_colission_polygon_2d()

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	pass

# Polygon2D のポリゴン情報などを CollisionPolygon2D にコピーします。
func update_colission_polygon_2d() -> void:
	# 形を設定した Polygon2D ノードの polygon の情報を 当たり判定の領域として設定します。
	node_collision_pollygon2d.polygon = node_polygon2d.polygon
	node_collision_pollygon2d.position = node_polygon2d.position
	node_collision_pollygon2d.scale = node_polygon2d.scale
	node_collision_pollygon2d.rotation = node_polygon2d.rotation

テスト

F6 キーで現在のシーンを再生してテストすると、Polygon2D ノードを移動・回転・拡大したポリゴンの地形をキャラクターがのって移動できました

Godot4 Polygon2DとCollisionPolygon2dの角度と拡大率の違いによる当たり判定の差4

変化するポリゴン用のフラグの追加

以下は AnimatableBody2D ノードを使った方が良いかもしれないので、推奨しません

常に回転する地形などはまだ試していませんが、それに対応するために、物理演算のフレーム処理で毎回ポリゴンの情報をコピーするフラグと処理を追加してみました。
動作を確認していませんので、参考程度にみてください。

以下のスクリプトは Polygon2D と CollisionPolygon2D の上位ノードの StaticBody2D (リネーム後 Terrain ) ノードに割り当てます。

extends StaticBody2D
class_name Terrain

# 下位にある Polygon2D ノード
var node_polygon2d: Polygon2D
# 下位にある CollsionPollygon2D ノード
var node_collision_pollygon2d: CollisionPolygon2D

# CollisionPolygon2D の当たり判定領域を毎フレーム Polygon2D からコピーします。変化する地形を想定しています。
var IsAlwaysUpdateCollisionPolygon2D: bool = false

# Called when the node enters the scene tree for the first time.
func _ready():
	# 下位にあるデフォルトの名前の2つのノードを取得します。
	node_polygon2d = get_node("Polygon2D")
	node_collision_pollygon2d = get_node("CollisionPolygon2D")
	
	# Polygon2D の見た目のポリゴンのデータを当たり判定を行う CollisionPolygon2D にコピーします。
	update_colission_polygon_2d()

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	pass
	
# The engine calls this method before every physics step
func _physics_process(delta):
	if IsAlwaysUpdateCollisionPolygon2D:
		update_colission_polygon_2d()

func update_colission_polygon_2d() -> void:
	# 形を設定した Polygon2D ノードの polygon の情報を 当たり判定の領域として設定します。
	node_collision_pollygon2d.polygon = node_polygon2d.polygon
	node_collision_pollygon2d.position = node_polygon2d.position
	node_collision_pollygon2d.scale = node_polygon2d.scale
	node_collision_pollygon2d.rotation = node_polygon2d.rotation

_physics_process イベント関数は、物理演算のフレーム処理で呼び出される関数です。

物理処理は、同様の仮想関数 _physics_process() で動作します。これはゲーム世界に衝突判定を持つキャラクターの制御など、各物理ステップの前に実行する必要がある処理に使用します。前述のとおり、 _physics_process() は物理的な相互作用を安定させるために、可能な限り固定時間間隔(デフォルトでは毎秒60回)で呼び出されます。この間隔は、プロジェクト設定の Physics -> Common-> Physics Fps で変更できます。

アイドル処理と物理処理 — Godot Engine (4.x)の日本語のドキュメント

まとめ

今回は、無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 で、 Polygon2D ノードのポリゴン情報を CollisionPolygon2D ノードにコピーして、見た目と当たり判定領域を一致させた前回のスクリプトでは、ノードの移動・回転・拡大に対応していなかったので、対応前の問題の確認改善したスクリプトによる結果を紹介しました。

参照サイト 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をコピーしました