# \# ジョイント・チェーン・ロープシステム スクリプト使用ガイド

**URL:** https://guild.rpgmakerofficial.com/t/topic/1143
**Category:** 一般
**Created:** [2026 年 2 月 6 日午前 6:32 UTC](https://guild.rpgmakerofficial.com/t/topic/1143 "2026-02-06T06:32:41Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Shirokishi](https://avatars.discourse-cdn.com/v4/letter/s/df788c/32.png) [@Shirokishi](https://guild.rpgmakerofficial.com/u/Shirokishi)
#### Post date: [2026 年 2 月 6 日午前 6:32 UTC](https://guild.rpgmakerofficial.com/t/topic/1143/1 "2026-02-06T06:32:41Z")

</div>

# ジョイント・チェーン・ロープシステム スクリプト使用ガイド（BreakableJointMonitor2D、RopePathBinder2D、ChainPathBinder2D、ChainJointSetupTool、ChainPartResource、JointBreakParams、AreaJointBreaker2D、RigidBodyPusherNatural）

[chain\_joints\_scripts.zip](https://guild.rpgmakerofficial.com/uploads/short-url/lcm2sP3ExTGwyctASQMuWzFAZ5X.zip) (24.1 KB)

本スクリプト群を使用すると、物理ジョイント（PinJoint2D、GrooveJoint2D）を監視・切断し、ロープやチェーンの形状をPath2Dとして可視化することができます。

ジョイントの破断条件、チェーンの自動セットアップ、ロープのパス生成などを自由に設定することができます。

## 0. 用語

|用語|意味|

| — | — |

|Joint|`PinJoint2D` または `GrooveJoint2D`（物理ボディ間の接続）|

|Monitor|`BreakableJointMonitor2D`（ジョイントの破断を監視・判定）|

|RopePathBinder|`RopePathBinder2D`（ロープの節点列からPath2Dを生成）|

|ChainPathBinder|`ChainPathBinder2D`（チェーンの構造を管理し、切断時にパスを分割）|

|ChainPart|`ChainPartResource`（鎖の部品情報：RigidBody2Dとsegノード）|

|SetupTool|`ChainJointSetupTool`（チェーン用Jointの自動セットアップツール）|

|AreaBreaker|`AreaJointBreaker2D`（Area2D範囲内のJoint2Dを一括切断）|

|JointBreakParams|`JointBreakParams`（ジョイントごとの個別破断パラメータ）|

|segノード|各RigidBody2D内の節点マーカー（seg1, seg2など）|

|RigidBodyPusher|`RigidBodyPusherNatural`（CharacterBody2DがRigidBody2Dを押す）|

* * *

## 1. セットアップ（「動作する状態」を作る）

### 1-1. 基本的なチェーン構造を作成する

**目的**

チェーンシステムを使用するには、まず複数のRigidBody2Dを連鎖させる必要があります。手動で作成するか、`ChainJointSetupTool`を使用して自動生成できます。

**設定手順（手動）**

1. `Node2D`をシーンに配置します（例：`ChainRoot`）

2. その子として複数の`RigidBody2D`を配置します（例：`Link1`, `Link2`, `Link3`…）

3. 各RigidBody2Dに`CollisionShape2D`と`Sprite2D`を追加します

4. 各RigidBody2Dの子として`Node2D`を追加し、`seg1`、`seg2`と命名します（接続点として使用）

**設定手順（自動：ChainJointSetupTool使用）**

1. `Node2D`をシーンに配置します

2. `chain_setup_tool.gd`をアタッチします

3. `target_parent`にチェーンの親ノードを設定します（未設定ならこのノードの親）

4. Inspectorで`_setup_button`にチェックを入れるか、`setup_chain()`を呼びます

5. 子のRigidBody2Dが自動検出され、Jointとsegノードが生成されます

**サンプルでは**

- `auto_setup_all=true`の場合、`BreakableJointMonitor2D`、`ChainPathBinder2D`、`Path2D`、`PathRibbonMesh2D`が自動生成されます

* * *

### 1-2. ジョイント監視を設定する（BreakableJointMonitor2D）

**目的**

ジョイントが一定条件を満たしたときに自動で切断するため、`BreakableJointMonitor2D`を配置して監視を開始します。

**設定手順**

1. `Node`をシーンに配置します

2. `breakable_joint_monitor_2d.gd`をアタッチします

3. `search_root`に監視対象のルートノードを設定します（未設定なら親ノード）

4. 破断条件を設定します（例：`break_relative_speed`、`pin_break_error_pixels`など）

5. `auto_collect_on_ready=true`（既定値）なら、起動時に自動でジョイントを収集します

**サンプルでは**

- `auto_collect_on_ready=true`で自動収集

- `recollect_after_break=true`で切断後に再収集

* * *

### 1-3. ロープ/チェーンの可視化を設定する

**目的**

物理的に動くロープやチェーンの形状を`Path2D`として可視化します。`RopePathBinder2D`または`ChainPathBinder2D`を使用します。

**設定手順（RopePathBinder2D：ロープ用）**

1. `Node`をシーンに配置します

2. `rope_solver.gd`をアタッチします

3. `source_mode`を設定します：

- `NODEPATH_LIST`：`point_node_paths`に節点のNodePathを明示的に指定

- `CHILDREN_RECURSIVE`：子孫から自動検出（`child_filter_mode`で型を指定）

1. `output_paths`に`Path2D`を追加します（空なら自動生成）

2. `auto_update=true`で自動更新されます

**設定手順（ChainPathBinder2D：チェーン用）**

1. `Node`をシーンに配置します

2. `chain_path_binder.gd`をアタッチします

3. `auto_detect_mode=true`にすると、`search_root`配下のRigidBody2Dを自動検出します

4. または`chain_parts`に手動で`ChainPartResource`を追加します

5. `joint_monitor`に`BreakableJointMonitor2D`を設定すると、切断時に自動でパスが分割されます

6. `output_paths`に`Path2D`を追加します（空なら自動生成）

**サンプルでは**

- `auto_update=true`、`update_in_physics=true`で物理フレームで更新

* * *

### 1-4. CharacterBody2DでRigidBody2Dを押す設定（RigidBodyPusherNatural）

**目的**

`CharacterBody2D`が`move_and_slide()`で移動した際に、接触した`RigidBody2D`を自然に押す機能を追加します。

**設定手順**

1. `CharacterBody2D`の子として`Node`を追加します

2. `rigid_body_pusher.gd`をアタッチします

3. `pusher_physics_priority`を設定します（`move_and_slide()`より後で実行されるように大きめの値、既定値：1000）

4. 押す強さや質量の考慮などを調整します

**サンプルでは**

- `use_force=true`で毎フレーム力を適用

- `consider_mass=true`で質量を考慮

- `wake_rigid_bodies=true`で接触時にRigidBody2Dを起こす

* * *

### 1-5. Area2D範囲内のジョイントを一括切断（AreaJointBreaker2D）

**目的**

特定の範囲（Area2D）内にあるジョイントを一括で切断する機能です。剣で切る、爆発で切るなどの演出に使用できます。

**設定手順**

1. 切断範囲となる`Area2D`を用意し、子に`CollisionShape2D`を追加します

2. 任意のノードに`area_joint_breaker.gd`をアタッチします

3. `target_area`に上記の`Area2D`を設定します

4. `monitor`に`BreakableJointMonitor2D`を設定します（任意、設定すると`joint_broken`シグナルが飛びます）

5. `break_joints_in_target_area()`を呼びます

**サンプルでは**

- エディタで`_break_now_button`にチェックを入れると実行できます

* * *

## 2. 実行（どう動作するか）

### 2-1. ジョイントの自動切断

**処理の流れ**

1. `BreakableJointMonitor2D`が`_physics_process`で各ジョイントを監視します

2. 破断条件を満たした場合、`break_delay_frames`（または`break_delay_sec`）だけ待機します

3. 条件が継続している場合、`joint.queue_free()`で切断し、`joint_broken`シグナルを発行します

4. `recollect_after_break=true`なら、切断後にジョイントを再収集します

**破断条件の例**

- `pin_break_error_pixels`：アンカー誤差が指定ピクセル以上

- `break_relative_speed`：相対速度が指定値以上

- `break_stretch_ratio`：初期距離に対する伸び率が指定値以上

- `break_angle_degrees` + `break_angle_duration_sec`：角度が指定度以上で一定時間継続

**サンプルでの動作**

- ジョイントが引っ張られたり、角度が大きくなったりすると自動で切断されます

* * *

### 2-2. ロープ/チェーンのパス更新

**処理の流れ**

1. `RopePathBinder2D`または`ChainPathBinder2D`が`_physics_process`で節点列を収集します

2. 各節点の`global_position`を`Path2D`のローカル座標に変換します

3. `Curve2D`をクリアして、新しい点列を追加します

4. オプションでリサンプル、スムーズハンドル、端点オフセットを適用します

5. `paths_updated`シグナルを発行します（`PathRibbonMesh2D`などで使用）

**チェーン切断時の自動分割**

1. `ChainPathBinder2D`が`joint_broken`シグナルを受け取ります

2. 切れたジョイントの`body_a`と`body_b`を取得します

3. 接続グラフを再構築し、連結成分を検出します

4. 各連結成分ごとに`Path2D`を生成・更新します

**サンプルでの動作**

- ロープ/チェーンが物理的に動くと、`Path2D`が追従して形状を可視化します

- ジョイントが切れると、パスが自動で分割されます

* * *

### 2-3. RigidBody2Dの押し出し

**処理の流れ**

1. `RigidBodyPusherNatural`が`_physics_process`で実行されます（`pusher_physics_priority`で実行順序を制御）

2. 親の`CharacterBody2D`の`get_slide_collision_count()`で衝突を取得します

3. 各衝突の相手が`RigidBody2D`の場合、押し力を計算します

4. 法線方向と移動方向の合成で押し方向を決定します

5. `apply_central_force()`または`apply_central_impulse()`で力を適用します

**サンプルでの動作**

- `CharacterBody2D`が箱などの`RigidBody2D`に接触すると、自然に押し出されます

* * *

## 3. 設定項目（主要パラメータ）

### 3-1. BreakableJointMonitor2D の設定

|項目|目的（何に効くか）|既定値|

| — | — | — |

|`search_root`|監視対象を探すルートノード|親ノード|

|`break_relative_speed`|相対速度がこの値以上で破断候補|0.0（無効）|

|`pin_break_error_pixels`|アンカー誤差がこのピクセル以上で破断|0.0（無効）|

|`break_stretch_ratio`|初期距離に対する伸び率がこの値以上で破断|0.0（無効）|

|`break_stretch_duration_sec`|この秒数以上伸び続けたら破断|0.0（無効）|

|`break_angle_degrees`|この角度以上で一定時間経ったら破断|0.0（無効）|

|`break_angle_duration_sec`|角度超過がこの秒数以上続いたら破断|0.5|

|`use_break_delay_frames`|BreakDelayをフレーム数で扱う（推奨）|true|

|`break_delay_frames`|exceededがこのフレーム数連続したら破断|1|

|`auto_collect_on_ready`|起動時に自動収集|true|

|`recollect_after_break`|切断後に自動再収集|true|

補足（破断しないときの典型原因）

- 破断条件の値が0.0（無効）になっている

- `break_delay_frames`が大きすぎる

- `search_root`が正しく設定されていない

- ジョイントが`exclude_groups`に含まれている

* * *

### 3-2. RopePathBinder2D / ChainPathBinder2D の設定

|項目|目的（何に効くか）|既定値|

| — | — | — |

|`auto_update`|自動更新（trueなら毎フレーム更新）|true|

|`update_in_physics`|物理フレームで更新する|true|

|`min_point_distance_px`|近すぎる点を追加しない|0.0（無効）|

|`max_points`|最大点数|0（無制限）|

|`resample_spacing_px`|点列を固定間隔でリサンプル|0.0（無効）|

|`enable_smooth_handles`|Curve2Dのハンドルを滑らかにする|false|

|`start_point_offset_local`|先頭点のオフセット|Vector2(0, 0)|

|`end_point_offset_local`|末尾点のオフセット|Vector2(0, 0)|

補足（パスが更新されないときの典型原因）

- `auto_update=false`になっている

- `output_paths`が空

- 節点が収集されていない（`source_mode`や`search_root`の設定を確認）

* * *

### 3-3. ChainJointSetupTool の設定

|項目|目的（何に効くか）|既定値|

| — | — | — |

|`target_parent`|セットアップ対象の親ノード|親ノード|

|`joint_type`|使用するJointの種類（GROOVE/PIN）|GROOVE|

|`groove_length`|GrooveJoint2Dの長さ|8.0|

|`auto_create_seg_nodes`|各RigidBody2Dにsegノードを自動生成|true|

|`auto_setup_all`|全ノードを自動生成・設定|true|

|`setup_on_ready`|実行時に自動セットアップ|false|

補足（セットアップが失敗するときの典型原因）

- `target_parent`配下にRigidBody2Dが2つ未満

- 既存のJointが正しく削除されていない

* * *

### 3-4. RigidBodyPusherNatural の設定

|項目|目的（何に効くか）|既定値|

| — | — | — |

|`pusher_physics_priority`|物理処理の優先度（大きいほど後）|1000|

|`require_owner_motion`|親が動いたときだけ押す|false|

|`use_force`|力方式（true推奨）|true|

|`push_strength`|押す強さ係数|100.0|

|`min_push_force`|最小の押し力|50.0|

|`consider_mass`|質量を考慮する|true|

|`mass_influence`|質量の影響度（0.0-1.0）|0.5|

|`normal_direction_weight`|法線方向の力の重み|0.7|

|`movement_direction_weight`|移動方向の力の重み|0.3|

補足（押せないときの典型原因）

- `require_owner_motion=true`で親が動いていない

- `min_push_force`が小さすぎる

- `consider_mass=true`で相手が重すぎる

* * *

## 4. 変更手順（よくある用途）

### 4-1. ジョイントの破断条件を調整する

**目的**

より敏感に、またはより頑丈にジョイントを設定します。

**手順**

1. `BreakableJointMonitor2D`を選択します

2. 破断条件の値を調整します：

- 敏感にする：`break_relative_speed`を下げる、`break_delay_frames`を1にする

- 頑丈にする：`break_relative_speed`を上げる、`break_delay_frames`を増やす

1. 個別設定が必要な場合は、`joint_params`に`JointBreakParams`リソースを追加します

**個別設定の例**

1. リソースとして`JointBreakParams`を作成します

2. `joint_path`に対象ジョイントのNodePathを設定します

3. 個別の破断パラメータを設定します（-1.0ならグローバル設定を使用）

4. `BreakableJointMonitor2D`の`joint_params`に追加します

* * *

### 4-2. ロープ/チェーンの見た目を調整する

**目的**

パスの滑らかさや点の密度を調整します。

**手順**

1. `RopePathBinder2D`または`ChainPathBinder2D`を選択します

2. `resample_spacing_px`を設定すると、点列が均一間隔になります（例：8.0）

3. `enable_smooth_handles=true`にすると、`Curve2D`が滑らかになります

4. `min_point_distance_px`を設定すると、近すぎる点が間引かれます

* * *

### 4-3. チェーンのセグメント数を増やす

**目的**

より長いチェーンを作成します。

**手順**

1. チェーンの親ノード配下に`RigidBody2D`を追加します

2. `ChainJointSetupTool`の`setup_chain()`を再実行します

3. または手動で`GrooveJoint2D`/`PinJoint2D`を追加します

* * *

### 4-4. 押し出しの強さを調整する

**目的**

`CharacterBody2D`が`RigidBody2D`を押す強さを変更します。

**手順**

1. `RigidBodyPusherNatural`を選択します

2. `push_strength`を調整します（大きいほど強く押せます）

3. `min_push_force`を調整します（地面の箱を押すため）

4. `mass_influence`を調整します（0.0に近づけると質量を無視）

* * *

## 5. トラブルシュート

|症状|主な原因|対処|

| — | — | — |

|ジョイントが切れない|破断条件が0.0（無効）|`break_relative_speed`などを有効な値に設定|

|ジョイントがすぐ切れる|破断条件が厳しすぎる|`break_relative_speed`を上げる、`break_delay_frames`を増やす|

|パスが更新されない|`auto_update=false`|`auto_update=true`に設定|

|パスが表示されない|`output_paths`が空|`Path2D`を追加するか、自動生成を待つ|

|チェーンがセットアップされない|RigidBody2Dが2つ未満|親ノード配下に2つ以上のRigidBody2Dを配置|

|押し出しが効かない|`require_owner_motion=true`で親が止まっている|`require_owner_motion=false`にするか、親を動かす|

|Area2Dで切断されない|`target_area`が未設定|`target_area`に`Area2D`を設定|

|個別設定が効かない|`joint_path`が正しくない|`joint_path`を再設定、または`search_root`からの相対パスを確認|

* * *

## 6. スクリプト概要

### 6-1. BreakableJointMonitor2D

`BreakableJointMonitor2D`は、シーン内の`PinJoint2D`と`GrooveJoint2D`を監視し、指定した条件を満たしたときに自動で切断する`Node`スクリプトです。

**特徴**

- Pin/Groove共通の破断条件（相対速度、伸び率、角度、時間ベースの伸び）

- Pin専用の破断条件（アンカー誤差）

- Groove専用の破断条件（範囲外、端での引っ張り）

- ジョイントごとの個別設定（`JointBreakParams`）

- フレームベース/秒ベースの破断遅延

- 自動収集・再収集機能

**前提と必要条件**

- Godot 4系の2Dノード構成を前提とします

- 監視対象は`search_root`配下の`PinJoint2D`と`GrooveJoint2D`です

- `exclude_groups`に含まれるノードは監視されません

**プロパティ一覧**

|プロパティ|型 / 既定値|説明|

| — | — | — |

|`search_root`|`NodePath` / 空|監視対象を探すルートノード|

|`exclude_groups`|`Array[String]` / `[]`|監視から除外するグループ名|

|`break_relative_speed`|`float` / `0.0`|相対速度がこの値以上で破断候補（0なら無効）|

|`pin_break_error_pixels`|`float` / `0.0`|アンカー誤差がこのピクセル以上で破断（0なら無効）|

|`break_stretch_ratio`|`float` / `0.0`|初期距離に対する伸び率がこの値以上で破断（0なら無効）|

|`break_stretch_duration_sec`|`float` / `0.0`|この秒数以上伸び続けたら破断（0なら無効）|

|`stretch_threshold_ratio`|`float` / `1.1`|伸び判定の閾値（初期距離に対する比率）|

|`break_angle_degrees`|`float` / `0.0`|この角度以上で一定時間経ったら破断（0なら無効）|

|`break_angle_duration_sec`|`float` / `0.5`|角度超過がこの秒数以上続いたら破断|

|`groove_break_out_of_range_pixels`|`float` / `0.0`|アンカー位置が溝の範囲外に出た場合に破断（0なら無効）|

|`groove_break_end_pull_speed`|`float` / `0.0`|端で外向きに引っ張る相対速度がこの値以上で破断（0なら無効）|

|`groove_end_epsilon_pixels`|`float` / `2.0`|端判定の許容（ピクセル）|

|`joint_params`|`Array[JointBreakParams]` / `[]`|ジョイントごとの個別設定|

|`use_break_delay_frames`|`bool` / `true`|BreakDelayをフレーム数で扱う（推奨）|

|`break_delay_frames`|`int` / `1`|exceededがこのフレーム数連続したら破断|

|`break_delay_sec`|`float` / `0.0`|exceededが連続してこの秒数続いたら破断（旧方式）|

|`over_time_decay_sec`|`float` / `0.0`|exceededが途切れたときのカウンタ減衰時間|

|`auto_collect_on_ready`|`bool` / `true`|起動時に自動収集|

|`recollect_interval_sec`|`float` / `0.0`|一定間隔で再収集する（0ならしない）|

|`recollect_every_frame`|`bool` / `false`|毎フレーム必ず再収集する|

|`recollect_after_break`|`bool` / `true`|切断後に自動再収集|

|`debug_print_eval`|`bool` / `false`|判定ログを出力する|

**シグナル**

- `joint_broken(joint: Joint2D, reason: String)`：ジョイントが切断されたときに発行

- `joint_registered(joint: Joint2D)`：ジョイントが登録されたときに発行

- `joint_unregistered(joint: Joint2D)`：ジョイントが登録解除されたときに発行

**公開メソッド**

- `collect_joints()`：ジョイントを手動で収集

- `break_joint(joint: Joint2D, reason: String = "manual")`：ジョイントを手動で切断

* * *

### 6-2. RopePathBinder2D

`RopePathBinder2D`は、「ロープ（節点列）」の現在形状に合わせて、`Path2D`の`Curve2D`を毎フレーム再構築する`Node`スクリプトです。

**特徴**

- 節点は`Node2D`であれば何でも可（RigidBody2D, Bone2D, CharacterBody2D, Marker2D等）

- 収集方法：明示NodePath / 子孫探索（型フィルタ）

- 出力：複数のPath2D更新

- 点の間引き / 簡易ハンドル / 固定間隔リサンプル

- ロープ切断時の自動分割

**前提と必要条件**

- 節点は`Node2D`である必要があります

- `Path2D`は`output_paths`に追加するか、自動生成されます

**プロパティ一覧**

|プロパティ|型 / 既定値|説明|

| — | — | — |

|`output_paths`|`Array[Path2D]` / `[]`|生成・更新するPath2Dの配列|

|`auto_update`|`bool` / `true`|自動更新（trueなら毎フレーム更新）|

|`update_in_physics`|`bool` / `true`|物理フレームで更新する|

|`source_mode`|`enum` / `NODEPATH_LIST`|`NODEPATH_LIST` / `CHILDREN_RECURSIVE`|

|`point_node_paths`|`Array[NodePath]` / `[]`|source\_mode==NODEPATH\_LISTのとき使用|

|`child_filter_mode`|`enum` / `ANY_NODE2D`|子孫探索での型フィルタ|

|`preserve_found_order`|`bool` / `true`|子孫探索での並び順を保持|

|`search_root`|`Node` / `null`|子孫探索の基点|

|`auto_split_on_break`|`bool` / `true`|ロープ切断時に自動でパスを分割|

|`joint_monitor`|`BreakableJointMonitor2D` / `null`|joint\_brokenシグナルを受け取る|

|`path_parent`|`Node` / `null`|生成されたPath2Dの親ノード|

|`min_point_distance_px`|`float` / `0.0`|近すぎる点を追加しない（0.0なら無効）|

|`max_points`|`int` / `0`|最大点数（0なら無制限）|

|`start_point_offset_local`|`Vector2` / `(0, 0)`|先頭点のオフセット|

|`end_point_offset_local`|`Vector2` / `(0, 0)`|末尾点のオフセット|

|`resample_spacing_px`|`float` / `0.0`|点列を固定間隔でリサンプル（0.0なら無効）|

|`enable_smooth_handles`|`bool` / `false`|Curve2Dのハンドルを滑らかにする|

|`smooth_handle_strength_px`|`float` / `12.0`|ハンドルの強さ（px）|

|`weaken_end_handles`|`bool` / `true`|端点のハンドルを弱める|

**シグナル**

- `paths_updated(paths: Array[Path2D])`：パスが更新されたときに発行

**公開メソッド**

- `update_paths_from_rope()`：手動でパスを更新

* * *

### 6-3. ChainPathBinder2D

`ChainPathBinder2D`は、鎖（Chain）の構造を管理し、ジョイント切断時に自動でパスを分割する`Node`スクリプトです。

**特徴**

- 各鎖の部品（RigidBody）内のsegノードを柔軟に設定可能

- 自動検出モード（`search_root`配下のRigidBody2Dを自動検出）

- ジョイント接続グラフを構築し、連結成分ごとにパスを生成

- 切断時に自動でパスを分割

**前提と必要条件**

- 鎖の部品は`ChainPartResource`で定義します

- `auto_detect_mode=true`の場合、`search_root`配下のRigidBody2Dを自動検出します

**プロパティ一覧**

|プロパティ|型 / 既定値|説明|

| — | — | — |

|`auto_detect_mode`|`bool` / `false`|自動検出モード（trueなら自動検出）|

|`search_root`|`Node` / `null`|検索開始ノード|

|`seg_node_prefix`|`String` / `"seg"`|segノードの命名規則プレフィックス|

|`use_rigidbody_as_seg_when_no_seg`|`bool` / `true`|segノードがない場合、RigidBody2D自体をsegとして使用|

|`chain_parts`|`Array[ChainPartResource]` / `[]`|鎖の部品の配列|

|`output_paths`|`Array[Path2D]` / `[]`|生成・更新するPath2Dの配列|

|`auto_update`|`bool` / `true`|自動更新|

|`update_in_physics`|`bool` / `true`|物理フレームで更新する|

|`joint_monitor`|`BreakableJointMonitor2D` / `null`|joint\_brokenシグナルを受け取る|

|`path_parent`|`Node` / `null`|生成されたPath2Dの親ノード|

|`ribbon_mesh`|`PathRibbonMesh2D` / `null`|パス更新時に直接関数呼び出し|

|`min_point_distance_px`|`float` / `0.0`|近すぎる点を追加しない|

|`max_points`|`int` / `0`|最大点数|

|`start_point_offset_local`|`Vector2` / `(0, 0)`|先頭点のオフセット|

|`end_point_offset_local`|`Vector2` / `(0, 0)`|末尾点のオフセット|

|`resample_spacing_px`|`float` / `0.0`|点列を固定間隔でリサンプル|

|`enable_smooth_handles`|`bool` / `false`|Curve2Dのハンドルを滑らかにする|

|`smooth_handle_strength_px`|`float` / `12.0`|ハンドルの強さ|

|`weaken_end_handles`|`bool` / `true`|端点のハンドルを弱める|

**公開メソッド**

- `update_paths_from_chain()`：手動でパスを更新

* * *

### 6-4. ChainJointSetupTool

`ChainJointSetupTool`は、チェーン用Jointの自動セットアップツールです。

**特徴**

- 子のRigidBody2Dを自動検出

- 連鎖的にJointを生成（GrooveJoint2DまたはPinJoint2D）

- segノードの自動生成

- 全ノードの自動セットアップ（BreakableJointMonitor2D、ChainPathBinder2D、Path2D、PathRibbonMesh2D）

**前提と必要条件**

- `target_parent`配下に2つ以上のRigidBody2Dが必要です

- `@tool`スクリプトなので、エディタでも実行可能です

**プロパティ一覧**

|プロパティ|型 / 既定値|説明|

| — | — | — |

|`target_parent`|`Node` / `null`|セットアップ対象の親ノード|

|`joint_type`|`enum` / `GROOVE`|使用するJointの種類（GROOVE/PIN）|

|`groove_length`|`float` / `8.0`|GrooveJoint2Dの長さ|

|`groove_initial_offset`|`float` / `1.0`|GrooveJoint2Dの初期オフセット|

|`groove_joint_position_local`|`Vector2` / `(0, -16)`|GrooveJoint2Dの位置|

|`pin_joint_position_local`|`Vector2` / `(0, 0)`|PinJoint2Dの位置|

|`disable_collision`|`bool` / `false`|Jointの衝突無効化|

|`bias`|`float` / `0.9`|Jointのbias|

|`auto_create_seg_nodes`|`bool` / `true`|各RigidBody2Dにsegノードを自動生成|

|`seg_node_prefix`|`String` / `"seg"`|segノードのプレフィックス|

|`seg1_position_local`|`Vector2` / `(0, -10)`|seg1の位置|

|`seg2_position_local`|`Vector2` / `(0, 10)`|seg2の位置|

|`auto_setup_all`|`bool` / `true`|全ノードを自動生成・設定|

|`auto_connect_breakable_monitor`|`bool` / `true`|BreakableJointMonitor2Dへの自動接続|

|`breakable_monitor_path`|`NodePath` / `""`|BreakableJointMonitor2Dへのパス|

|`auto_setup_chain_binder`|`bool` / `true`|ChainPathBinder2Dへの自動設定|

|`chain_binder_path`|`NodePath` / `""`|ChainPathBinder2Dへのパス|

|`setup_on_ready`|`bool` / `false`|実行時に自動セットアップ|

|`_setup_button`|`bool` / `false`|Inspectorから実行するボタン|

**公開メソッド**

- `setup_chain()`：チェーンをセットアップ

* * *

### 6-5. ChainPartResource

`ChainPartResource`は、鎖の部品情報を保持する`Resource`クラスです。

**プロパティ一覧**

|プロパティ|型 / 既定値|説明|

| — | — | — |

|`rigid_body_path`|`NodePath` / `NodePath()`|この鎖の部品のRigidBody2D（NodePath）|

|`seg_node_paths`|`Array[NodePath]` / `[]`|この部品内のsegノード（NodePathの配列）|

* * *

### 6-6. JointBreakParams

`JointBreakParams`は、ジョイントごとの個別破断パラメータを保持する`Resource`クラスです。

**プロパティ一覧**

|プロパティ|型 / 既定値|説明|

| — | — | — |

|`joint_path`|`NodePath` / `NodePath()`|対象ジョイント（NodePath）|

|`break_relative_speed`|`float` / `-1.0`|相対速度（-1ならグローバル設定を使用）|

|`pin_break_error_pixels`|`float` / `-1.0`|アンカー誤差（-1ならグローバル設定を使用）|

|`groove_break_out_of_range_pixels`|`float` / `-1.0`|アンカー位置が溝の範囲外（-1ならグローバル設定を使用）|

|`groove_break_end_pull_speed`|`float` / `-1.0`|端で外向きに引っ張る相対速度（-1ならグローバル設定を使用）|

|`groove_end_epsilon_pixels`|`float` / `-1.0`|端判定の許容（-1ならグローバル設定を使用）|

|`groove_break_stretch_ratio`|`float` / `-1.0`|初期距離に対する伸び率（-1ならグローバル設定を使用）|

|`groove_break_stretch_duration_sec`|`float` / `-1.0`|この秒数以上伸び続けたら破断（-1ならグローバル設定を使用）|

|`groove_stretch_threshold_ratio`|`float` / `-1.0`|伸び判定の閾値（-1ならグローバル設定を使用）|

|`groove_break_angle_degrees`|`float` / `-1.0`|この角度以上で一定時間経ったら破断（-1なら無効）|

|`groove_break_angle_duration_sec`|`float` / `0.5`|角度超過がこの秒数以上続いたら破断|

* * *

### 6-7. AreaJointBreaker2D

`AreaJointBreaker2D`は、「別オブジェクト」が実行して、指定したArea2D（のCollisionShape2D）範囲内のJoint2Dを一括で切断するユーティリティです。

**特徴**

- BreakableJointMonitor2Dがある場合は`monitor.break_joint()`を使う（推奨）

- monitorが無い場合は`joint.queue_free()`で直接削除

- 対応形状：CircleShape2D、RectangleShape2D、CapsuleShape2D

**前提と必要条件**

- `target_area`に`Area2D`を設定する必要があります

- `Area2D`の子に`CollisionShape2D`が必要です

**プロパティ一覧**

|プロパティ|型 / 既定値|説明|

| — | — | — |

|`enabled`|`bool` / `true`|有効/無効|

|`monitor`|`BreakableJointMonitor2D` / `null`|BreakableJointMonitor2Dの参照（任意）|

|`search_root`|`Node` / `null`|走査するルート（未設定ならシーン全体）|

|`target_area`|`Area2D` / `null`|切断範囲として使うArea2D|

|`target_collision_shape`|`CollisionShape2D` / `null`|範囲判定に使うCollisionShape2D（未設定なら自動検索）|

|`include_pin_joint`|`bool` / `true`|PinJoint2Dを対象にするか|

|`include_groove_joint`|`bool` / `true`|GrooveJoint2Dを対象にするか|

|`include_other_joint2d`|`bool` / `true`|その他のJoint2Dを対象にするか|

|`break_reason`|`String` / `"area_break"`|切断理由（monitorがある場合に渡される）|

|`max_break_per_call`|`int` / `0`|1回の実行で切る上限（0なら無制限）|

|`_break_now_button`|`bool` / `false`|エディタでボタン実行|

**公開メソッド**

- `break_joints_in_target_area()`：target\_areaの範囲内のJoint2Dを切断する

* * *

### 6-8. RigidBodyPusherNatural

`RigidBodyPusherNatural`は、親`CharacterBody2D`の`move_and_slide()`後に実行され、接触した`RigidBody2D`を自然に押す`Node`スクリプトです。

**特徴**

- 親が動いたときだけ押すオプション

- 力方式/インパルス方式の選択

- 質量を考慮した押し出し

- 法線方向と移動方向の合成

**前提と必要条件**

- 親ノードが`CharacterBody2D`である必要があります

- `move_and_slide()`が呼ばれている必要があります

**プロパティ一覧**

|プロパティ|型 / 既定値|説明|

| — | — | — |

|`pusher_physics_priority`|`int` / `1000`|物理処理の優先度（大きいほど後）|

|`require_owner_motion`|`bool` / `false`|親が動いたときだけ押す|

|`min_owner_position_delta_pixels`|`float` / `0.01`|1フレームでの親の実移動量がこれ未満なら押さない|

|`min_owner_real_speed`|`float` / `0.1`|親の実速度がこれ未満なら押さない|

|`use_force`|`bool` / `true`|力方式（毎フレーム用途はforce推奨）|

|`push_strength`|`float` / `100.0`|押す強さ係数|

|`min_push_force`|`float` / `50.0`|最小の押し力|

|`max_force`|`float` / `200000.0`|力の上限（use\_force=trueの場合）|

|`max_impulse`|`float` / `5000.0`|インパルスの上限（use\_force=falseの場合）|

|`consider_mass`|`bool` / `true`|質量を考慮する|

|`mass_influence`|`float` / `0.5`|質量の影響度（0.0-1.0）|

|`normal_direction_weight`|`float` / `0.7`|衝突法線方向の力の重み（0.0-1.0）|

|`movement_direction_weight`|`float` / `0.3`|移動方向の力の重み（0.0-1.0）|

|`wake_rigid_bodies`|`bool` / `true`|RigidBody2Dを起こす|

* * *

## 7. 使用例

### 7-1. 基本的なチェーン作成

1. `Node2D`をシーンに配置（`ChainRoot`）

2. その子として`RigidBody2D`を複数配置（`Link1`, `Link2`, `Link3`…）

3. `ChainJointSetupTool`を`ChainRoot`の親に配置

4. `target_parent`に`ChainRoot`を設定

5. `_setup_button`にチェックを入れる

6. Jointとsegノードが自動生成される

### 7-2. ジョイントの自動切断

1. `BreakableJointMonitor2D`をシーンに配置

2. `search_root`にチェーンのルートを設定

3. `break_relative_speed=500.0`などで破断条件を設定

4. 実行すると、条件を満たしたジョイントが自動で切断される

### 7-3. チェーンの可視化

1. `ChainPathBinder2D`をシーンに配置

2. `auto_detect_mode=true`に設定

3. `search_root`にチェーンのルートを設定

4. `joint_monitor`に`BreakableJointMonitor2D`を設定

5. `PathRibbonMesh2D`を配置し、`path_nodes`に`ChainPathBinder2D`の`output_paths`を設定

6. 実行すると、チェーンの形状が可視化され、切断時に自動で分割される

### 7-4. CharacterBody2Dで箱を押す

1. `CharacterBody2D`の子として`Node`を追加

2. `rigid_body_pusher.gd`をアタッチ

3. `push_strength=100.0`などで押す強さを調整

4. 実行すると、`CharacterBody2D`が接触した`RigidBody2D`を自然に押し出します

### 7-5. Area2D範囲内のジョイントを一括切断

1. 切断範囲となる`Area2D`を用意し、子に`CollisionShape2D`を追加

2. 任意のノードに`area_joint_breaker.gd`をアタッチ

3. `target_area`に上記の`Area2D`を設定

4. `monitor`に`BreakableJointMonitor2D`を設定（任意）

5. `break_joints_in_target_area()`を呼ぶ

6. 範囲内のジョイントが一括で切断されます

* * *

以上が、ジョイント・チェーン・ロープシステムの使用ガイドです。
