mcpField
P
physics-system

physics-system

github.com/jame581開発889169 回インストール4 日前に更新
リポジトリ

physics-system について

Godot 4.3+ でゲーム物理を実装する開発者向けのスキルです。衝突ボディ、形状、クエリ、補間に加え、Jolt Physics とラグドールの設定を扱います。

主な機能

  1. 014 種類の物理オブジェクトの使い分け
  2. 02衝突形状、レイヤー、マスクの設定
  3. 03レイと空間ステートによるクエリ
  4. 043D 物理での Jolt Physics の利用
  5. 05補間とラグドールの設定

活用シーン

  1. 01プレイヤー、敵、オブジェクトの衝突構築
  2. 02トリガー、重力、オーディオ領域の作成
  3. 03レイ判定と 3D マウスピッキング
  4. 04キャラクターへのラグドール物理の追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jame581/godotprompter --skill physics-system

インストール後、Claude Code で/physics-systemを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
area-recipes.md
collision-layers.md
collision-shapes.md
interpolation-camera.md
interpolation-tuning.md
jolt-differences.md
ragdoll-recipes.md
raycasting-recipes.md
rigidbody-recipes.md
softbody-recipes.md
staticbody-recipes.md
troubleshooting.md

詳細

Godot 4.3+ の物理システム

すべての例は、非推奨 API を使用せずに Godot 4.3+ を対象としています。まず GDScript を示し、次に C# を示します。

関連スキル: CharacterBody2D/3D の移動パターンについては player-controller、ヒットボックス/ハートボックスの構成については component-system、物理パフォーマンスの調整については godot-optimization、カメラの追従と補間については camera-system、ネットワーク物理については multiplayer-sync、タイルの衝突設定と 2D キャンバスレイヤーについては 2d-essentials を参照してください。


1. 物理ボディの種類

4 種類の衝突オブジェクトがあります(後半の 3 種類は PhysicsBody2D/3D を継承します)。

種類移動方法用途
Area2D/3Dコード重なりの検出、重力ゾーン、オーディオゾーン
StaticBody2D/3D移動しない(または constant_linear_velocity)壁、床、コンベアベルト
RigidBody2D/3D物理エンジン木箱、投射物、破片、ラグドール
CharacterBody2D/3Dコードプレイヤー、敵、NPC(player-controller を参照)

すべての衝突オブジェクトには、少なくとも 1 つの CollisionShape2D/3D(または CollisionPolygon2D/3D)子ノードが必要です。Jolt Physics は 4.4 以降に組み込み(実験的機能、オプトイン)となり、4.6 以降で作成されたプロジェクトではデフォルトの 3D エンジンです — セクション 8 を参照してください。既存のプロジェクトでは、切り替えるまで GodotPhysics が使われます。2D では常に GodotPhysics が使われます。

重要なルール: scale を使って衝突シェイプや物理ボディのスケールを変更してはいけません。シェイプ自体のサイズパラメーター(半径、半寸法、高さ)を使ってください。スケールの変更は衝突精度を損ないます。


2. RigidBody2D/3D

力とインパルス
メソッド効果用途
apply_force(force, position)指定した点に継続的な加速を加えるスラスター、風、磁石
apply_central_force(force)中心に継続的な加速を加える重力、一定の押す力
apply_impulse(impulse, position)指定した点の速度を瞬時に変化させる弾の命中、爆発
apply_central_impulse(impulse)中心の速度を瞬時に変化させるジャンプ、ノックバック
apply_torque(torque)継続的な角加速を加える操舵、回転
apply_torque_impulse(impulse)角速度を瞬時に変化させる衝撃による回転

apply_force + apply_central_impulse + apply_torque を使った推進と回転の例(GDScript + C#)については、references/rigidbody-recipes.md を参照してください。

_integrate_forces() — 安全な物理変更

RigidBody のトランスフォーム、速度、角速度を読み取ったり変更したりするには、_physics_process() の代わりに _integrate_forces(state) を使用してください。_physics_process() 内で position や linear_velocity を直接設定すると、物理エンジンと競合します。

警告: ボディがスリープ中は _integrate_forces() は呼び出されません。コールバックを継続的に実行する必要がある場合は can_sleep = false を設定してください。それ以外の場合は、パフォーマンス向上のためにボディをスリープさせてください。

state.apply_force / state.apply_torque を使った推進とトルクの例(GDScript + C#)については、references/rigidbody-recipes.md を参照してください。

接触モニタリング、PhysicsMaterial、Freeze、look_at
  • 接触シグナルを使うには、contact_monitor = true と max_contacts_reported > 0 が必要です。設定すると body_entered/body_exited が発火します。
  • PhysicsMaterial リソースは、friction(氷の 0 からゴムの 1)と bounce(0 から 1)を制御します。
  • フリーズモード: FREEZE_MODE_STATIC(StaticBody のように動作)または FREEZE_MODE_KINEMATIC(コードで移動し、他の物体を押す)。
  • RigidBody3D の向き: RigidBody に look_at() を使用してはいけません。代わりに _integrate_forces を使い、外積による操舵項から state.angular_velocity を設定してください。

take_damage を使った接触ハンドラー、PhysicsMaterial のプロパティ一覧、フリーズの切り替え、角速度による RigidBody3D のホーミングを含む、GDScript + C# の完全なレシピについては、references/rigidbody-recipes.md を参照してください。


3. StaticBody2D/3D

StaticBodyは物理エンジンによって移動しませんが、constant_linear_velocityを介してほかのボディを押すことができます(例:コンベヤーベルト)。コードで移動させながらCharacterBodyも押すプラットフォームには、**AnimatableBody2D/3D**を使用してください。コードで移動させたStaticBodyでは、CharacterBodyを確実に押せません。

コンベヤーベルトと移動プラットフォームのレシピ(GDScript + C#、Tween駆動のAnimatableBody2Dループ)については、references/staticbody-recipes.mdを参照してください。


4. Area2D/3D

Areaは範囲内の重なりを検出し、物理プロパティを上書きします。衝突応答は発生しないため、ボディはそのまま通過します。Areaがボディを報告するのは、monitoringがオンで、かつそのcollision_maskにボディのcollision_layerが含まれている場合だけです。body_enteredが発火しないよくある原因はこの不一致です。デフォルト(レイヤー1、マスク1)が一致している場合でも、両方の設定を明示してください。ボディ同士の重なりにはbody_entered / body_exitedを接続し、Area同士(ヒットボックス対ダメージ判定ボックス。component-systemを参照)にはarea_entered / area_exitedを使用します。Areaでは、重力(無重力ゾーン、点重力/ブラックホール)、linear_damp / angular_damp(水中、スローモーション)を上書きしたり、音声を特定のAudioBusに転送したりすることもできます。複数のAreaが重なる場合は、priorityで適用順序を決めます。space_overrideモード(COMBINE、REPLACE、COMBINE_REPLACE、REPLACE_COMBINE)を選択してください。

重なり検出の標準的な例(GDScript + C#)、space-overrideモードの参照表、無重力および点重力のレシピについては、references/area-recipes.mdを参照してください。

⚠️ Godot 4.7での変更点: Jolt Physicsでは、Area3Dがシグナルとメソッドを通じてSoftBody3Dとの重なりを報告するようになりました。不要なArea3D ↔ SoftBody3Dの相互作用が無視されるよう、衝突レイヤー/マスクを設定してください。4.7移行ガイドを参照してください。


5. Collision Shapes

形状(2D / 3D)用途
Rectangle / Box木箱、プラットフォーム、部屋
Circle / Sphereボール、飛び道具、単純なキャラクター、トリガーゾーン
Capsule(2Dおよび3D)キャラクター。丸みがあり、端を滑らかに乗り越えます
Segment2D / —薄い壁、レーザービーム
SeparationRay2D / 3Dキャラクターの接地スナップ
WorldBoundary2D / 3D無限の床/壁/天井
— / Cylinder3D柱、樽(GodotPhysicsでは既知のバグがあるため、Joltを推奨)

動的ボディにはプリミティブを推奨します。ConvexPolygonShapeは高速ですが、穴や内側に湾曲した形状を表現できません。ConcavePolygonShapeはレベルの形状を正確に表現できますが、StaticBody専用で、最も低速です。CollisionShapeノードを移動、回転、拡大・縮小しないでください。形状を変形しないことで、ブロードフェーズの最適化が有効になります。Godot 4.7以降では、横向きの一方向プラットフォーム用にone_way_collision_directionが追加されています。

凸/凹形状のコスト表、形状生成メニュー、パフォーマンスに関するすべてのルール、および4.7以降の一方向の方向指定API(GDScript + C#):references/collision-shapes.md


6. Collision Layers and Masks

Godotでは、次元ごと(2Dと3Dは別々)に32個の物理レイヤーを使用できます。

  • collision_layer — このオブジェクトが存在するレイヤー(ほかのオブジェクトはここをスキャンします)
  • collision_mask — このオブジェクトがスキャンするレイヤー(検出対象)

考え方: Layerは「自分がいる場所」、Maskは「自分がスキャンする場所」です。オブジェクトAのマスクにオブジェクトBのレイヤーが含まれる場合、またはその逆の場合に衝突が発生します。

レイヤー名はProject Settings → Layer Names → 2D Physics(または3D Physics)で設定します。コードからはset_collision_layer_value(N, true) / set_collision_mask_value(N, true)で設定します(インデックスは1始まりです)。

レイヤーの命名規則、ビットマスクの略記法、Inspectorのエクスポートフラグ、GDScript + C#の例については、references/collision-layers.mdを参照してください。


7. Raycasting and Physics Queries

RayCast2D/3D ノード(毎フレームのシンプルなレイ)

RayCast2D/RayCast3D を子ノードとして追加すると、物理フレームごとに自動でレイをキャストします。is_colliding() と get_collider()/get_collision_point()/get_collision_normal() で結果を取得します。

GDScript と C# の RayCast ノードの例については、references/raycasting-recipes.md を参照してください。

コードベースのレイキャスティング(PhysicsDirectSpaceState)

必要なときにクエリを実行するには、get_world_2d().direct_space_state(または get_world_3d())から空間の状態にアクセスし、PhysicsRayQueryParameters2D/3D.create(from, to) で作成した query を使って intersect_ray(query) を呼び出します。自身を除外するには query.exclude = [get_rid()] を設定し、レイヤーを絞り込むには query.collision_mask を設定します。クエリは _physics_process() 内で実行してください — 物理ステップの実行中は空間がロックされ、物理演算が別スレッドで実行されている場合、空間にアクセスできるのはその中だけです。

自身の除外とマスクによる絞り込みを含む、コードベースのレイキャストの GDScript と C# の完全な例、および 3D のマウスピッキングのレシピについては、references/raycasting-recipes.md を参照してください。

レイの結果、その他のクエリ、3D のマウスピッキング

intersect_ray の結果辞書には position、normal、collider、collider_id、rid、shape が含まれます。PhysicsDirectSpaceState は、intersect_point(ある点で重なっているシェイプ)、intersect_shape(領域クエリ)、cast_motion(シェイプのスイープ)、collide_shape(接触点)、get_rest_info(静止時の衝突情報)にも対応しています。3D のマウスピッキングでは、Camera3D.project_ray_origin(screen_pos) と project_ray_normal(screen_pos) を組み合わせてレイを作成します。

マウスピッキングの完全なレシピ(GDScript と C#)については、references/raycasting-recipes.md を参照してください。


8. Jolt Physics

Jolt は組み込みの代替物理エンジンで、Godot 4.4 から実験的なオプトイン機能として利用できます。(Godot 4.6 以降) Jolt は実験的機能ではなくなり、新規作成した 3D プロジェクトではデフォルトになります。以前のバージョンからアップグレードしたプロジェクトは、変更するまで DEFAULT(GodotPhysics3D)のままです。

Jolt を有効にする

プロジェクト設定 → Physics → 3D → Physics Engine → Jolt Physics → 保存 → エディターを再起動します。(3D のみ。2D では常に GodotPhysics が使用されます。)

メリットと違い

メリット: 積み重ねの安定性が向上し、GodotPhysics で既知の不具合がある CylinderShape3D を問題なく使用でき、SoftBody3D が改善され、アクティブエッジ検出によってゴースト衝突が軽減されます。

GodotPhysics との動作上の違い(安定化、衝突マージン、単一ボディのジョイント、face_index、未対応のジョイントプロパティ)については、references/jolt-differences.md を参照してください。

⚠️ Godot 4.7 での変更: Jolt Physics では、WorldBoundaryShape3D.plane.d が Godot Physics と同じ符号規則に従うようになりました。平面の距離は Godot 4.6 とは逆の符号で解釈されます。4.6 の動作を維持するには、符号を反転してください。4.7 移行ガイド を参照してください。


9. 物理補間

物理ティック間の視覚的な動きを滑らかにし、ティックレートとフレームレートが一致しない場合に発生する「階段状」のちらつきをなくします。プロジェクト設定 → Physics → Common → Physics Interpolation で有効にします(4.3 では 2D のみが補間され、3D は 4.4 から対応します)。Godot 4.5 以降では 3D 補間パイプラインが再構成され(RenderingServer → SceneTree)、ネストされたトランスフォームでより正確な結果が得られるようになりました。API に変更はなく、アップグレードすると自動的に改善されます。

基本ルール
  1. すべてのゲームロジックを _physics_process() に移動します — 物理ティック以外で設定したトランスフォームはちらつきの原因になります
  2. 物理オブジェクトを動かす Tweens と AnimationPlayer は、物理ティックのタイミングを使用する必要があります
  3. テレポート後または初期配置後に reset_physics_interpolation() を呼び出します。「尾を引く」現象を防ぎます

テレポート時のリセット例(GDScript と C#)、ノードごとの physics_interpolation_mode の制御、ティックレートの目安については、references/interpolation-tuning.md を参照してください。

カメラの補間

物理補間では、カメラに特別な処理が必要です。カメラを独立させる(または top_level = true にする)ことで、_process()(_physics_process() ではありません)で更新し、Node3D.get_global_transform_interpolated() を使ってターゲットの滑らかな位置を取得します(4.4+)。

滑らかに追従する Camera3D の完全な手順(GDScript + C#)については、references/interpolation-camera.md を参照してください。


10. ラグドールシステム

ラグドールはアニメーションを物理演算に置き換え、プロシージャルな死亡表現や爆発、力の抜けたキャラクターを実現します。Skeleton3D → Skeleton メニュー → Create Physical Skeleton から生成します。肩/腰/首には ConeJoint、肘/膝には HingeJoint を使います。PinJoint(デフォルト)では、崩れてしまう傾向があります。physical_bones_start_simulation() で動作させ、Influence でブレンドします。

セットアップ、ジョイントのガイダンス、GDScript + C# による完全な制御、アニメーションブレンド、衝突の例外については、references/ragdoll-recipes.md を参照してください。


11. SoftBody3D

SoftBody3D は変形可能なオブジェクト(布、マント、ゼリーなど)をシミュレートします。メッシュの細分化がシミュレーションを左右し、CollisionShape の子ノードは必要ありません。Jolt Physics を推奨します。 崩壊を防ぐため、Simulation Precision ≥ 5 に設定します。Pressure > 0.0 にするのは閉じたメッシュの場合のみです。

Godot 4.5+ では、RigidBody3D と同様に力を適用する apply_central_impulse() / apply_central_force() が追加されており、すべてのシミュレーションポイントに力が分配されます。

布/マントの手順(PlaneMesh、BoneAttachment3D による固定、Parent Collision Ignore)と、GDScript および C# による 4.5+ の力/インパルス API(爆発によるノックバック、継続的な風)については、references/softbody-recipes.md を参照してください。

⚠️ Godot 4.7 での変更点: Jolt Physics では、SoftBody3D の質量は 0(自動計算され、ポイントあたり 1 kg となるため、合計質量が非常に大きくなる値)ではなくなり、Godot Physics と同様、ボディ全体で 1 kg がデフォルトになりました。linear_stiffness の適用方法も変更されているため、アップグレード後に linear_stiffness と damping_coefficient を再調整してください。4.7 移行ガイドを参照してください。


13. 物理演算の問題のトラブルシューティング

症状 → トンネリング、不安定に揺れる積み重ね、スケーリングされたシェイプ、タイル衝突による引っ掛かり、不安定な円柱、物理演算のスパイラル・オブ・デス、原点から遠い場所での浮動小数点精度の問題を網羅した、原因と対処法の簡易表です。

完全な表については、references/troubleshooting.md を参照してください。


14. 実装チェックリスト

  • 動的ボディにはプリミティブの衝突シェイプを使用し、凹形シェイプは StaticBodies のみに使用する
  • Project Settings で衝突レイヤーに名前を付け、各ボディのレイヤー/マスクを正しく設定する
  • 衝突シェイプやボディに scale を設定しない — シェイプのサイズパラメーターを直接使用する
  • RigidBodies の状態は _physics_process() ではなく、_integrate_forces() で変更する
  • 接触シグナルが必要な RigidBodies では、contact_monitor = true と max_contacts_reported > 0 を設定する
  • 移動プラットフォームには AnimatableBody2D/3D を使用する(StaticBody を手動で動かさない)
  • コード内のレイキャストには、_physics_process() 内でのみ PhysicsDirectSpaceState を使用する
  • 物理補間を有効にし、テレポート後/初期配置後に reset_physics_interpolation() を呼び出す
  • ラグドールのボーンをキャラクターのカプセルとは別の衝突レイヤーに配置する
  • 3D プロジェクトでは Jolt を使用する(Godot 4.6+ では非実験的なデフォルト)

コメント