【Godot】スクリプトでレイキャストする方法

今回はスクリプトでレイキャスト(ある地点から特定の方向にレイ(光線)を発生させて衝突判定を行う)する方法を紹介します。

なお、RayCast2D ノードを使用した衝突判定の方法は以下のページにまとめています。

【Godot】RayCast2Dの基本的な使い方

スクリプトでレイキャストを行う方法

Godot Engineでは、Physics2DServer という2D物理エンジンにアクセスするインターフェースが用意されていて、それを使用することでスクリプトで動的なレイキャストを行うことができます。

具体的には、intersect_ray() という関数を呼び出します

intersect_ray() の説明

intersect_ray() には以下の引数を指定します

  • Vector2 from: レイの開始座標
  • Vector2 to: レイの終端座標
  • Array exclude = []: 衝突から除外するオブジェクト
  • int collision_layer = 0x7fffffff: 衝突対象となるコリジョンレイヤー
  • bool collide_with_bodies = true: Body2D系ノードを衝突判定対象とするかどうか
  • bool collide_with_areas = false: Area2Dノードを衝突対象とするかどうか

注意点としては、最後の引数「collide_with_areas」です。デフォルトでは false(無効) となっているので、Area2Dノードを衝突対象としたい場合には、この値を “true” にする必要があります。

実装例

intersect_ray() を使用した衝突判定の実装方法を紹介します。

当たり判定を行うシーンの作成

まずは当たり判定を行うシーンを作成します。

Area2D (Targetにリネーム)
 +-- ColorRect
 +-- CollsionShape2D (RectangleShape2D)

ノードの構成はこのようにしました。

レイキャスト判定用のシーンを作成する

次にレイキャストを行うシーンを作成します。Node2Dシーンを作成して「Main」にリネームしておきます。

そして “Target.tscn” シーンをいくつか配置しておきます。

そうしたら Mainシーンにスクリプトをアタッチします。

extends Node2D

# レイの開始座標
var start_position = Vector2(512, 300)
# レイの終端座標
var mouse_position = Vector2()

# 衝突しているかどうか
var is_hit = false

func _process(delta: float) -> void:
	# マウス座標をレイの終端とする
	mouse_position = get_viewport().get_mouse_position()
	update()
	
func _physics_process(delta: float) -> void:
	# レイの判定を行う
	var space_state = get_world_2d().direct_space_state
	var collision_mask = 0x7FFFFFFF # すべてのコリジョンとアタリ判定する
	var collide_with_bodies = true # body系と判定する
	var collide_wthi_areas = true # area2dと判定する
	
	var result = space_state.intersect_ray(start_position, mouse_position, [], collision_mask, collide_with_bodies, collide_wthi_areas)	
	if result:
		# 衝突した
		print("Hit at point: ", result.position)
	
	# 衝突フラグを格納する
	is_hit = result.empty() == false

func _draw() -> void:
	var color = Color.silver
	if is_hit:
		# 衝突していたら赤い線にする
		color = Color.red
	draw_line(start_position, mouse_position, color, 1)

では実行して動作を確認します。

完成プロジェクト

今回作成したプロジェクトファイルを添付しておきます。

参考資料