Godot4 当たり判定領域 Shape2D を取得するスクリプト例と実行結果

無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 で、CharacterBody2D などの CollisionObject2D 派生クラスの当たり判定領域の設定で使用される Shape2D 派生リソースを取得するスクリプトの例と使用結果を紹介します。
Shape2D 派生リソースの種類格納場所、それを得ることによるメリットについても紹介します。

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

Shape2D を取得するメリット

Shape2D の collide メンバ関数を使うと、その Shape2D の持つ当たり判定領域と、指定したもう一つの Shape2D の当たり判定領域が重なったかどうかを判定できます。

矩形(四角形)の範囲だけならば実装できそうですが、カプセル型やポリゴンなども含めると、 Shape2D の collide の機能はとても便利です。
※シグナルを使って領域と重なった際に通知を受けて処理する方が一般的かもしれません。

bool collide(local_xform: Transform2D, with_shape: Shape2D, shape_xform: Transform2D

Returns true if this shape is colliding with another.

This method needs the transformation matrix for this shape (local_xform), the shape to check collisions with (with_shape), and the transformation matrix of that shape (shape_xform).

このシェイプが別のシェイプと衝突している場合は true を返します。

このメソッドには、この形状の変換行列 (local_xform)、衝突をチェックする形状 (with_shape)、およびその形状の変換行列 (shape_xform) が必要です。
Shape2D — Godot Engine (4.x)の日本語のドキュメント と Google 翻訳

Shape2D 派生リソースには、四角形や円形の他にも様々な図形に対応したリソースがあります。

Godot4 Shape2D 派生クラス ( doxygen で生成したドキュメントより)

Shape2D 派生リソースの取得に必要なオーナーIDと要素番号

CharacterBody2D などの CollisionObject2D 派生クラスは、当たり判定領域を持つ CollisionShape2D, CollisionPolygon2D下位ノードに持ちます。

Godot4 Shape2D 派生リソースを持つ CollsionShape2Dノードを2つ持った CharacterBody2D ノードのシーンドックの例

CollisionShape2D 下位ノードは、当たり判定の領域を定義するために Shape2D 派生のリソースShape プロパティ設定します。

Godot4 CharacterBody2D ノードの下位の Shape2D 派生ノード1個目のリソース

このことから、CharacterBody2D などの CollisionObject 派生ノードが当たり判定領域を定義した Shape2D 派生リソースを得るには、そのリソースを持っている CollisionShape2D ノードも指定する必要があります。

このとき Shape2D 派生リソースを持つ CollsionShape2D ノードはリソースのオーナーとなっていて、そのオーナー ID と、そのオーナーが持っているリソースの要素番号を指定することで Shape2D 派生リソースを取得できます。

Abstract base class for 2D physics objects. CollisionObject2D can hold any number of Shape2Ds for collision. Each shape must be assigned to a shape owner. Shape owners are not nodes and do not appear in the editor, but are accessible through code using the shape_owner_* methods.

2D 物理オブジェクトの抽象基本クラス。 CollisionObject2D は、衝突のために任意の数の Shape2D を保持できます。各形状は形状所有者に割り当てる必要があります。シェイプ オーナーはノードではないため、エディターには表示されませんが、shape_owner_* メソッドを使用してコードからアクセスできます。
CollisionObject2D — Godot Engine (4.x)の日本語のドキュメント と Google 翻訳

スクリプト

以下のスクリプトでは、引数で渡した CollisionObject 派生ノードが持つ Shape2D 派生リソースを全て取得します。
※詳細はスクリプト内のコメントを参照してください。
※スクリプトは自己責任でご使用ください。

# CollisionObject の下位の Shape2D 派生リソースを全て取得します。
func get_shape2d_all(collision_object_2d: CollisionObject2D) -> Array[Shape2D]:
	# 見つかった Shape2D 派生リソースを格納する配列
	var shape2d_array: Array[Shape2D]
	
	# 全てのオーナー ID を配列で取得します。
	var owner_id_array: PackedInt32Array = collision_object_2d.get_shape_owners()
	# オーナーごとに持っている Shape2D 派生リソースを取得します。
	for owner_id in owner_id_array:
		# そのオーナーが持っている Shape2D 派生リソースの個数を取得します。
		var shape_count = collision_object_2d.shape_owner_get_shape_count(owner_id)
		# そのオーナーが持っている Shape2D 派生リソースを1つずつ取得します。
		for shape_index in range(shape_count):
			var shape: Shape2D = collision_object_2d.shape_owner_get_shape(owner_id, shape_index)
			# 取得した Shape2D 派生リソースが有効ならば、戻り値の配列に追加します。
			if shape:
				shape2d_array.append(shape)
	return shape2d_array

テスト

GodotSan (CharacterBody2D 派生 ) ノードは、四角形の当たり判定だけを持たせているのですが、テストのためにもう一つ円形の当たり判定も追加しました。

GodotSan の下位に CollsionShape2D ノードを二つ配置して、それぞれの Shape プロパティに Shape2D 派生の RectangleShape2D (四角形 サイズ 104 × 98)と CircleShape2D (円形、半径58)のリソース割り当てました。

CollisionShape2D ノードは、 GodotSan (CharacterBody2D 派生) ノードを右クリックすると表示されるメニュー「子ノードを追加」CollisionShape2D を選択して追加できます。

そして、GodotSan ノードを持つシーンのスクリプトで、以下のように最初に一度呼び出される _ready イベント関数内で、以下のようなテストコードを追記します。
※詳細はスクリプト内のコメントを参照してください。

10 行目で呼び出している print_all_property_name_and_value 関数で、すべてのプロパティをテキストで出力します。この関数については後述の関連記事を参照してください。

func _ready():
	# シーンに配置した GodotSan ノードの下位の Shape2D 派生リソースを全て配列で取得します。
	var shape2d_array = get_shape2d_all($GodotSan)
	print(str(len(shape2d_array)), "個の Shape2D 派生リソースを取得しました。\n")
	# 取得した Shape2D 派生リソースの1つずつの情報(全てのプロパティの名前と値)を出力します。
	var count:int = 0
	for shape2d in shape2d_array:
		count += 1
		print("Shape2D #", str(count))
		print_all_property_name_and_value(shape2d)
		print("")

下パネルの出力に以下のように結果が表示されました。
先ほど GodotSan に追加した四角形円形Shape2D 派生リソースプロパティが出力されています。
四角形の size や、円形の radius (半径) の値も一致しています。

2個の Shape2D 派生リソースを取得しました。

Shape2D #1
RefCounted: null
Resource: null
Resource: null
resource_local_to_scene: false
resource_path: res://godot_san.tscn::RectangleShape2D_i7qjd
resource_name: 
resource_scene_unique_id: RectangleShape2D_i7qjd
Shape2D: null
custom_solver_bias: 0
RectangleShape2D: null
size: (104, 98)
script: <null>

Shape2D #2
RefCounted: null
Resource: null
Resource: null
resource_local_to_scene: false
resource_path: res://godot_san.tscn::CircleShape2D_xu0xm
resource_name: 
resource_scene_unique_id: CircleShape2D_xu0xm
Shape2D: null
custom_solver_bias: 0
CircleShape2D: null
radius: 10
script: <null>

関連記事

今回のスクリプトでも使用した、ノードの持つすべての基本の型プロパティ名前を文字列で出力する print_all_property_name_and_value 関数については以下の記事を参照してください。

まとめ

今回は、無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 で、CharacterBody2D などの CollisionObject2D 派生クラスの当たり判定領域の設定で使用される Shape2D 派生リソースを取得するスクリプトの例と使用結果を紹介しました。
Shape2D 派生リソースの種類格納場所、それを得ることによるメリットについても紹介しました。

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