更新自研插件
This commit is contained in:
@@ -76,7 +76,7 @@ Chair_PC_04 ← 模型实例,仍然引用 res://.../chair.
|
||||
| 设置 | 默认 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `auto_add_collision` | `true` | 自动处理拖进场景的模型 |
|
||||
| `collision_shape` | `Convex Hull` | `Convex Hull` / `Trimesh` / `Box` / `Sphere` / `Capsule` / `Cylinder` |
|
||||
| `collision_shape` | **`Trimesh`** | `Convex Hull` / `Trimesh` / `Box` / `Sphere` / `Capsule` / `Cylinder` |
|
||||
| `collision_body` | `StaticBody3D` | `StaticBody3D` / `RigidBody3D` / `Area3D` / `CharacterBody3D` |
|
||||
| `skip_meshes_with_collision` | `false` | 跳过已经位于物理体下的网格(模型自带碰撞时打开) |
|
||||
| `collision_layer` / `collision_mask` | `1` | 碰撞层 / 掩码 |
|
||||
@@ -85,9 +85,33 @@ Chair_PC_04 ← 模型实例,仍然引用 res://.../chair.
|
||||
|
||||
### 形状怎么选
|
||||
|
||||
- **Convex Hull**(默认)—— 每个网格一个凸包。性能好,可用于会移动的物体;凹形会被"填平"。
|
||||
- **Trimesh** —— 逐面精确,不做凸包简化。**只能用在静态物体上**,顶点多时开销较大。
|
||||
- **Box / Sphere / Capsule / Cylinder** —— 最省性能。这几种形状会**按每个网格的实际位置自动偏移居中**。
|
||||
| 形状 | 精度 | 代价 |
|
||||
| --- | --- | --- |
|
||||
| **Trimesh**(默认) | 逐三角面精确,索引一个不差,不做任何简化 | 顶点多时开销大;**只能用于静态物体** |
|
||||
| **Convex Hull** | 凸包,凹形被"填平"(椅子坐垫下方、脚轮之间会变实心) | 可用于移动物体,开销可控 |
|
||||
| **Box / Sphere / Capsule / Cylinder** | 单个包围体,最粗 | 最省性能 |
|
||||
|
||||
**默认给 Trimesh,是因为静态场景物件本来就该用最精确的形状。** 精度不足的典型症状是"碰撞比模型胖"——那是凸包把凹陷填平了,换成 Trimesh 即可。
|
||||
|
||||
这几种基础形状会**按每个网格的实际位置自动偏移居中**,不会全部堆在原点。
|
||||
|
||||
> **Trimesh 与移动刚体不兼容。** `ConcavePolygonShape3D` 是静态专用形状,Godot 不会用它驱动物理模拟,而且**失效是静默的**。为避免踩坑,构建时会自动降级为凸包并打印告警 —— 需要会移动的碰撞体时,请把 `collision_shape` 换成凸包或基础形状。
|
||||
|
||||
### 怎么确认当前用的是哪种形状
|
||||
|
||||
在场景里选中 `CollisionBody` 下的 `CollisionShape3D`,看检视面板里的 **Shape** 属性:
|
||||
|
||||
| 看到 | 说明 |
|
||||
| --- | --- |
|
||||
| `ConcavePolygonShape3D` | **Trimesh** —— 逐面精确 |
|
||||
| `ConvexPolygonShape3D` | **凸包** —— 凹形已被填平 |
|
||||
| `BoxShape3D` / `SphereShape3D` / … | 基础形状 |
|
||||
|
||||
用凸包时,"碰撞比模型胖"是必然的,不是精度不足:凸包**无法表达凹形**,增加网格密度也不会改善。
|
||||
|
||||
### 升级提示
|
||||
|
||||
`collision_shape` 的默认值在 2.0 内定稿时从 `Convex Hull` 改成了 `Trimesh`。如果你之前跑过更早的版本,启动时插件会检测到"这个值仍是旧默认值"并自动迁移,同时打印一条日志。**已经生成的碰撞体不会跟着变** —— 要重新执行一次「移除选中模型的碰撞」→「给选中模型加碰撞」。
|
||||
|
||||
### 模型自带碰撞时
|
||||
|
||||
@@ -120,7 +144,7 @@ MeshColliderLib.remove_collision(model_instance) # bool
|
||||
|
||||
---
|
||||
|
||||
## 两个必须知道的限制
|
||||
## 三个必须知道的限制
|
||||
|
||||
**1. 碰撞体不会跟着动画变形。**
|
||||
碰撞是按模型**静止姿态的几何**烘焙的,不是按骨骼运行时变形后的形状。这是静态烘焙的固有性质,游戏里通常也是用胶囊/凸包代替。
|
||||
@@ -132,12 +156,18 @@ MeshColliderLib.remove_collision(model_instance) # bool
|
||||
|
||||
> 这一条正是 1.0 本地化方案想解决的问题,但它的代价(1–3× 存储 + 静默过期)不值得。原生 `-col` 方案没有这个问题,因为它把碰撞生成放在导入流程里 —— 这也是我建议优先考虑它的原因。
|
||||
|
||||
**3. 模型的世界尺寸太小,物理会不准。**
|
||||
Godot 的物理按"1 单位 = 1 米"调参。如果模型导入后只有几厘米大(某些 FBX 会这样),碰撞虽然几何正确,但**碰撞检测会变得不可靠** —— 表现为穿透、抖动、站在物体上却下滑。
|
||||
|
||||
这不是碰撞体的问题,改形状类型也没用。正确做法是**把模型调制到真实比例**:在导入设置里调 `Scale`,或给模型的父节点设 `scale`,让它变成真实尺寸(一把椅子约 1 米、一个角色约 1.7 米)。
|
||||
|
||||
---
|
||||
|
||||
## 已知取舍
|
||||
|
||||
- **检测靠轮询**(0.4 秒一次)。Godot 没有暴露"模型被拖进来"的信号,这是唯一可靠的做法。
|
||||
- **已验证的 API 兼容性**:本插件只使用在 Godot 4.7.2 上实测过的 API。踩过的坑包括 `MeshInstance3D.skeleton` 是 `NodePath` 而不是 `Skeleton3D`、`ClassDB.can_instantiate()` 才是判断节点能否容纳子节点的正确方法、以及 GDScript 不允许 `const` 字典的值引用其他常量。
|
||||
- **变换在注入前一次性快照**。所有网格的世界变换在**模型确实处于场景树中**时解析好,再交给构建函数。这有两个原因:刚体是**故意游离**的(由撤销系统负责挂载),而 `global_transform` 在树外会打印 `Condition "!is_inside_tree()" is true` 并返回单位阵;更重要的是,依赖"读取瞬间节点仍在树里"会让碰撞在边界情况下静默烘焙到原点。快照把这件事变成确定的,缺了变换的网格会被跳过而不是猜一个。
|
||||
- **已验证的 API 兼容性**:本插件只使用在 Godot 4.7.2 上实测过的 API。踩过的坑包括 `MeshInstance3D.skeleton` 是 `NodePath` 而不是 `Skeleton3D`、`ClassDB.can_instantiate()` 才是判断节点能否容纳子节点的正确方法、以及 GDScript 不允许 `const` 字典的值引用其他常量(所以库里的枚举默认值写成字面量索引)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user