物理链条/绳索的设置方法
本指南详细介绍了如何设置物理链条(绳索或铁链)。
目录
1. 理解基本链条结构
链条的组成元素
链条由以下元素组成:
- RigidBody2D: 链条的每个链节(段)
- GrooveJoint2D 或 PinJoint2D: 链节之间的连接
- seg节点: 每个RigidBody2D内的连接点标记(Node2D)
- BreakableJointMonitor2D: 监控关节断裂
- ChainPathBinder2D: 将链条形状可视化为Path2D
- PathRibbonMesh2D: 使用 Ribbon Mesh 绘制 Path2D
节点结构示例
ChainRoot (Node2D)
├── RigidBody2D1
│ ├── CollisionShape2D
│ ├── Sprite2D
│ ├── seg1 (Node2D, position: 0, -10)
│ └── seg2 (Node2D, position: 0, 10)
├── RigidBody2D2
│ ├── GrooveJoint2D (连接到 RigidBody2D1)
│ ├── CollisionShape2D
│ ├── Sprite2D
│ ├── seg1
│ └── seg2
├── RigidBody2D3
│ └── ...
└── ...
2. 手动设置
2-1. 创建基本链条
步骤1: 创建链条根节点
- 在场景中放置一个
Node2D(例如:ChainRoot) - 此节点将作为链条的父节点
步骤2: 放置 RigidBody2D
- 在
ChainRoot下放置多个RigidBody2D - 为每个 RigidBody2D 命名(例如:
Link1,Link2,Link3…) - 设置每个 RigidBody2D 的位置(如果是垂直排列:根据每个链节的长度,以适当的间隔放置)
步骤3: 添加 CollisionShape2D 和 Sprite2D
- 将
CollisionShape2D添加为每个 RigidBody2D 的子节点 - 将
Shape设置为RectangleShape2D或CapsuleShape2D - 将
Sprite2D添加为每个 RigidBody2D 的子节点(可选) - 设置纹理
步骤4: 创建 seg 节点
- 将
Node2D添加为每个 RigidBody2D 的子节点 - 将第一个节点命名为
seg1,并将position设置为(0, -10) - 将第二个节点命名为
seg2,并将position设置为(0, 10)- 这些是连接点的标记
seg1表示上方连接点,seg2表示下方连接点
步骤5: 放置 GrooveJoint2D
- 将
GrooveJoint2D添加为第二个及后续每个 RigidBody2D 的子节点 - 每个 GrooveJoint2D 的设置:
position:(0, -16)(靠近 RigidBody2D 的顶部)node_a: 到前一个 RigidBody2D 的路径(例如:../../RigidBody2D)node_b:..(自身的 RigidBody2D)bias:0.9(硬连接)或0.2(软连接)length:8.0(沟槽长度)initial_offset:1.0或2.0(初始偏移量)
步骤6: 固定首尾(可选)
-
如果固定头部:
- 放置一个
StaticBody2D - 在其下添加一个
GrooveJoint2D node_a:..(StaticBody2D 自身)node_b: 到头部 RigidBody2D 的路径(例如:../../Node2D/RigidBody2D)
- 放置一个
-
如果固定尾部:
- 同样放置
StaticBody2D和GrooveJoint2D
- 同样放置
完成示例
ChainRoot (Node2D)
├── RigidBody2D1
│ ├── CollisionShape2D
│ ├── Sprite2D
│ ├── seg1 (Node2D, position: 0, -10)
│ └── seg2 (Node2D, position: 0, 10)
├── RigidBody2D2
│ ├── GrooveJoint2D
│ │ ├── node_a: ../../RigidBody2D1
│ │ ├── node_b: ..
│ │ ├── position: (0, -16)
│ │ ├── bias: 0.9
│ │ ├── length: 8.0
│ │ └── initial_offset: 1.0
│ ├── CollisionShape2D
│ ├── Sprite2D
│ ├── seg1
│ └── seg2
└── ...
3. 自动设置(使用ChainJointSetupTool)
3-1. 基本自动设置
步骤1: 创建链条根节点
- 在场景中放置一个
Node2D(例如:ChainRoot)
步骤2: 放置 RigidBody2D
- 在
ChainRoot下放置多个RigidBody2D - 为每个 RigidBody2D 添加
CollisionShape2D和Sprite2D - 适当设置位置
步骤3: 放置 ChainJointSetupTool
- 在
ChainRoot的父节点(或任意位置)放置一个Node - 附加
chain_setup_tool.gd脚本 - 在 Inspector 中设置以下内容:
target_parent: 指向ChainRoot的 NodePathjoint_type:GROOVE(推荐)或PINauto_create_seg_nodes:true(自动生成 seg 节点)auto_setup_all:true(自动设置所有系统)
步骤4: 执行设置
- 在 Inspector 中勾选
_setup_button - 或者,从脚本调用
setup_chain() - 在编辑器中会自动执行
自动生成的内容
- 如果
auto_setup_all=true:- 为每个 RigidBody2D 生成
seg1和seg2节点 - 为每个 RigidBody2D 生成
GrooveJoint2D(或PinJoint2D) - 生成
BreakableJointMonitor2D - 生成
ChainPathBinder2D - 生成
Path2D - 生成
PathRibbonMesh2D
- 为每个 RigidBody2D 生成
3-2. 详细设置
GrooveJoint2D 的设置
| 属性 | 说明 | 推荐值 |
|---|---|---|
groove_length |
沟槽长度 | 8.0 |
groove_initial_offset |
初始偏移量 | 1.0 或 2.0 |
groove_joint_position_local |
关节位置 | (0, -16) |
bias |
连接硬度 | 0.9(硬)或 0.2(软) |
disable_collision |
禁用碰撞 | false(通常启用) |
seg 节点的设置
| 属性 | 说明 | 推荐值 |
|---|---|---|
auto_create_seg_nodes |
自动生成 seg 节点 | true |
seg_node_prefix |
seg 节点前缀 | “seg” |
seg1_position_local |
seg1 位置 | (0, -10) |
seg2_position_local |
seg2 位置 | (0, 10) |
自动设置的设置
| 属性 | 说明 | 推荐值 |
|---|---|---|
auto_setup_all |
自动设置所有系统 | true |
auto_connect_breakable_monitor |
自动连接到 BreakableJointMonitor2D | true |
auto_setup_chain_binder |
自动设置 ChainPathBinder2D | true |
setup_on_ready |
运行时自动设置 | false(通常手动执行) |
4. 可视化系统设置
4-1. ChainPathBinder2D 的设置
步骤1: 放置 ChainPathBinder2D
- 在链条根节点(或其父节点)放置一个
Node - 附加
chain_path_binder.gd脚本
步骤2: 基本设置
- 设置
auto_detect_mode:true(自动检测模式) search_root: 指向链条根节点的 NodePath(例如:../ChainRoot)output_paths: 添加指向Path2D的 NodePath(如果为空则自动生成)
步骤3: 可选设置
| 属性 | 说明 | 推荐值 |
|---|---|---|
auto_update |
自动更新 | true |
update_in_physics |
在物理帧中更新 | true |
enable_smooth_handles |
使 Curve2D 平滑 | true |
smooth_handle_strength_px |
手柄强度 | 2.0~12.0 |
resample_spacing_px |
以固定间隔重新采样点列 | 0.0(禁用)或 8.0 |
4-2. PathRibbonMesh2D 的设置
步骤1: 放置 PathRibbonMesh2D
- 在链条根节点(或其父节点)放置一个
Node2D - 附加
path_ribbon_mesh_2d.gd脚本
步骤2: 基本设置
path_nodes: 添加指向Path2D的 NodePath(例如:[NodePath("../Path2D")])width: 绳索宽度(例如:20.0)ribbon_texture: 设置纹理(例如:chain.png、rope.png)
步骤3: 可选设置
| 属性 | 说明 | 推荐值 |
|---|---|---|
width_curve |
宽度曲线 | Curve 资源 |
upper_width_curve |
上部宽度曲线 | Curve 资源 |
lower_width_curve |
下部宽度曲线 | Curve 资源 |
thickness_domain_mode |
厚度域模式 | 0(常规) |
4-3. 创建 Path2D
自动生成的情况
- 如果
ChainPathBinder2D的output_paths为空,则会自动生成Path2D
手动创建的情况
- 在链条根节点(或其父节点)放置一个
Path2D Curve2D会自动创建- 将其添加到
ChainPathBinder2D的output_paths中
5. 关节监控设置
5-1. BreakableJointMonitor2D 的设置
步骤1: 放置 BreakableJointMonitor2D
- 在链条根节点(或其父节点)放置一个
Node - 附加
breakable_joint_monitor_2d.gd脚本
步骤2: 基本设置
search_root: 指向监控目标的根节点的 NodePath(例如:../ChainRoot)auto_collect_on_ready:true(启动时自动收集)
步骤3: 设置断裂条件
| 属性 | 说明 | 推荐值 |
|---|---|---|
break_relative_speed |
相对速度超过此值时断裂 | 0.0(禁用)或 500.0 |
break_angle_degrees |
超过此角度并持续一定时间后断裂 | 0.0(禁用)或 80.0 |
break_angle_duration_sec |
角度超过持续此秒数后断裂 | 0.5 |
break_stretch_ratio |
相对于初始距离的拉伸率超过此值时断裂 | 0.0(禁用)或 1.5 |
use_break_delay_frames |
将 BreakDelay 视为帧数 | true |
break_delay_frames |
exceeded 连续此帧数后断裂 | 1~10 |
5-2. 单独设置(JointBreakParams)
步骤1: 创建 JointBreakParams 资源
- 在项目面板中右键单击 →
新建资源 - 选择
JointBreakParams - 命名并保存(例如:
joint_params_weak.tres)
步骤2: 填写单独设置
joint_path: 指向目标关节的 NodePath(例如:../ChainRoot/RigidBody2D2/GrooveJoint2D)- 设置单独的断裂参数:
-1.0表示使用全局设置0.0及以上表示使用单独设置
步骤3: 添加到 BreakableJointMonitor2D
- 将创建的资源添加到
BreakableJointMonitor2D的joint_params中
示例
BreakableJointMonitor2D
├── search_root: ../ChainRoot
├── break_angle_degrees: 80.0(全局设置)
└── joint_params:
└── JointBreakParams
├── joint_path: ../ChainRoot/RigidBody2D2/GrooveJoint2D
└── groove_break_angle_degrees: 90.0(单独设置,更敏感)
6. 常见设置模式
模式1: 柔软的绳索
GrooveJoint2D 的设置
bias: 0.2(柔软)length: 8.0initial_offset: 2.0
RigidBody2D 的设置
linear_damp: 10.0(强阻尼)angular_damp: 10.0
BreakableJointMonitor2D 的设置
break_angle_degrees: 80.0break_angle_duration_sec: 0.3(短时间内切断)
用途: 柔软摆动的绳索,相对容易切断
模式2: 坚硬的链条
GrooveJoint2D 的设置
bias: 0.9(坚硬)length: 8.0initial_offset: 1.0
RigidBody2D 的设置
mass: 3.0(常规链节)mass: 8.0(重物部分,例如:球体或配重)
BreakableJointMonitor2D 的设置
break_angle_degrees: 0.0(禁用,不断裂)- 或者仅在单独设置中允许部分断裂
用途: 坚硬链条,几乎不断裂,悬挂重物
模式3: 固定链条
头部固定
- 放置
StaticBody2D - 使用
GrooveJoint2D连接到头部的 RigidBody2D
尾部固定
- 放置
StaticBody2D - 使用
GrooveJoint2D连接到尾部的 RigidBody2D
用途: 桥梁锁链,固定绳索
模式4: 分支链条
结构
- 通过一个 RigidBody2D 连接多个链条
- 在连接点的 RigidBody2D 上放置多个 GrooveJoint2D
示例
Chain1
└── RigidBody2D6
└── GrooveJoint2D (Chain1 内部)
└── GrooveJoint2D2 (连接到 Chain2/RigidBody2D7)
用途: 连接多个链条,Y型绳索
7. 故障排除
问题1: 链条不移动
原因和对策
| 原因 | 对策 |
|---|---|
RigidBody2D 的 freeze=true |
设置为 freeze=false |
RigidBody2D 的 mass 为 0 |
将 mass 设置为 1.0 以上 |
GrooveJoint2D 的 node_a 不正确 |
检查 NodePath,修正相对路径 |
GrooveJoint2D 的 node_b 不正确 |
将 node_b 设置为 .. |
问题2: 链条断裂过多
原因和对策
| 原因 | 对策 |
|---|---|
break_angle_degrees 太小 |
增大数值(例如:80.0 → 120.0) |
break_delay_frames 太小 |
增大数值(例如:1 → 10) |
break_relative_speed 太小 |
增大数值,或设置为 0.0(禁用) |
bias 太小(过于柔软) |
增大数值(例如:0.2 → 0.9) |
问题3: 链条不断裂
原因和对策
| 原因 | 对策 |
|---|---|
| 所有断裂条件均为 0.0(禁用) | 将 break_angle_degrees 等设置为有效值 |
BreakableJointMonitor2D 的 search_root 不正确 |
设置为正确的 NodePath |
关节包含在 exclude_groups 中 |
检查 exclude_groups |
auto_collect_on_ready=false |
设置为 true,或手动调用 collect_joints() |
问题4: 路径未显示
原因和对策
| 原因 | 对策 |
|---|---|
ChainPathBinder2D 的 auto_update=false |
设置为 true |
output_paths 为空 |
添加 Path2D,或等待自动生成 |
search_root 不正确 |
设置为正确的 NodePath |
| 不存在 seg 节点 | 设置为 auto_create_seg_nodes=true,或手动创建 seg 节点 |
auto_detect_mode=false 且 chain_parts 为空 |
设置为 auto_detect_mode=true,或向 chain_parts 添加 ChainPartResource |
问题5: 设置工具不工作
原因和对策
| 原因 | 对策 |
|---|---|
target_parent 下少于 2 个 RigidBody2D |
放置 2 个以上的 RigidBody2D |
target_parent 未设置且没有父节点 |
明确设置 target_parent |
| 未在编辑器中运行 | 在编辑器中勾选 _setup_button |
| 未删除现有的 Joint | 手动删除现有 Joint 后重新执行 |
问题6: 链条过重(性能问题)
原因和对策
| 原因 | 对策 |
|---|---|
| RigidBody2D 数量过多 | 减少链节数量 |
continuous_cd 过大 |
将 continuous_cd 设置为 0 或 1 |
PathRibbonMesh2D 更新负担重 |
将 auto_update=false 进行手动更新,或降低更新频率 |
BreakableJointMonitor2D 每帧重新收集 |
设置为 recollect_every_frame=false |
8. 设置检查清单
基本链条
- 放置
Node2D作为根节点 - 放置 2 个以上的
RigidBody2D - 为每个 RigidBody2D 添加
CollisionShape2D - 为每个 RigidBody2D 添加
seg1和seg2节点 - 为第二个及后续的 RigidBody2D 添加
GrooveJoint2D - 正确设置每个 GrooveJoint2D 的
node_a和node_b
可视化系统
- 放置
ChainPathBinder2D - 设置为
auto_detect_mode=true - 设置
search_root - 创建
Path2D(或等待自动生成) - 放置
PathRibbonMesh2D - 在
path_nodes中设置Path2D - 设置纹理
关节监控
- 放置
BreakableJointMonitor2D - 设置
search_root - 设置断裂条件(例如:
break_angle_degrees) - 设置为
auto_collect_on_ready=true
自动设置(使用ChainJointSetupTool)
- 放置
ChainJointSetupTool - 设置
target_parent - 设置为
auto_setup_all=true - 勾选
_setup_button,或调用setup_chain()
9. 实例:创建柔软绳索
步骤1: 创建根节点
- 在场景中放置合适的根节点(例如:
Area2D、Node2D等) - 在其下放置用于链条的
Node2D
步骤2: 放置 RigidBody2D
-
在用于链条的
Node2D下放置所需数量的RigidBody2D -
设置每个 RigidBody2D 的位置:
- 垂直排列时:根据每个链节的长度,以适当的间隔放置
- 水平排列时:调整
position.x - 链节之间的间隔根据每个链节的大小和连接方式决定
-
为每个 RigidBody2D 设置:
linear_damp: 10.0(强阻尼)angular_damp: 10.0
步骤3: CollisionShape2D 和 seg 节点
- 为每个 RigidBody2D 添加
CollisionShape2D - 根据用途选择形状(
RectangleShape2D、CapsuleShape2D等) - 为每个 RigidBody2D 添加
seg1(position: 0, -10)和seg2(position: 0, 10)
步骤4: 放置 GrooveJoint2D
- 将
GrooveJoint2D添加为第二个及后续每个 RigidBody2D 的子节点:position: (0, -16)(靠近 RigidBody2D 的顶部)node_a: 到前一个 RigidBody2D 的相对路径node_b: ..(自身的 RigidBody2D)bias: 0.2(柔软连接)length: 8.0initial_offset: 2.0
步骤5: 固定用 StaticBody2D(可选)
-
如果固定头部:在根节点下放置
StaticBody2D -
在其下添加
GrooveJoint2D:node_a: ..(StaticBody2D 自身)node_b: 到头部 RigidBody2D 的相对路径bias: 0.2length: 8.0initial_offset: 2.0
-
固定尾部时也进行同样的设置
步骤6: 可视化系统
-
在根节点下放置
Path2D -
在根节点下放置
Node并附加chain_path_binder.gd:auto_detect_mode: truesearch_root: 指向用于链条的Node2D的相对路径output_paths: 指向Path2D的相对路径enable_smooth_handles: truesmooth_handle_strength_px: 2.0
-
在根节点下放置
Node2D并附加path_ribbon_mesh_2d.gd:path_nodes: 指向Path2D的相对路径width: 20.0ribbon_texture: 设置合适的纹理
步骤7: 关节监控
-
在根节点下放置
Node并附加breakable_joint_monitor_2d.gd:search_root: 指向用于链条的Node2D的相对路径break_angle_degrees: 80.0break_angle_duration_sec: 0.3use_break_delay_frames: falsebreak_delay_frames: 3
-
设置
ChainPathBinder2D的joint_monitor(可选)
10. 实例:创建坚硬链条和配重
步骤1: 创建链条
- 在场景中放置合适的根节点
- 在其下放置用于链条的
Node2D
步骤2: 放置 RigidBody2D
-
在用于链条的
Node2D下放置所需数量的RigidBody2D -
设置每个 RigidBody2D 的位置:
- 垂直排列时:根据每个链节的长度,以适当的间隔放置
- 头部的 RigidBody2D 也可以设置为
freeze: true(固定)
-
对于作为配重的 RigidBody2D,设置较大的
mass(例如:mass: 8.0) -
为每个 RigidBody2D 添加
seg1和seg2
步骤3: 放置 GrooveJoint2D
- 将
GrooveJoint2D添加为第二个及后续每个 RigidBody2D 的子节点:position: (0, -16)node_a: 到前一个 RigidBody2D 的相对路径node_b: ..bias: 0.9(坚硬连接)length: 8.0initial_offset: 1.0
步骤4: 可视化系统
- 在用于链条的
Node2D下放置Path2D - 在用于链条的
Node2D下放置Node并附加chain_path_binder.gd - 在用于链条的
Node2D下放置Node2D并附加path_ribbon_mesh_2d.gd(设置合适的纹理)
步骤5: 关节监控(含单独设置)
- 在用于链条的
Node2D下放置Node并附加breakable_joint_monitor_2d.gd - 根据需要创建
JointBreakParams资源:joint_path: 指向目标关节的相对路径groove_break_angle_degrees: 90.0(单独设置)groove_break_angle_duration_sec: 0.5
- 添加到
BreakableJointMonitor2D的joint_params中
步骤6: 创建分支链条(可选)
- 放置另一个用于链条的
Node2D - 同样放置所需数量的 RigidBody2D
- 在连接点的 RigidBody2D 上添加两个 GrooveJoint2D:
- 第一个:连接到自身链条内部
- 第二个:连接到另一个链条的 RigidBody2D
以上就是链条的设置指南。