Godot 4 | ノードの当たり判定(オーバーラップ)の実装サンプル
ゲームエンジン「Godot 4」でゲームオブジェクトにしているノードの当たり判定についての覚え書きと実装方法の紹介です。
- Windows11 22H2
- Godot v4.1.1
当たり判定(オーバーラップ)の動作サンプルプロジェクト
当たり判定に関連した基本ノード
当たり判定からみた基本ノードをメモしています。
ノード | 概要 |
---|---|
Area2D | 接触判定はするが衝突による物理シュミレーションの影響を受けない2D物理ボディ ・オーバーラップ検出 ・アイテムやドアなど |
StaticBody2D | 衝突判定はあるが動かせない2D物理ボディ ・木や壁、山など |
RigidBody2D | 物理シミュレーションの影響を受ける2D物理ボディ ・動かせる岩、衝突判定のある敵、ほか |
CharacterBody2D | スクリプトによって移動されるキャラクターに特化した2D物理ボディ ・プレイヤーなど |
いずれも「CollisionShape2D」や「CollisionPolygon2D」などの衝突に対する形状を持つ子ノードが必要。
KinematicBody2DはGodot 4.1では無い
多くの解説で使われている「KinematicBody2D」はGodot 4からは無くなっているようです。
「KinematicBody2D」は「RigidBody2D」「CharacterBody2D」と扱いは同等で置き換わったという認識で良さそう。
各ノードタイプ別の階層
各タイプ別オブジェクト用に最低限必要な階層をメモしています。
必要に応じてヒットエリアとする「BaseHitBox」などを組み合わせていきます。
「プレイヤー」
Player(CharacterBody2D)
┣ Image(Sprite2D)
┗ 衝突形状(CollisionShape2D)
「木や壁、山など」
Player(StaticBody2D)
┣ Image(Sprite2D)
┗ 衝突形状(CollisionShape2D)
「アイテム、弾など」
Item(Area2D)
┣ Image(Sprite2D)
┗ 衝突形状(CollisionShape2D)
「すり抜ける敵」
Item(Area2D)
┣ Image(Sprite2D)
┗ 衝突形状(CollisionShape2D)
「ぶつかる敵」
Item(RigidBody2D)
┣ Image(Sprite2D)
┗ 衝突形状(CollisionShape2D)
プレイヤーとすり抜けるノードとの当たり判定
プレイヤーとすり抜けるノードとの当たり判定です。
以下の条件を満たしている事を前提としています。
- 移動用のインプットマップが設定されている(サンプルではトップダウン)
プレイヤーのノード
Player(CharacterBody2D)#スクリプト
┣ Image(Sprite2D)
┗ 衝突形状(CollisionShape2D)
プレイヤーノードのスクリプト
class_name Player extends CharacterBody2D
@export var speed = 500
var direction : Vector2
func _process(_delta):
pass
func _physics_process(_delta):
direction = Input.get_vector("move_left", "move_right", "move_up", "move_down")
velocity = direction * speed
move_and_slide()
# 対象と重なった時
func _on_area_2d_body_entered(_body):
modulate = Color(1, 0.5, 0.5)
# 対象から離れた時
func _on_area_2d_body_exited(_body):
modulate = Color(1, 1, 1)
「modulate」でカラーバランスを変更して、重なっているかどうかを確認しています。
すり抜けるノードのノード
Item(Area2D)#スクリプト
┣ Image(Sprite2D)
┗ 衝突形状(CollisionShape2D)
すり抜けるノードのスクリプト
extends Area2D
func _ready():
# プレイヤーノードの取得
var player = get_node("/root/Main/Player")
# プレイヤーノードに接続(重なった時用)
connect("body_entered", Callable(player, "_on_area_2d_body_entered"))
# プレイヤーノードに接続(離れた時用)
connect("body_exited", Callable(player, "_on_area_2d_body_exited"))
エディタの「ノード」タブから接続する機能がありますが、先々の処理を想定して今回はスクリプトからget_node()
とconnect()
でプレイヤーノードに接続しています。
プレイヤーノードのパスはシーンのツリー状況によって調節が必要、検索とかあるのかな。
ディスカッション
コメント一覧
まだ、コメントがありません