概要
CollisionObject2Dの子クラスたち(Area2D, RigidBody2D, StaticBody2D, CharacterBody2D)の仕様の違い、ユースケースを公式ドキュメント、デモアプリから見て学ぶ
環境
Godot 4.4
親子関係
Node2D
└─CollisionObject2D
├─Area2D
└─PhysicsBody2D
├─StaticBody2D
├─RigidBody2D
└─CharacterBody2D
Area2D
Area2Dとは
Area2Dは、2D空間の領域を定義します。このスペースでは、他の CollisionObject2D ノードが進入、オーバラップ、および退出することを検出できます。
- 空間の定義。物理エンジンを要するような物体の定義は適さない
- 空間へのAreaやBodyの侵入を検知できる
参考:Godotドキュメント
使用例
- 弾丸やその他の発射物にArea2Dを定義することで、命中(衝突)してダメージを与える処理
- ただし反発などの物理処理は不可
- 敵の周囲にArea2Dを定義することで、プレイヤーを検知する処理
- 大規模なマップで複数のカメラにArea2Dを定義することで、プレイヤーがカメラのArea2Dに侵入したときにそのカメラをアクティブにする
StaticBody2D
StaticBody2Dとは
外部力によって移動できない2D物理ボディ。手動で移動させても、その経路上の他のボディに影響を与えない。
- 名の通り動かない物体の定義。この物体自身は物理エンジンの影響を受けない
- Areaの侵入やBodyの衝突を検知できない
参考:Godotドキュメント
使用例
- 床や壁などの動かない物体
- 物理影響を受けない特殊なノード
補足
移動時の注意点
- _process内でpositionを変更すると他のRigidBody2Dを押しのけて移動できる
- _physics_process内でmove_and_collideを呼び出すと他のRigidBody2Dを押しのけず移動できない
- StaticBody2Dでは物理エンジンをサポートしないため、この処理はNG
RigidBody2D
RigidBody2Dとは
物理シミュレーションによって動かされる物体。重力などの力を加えて動かす。
- 物理エンジンによって動く剛体
- Bodyの衝突を検知できる
参考:Godotドキュメント
使用例
- 箱や樽のような物理的に動かしたい物体
- ボールのような跳ね返る物体
補足
移動時の注意点
-
_process内でpositionを変更しても元の場所に戻る
- RigidBody2Dはあくまで物理法則に則って挙動を示すため
- _integrate_forces(物理エンジン)でpositionを上書きすることで位置を変更できる
- _physics_process内でapply_force系のメソッドで力を加えることで移動させる
- 力 → 速度 → 遷移距離 の流れで移動させる
- 等速運動や瞬間移動のような物理法則に従わない動きは推奨されなさそう
- apply_forceで渡すのは力ではなく加速度。質量の情報なし。(forceじゃなくてaccelerationじゃん...)
運動方程式(備忘)
- f[力] = m[質量] * a[加速度]
- v[速度] = t[時間] * a[加速度]
- x[遷移距離] = v[速度] * t[時間] + 1/2 * a[加速度] * t[時間]²
衝突判定
- body_entered, body_existedから物体の衝突を検知可能。ただしデフォルトでは検知できないため下記設定が必要。(標準でサポートしてないということは衝突の検知は非推奨??)
- インスペクタのRigidBody2D > Solver > Contact Monitorをオン
- インスペクタのRigidBody2D > Solver > Max Contacts Reportedで最大検知数を設定
CharacterBody2D
CharacterBody2Dとは
キャラクターに特化したスクリプトで動かす物理ボディ。
- 物理法則の影響を全く受けない
- 他の物理ボディには影響を与える
- 物体の衝突や壁/斜面の検出ができる
参考:Godotドキュメント
使用例
- ユーザが操作できるキャラクター
移動時の注意点
- _physics_process内でvelocity(速度)を設定してmove_and_slideを呼び出して移動する
- RigidBody2Dは加速度、CharacterBody2Dは速度で制御
衝突判定
- _physics_process内でget_slide_collisionやget_last_slide_collisionを呼び出して衝突物を取得できる
- is_on_floorで床、is_on_wallで壁の衝突判定を取得可能
まとめ
期待する役割が異なる4つのノードとその機能について学びました。
記載した内容以外にも様々なプロパティ、メソッドが提供されているため、使っていきながら覚えていきたいですね。