可拖拽判断(PickupItem 标记)
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
# 2026-10-12
|
||||
|
||||
## 可拖拽判断(PickupItem 标记)
|
||||
|
||||
**需求**:`scripts/item.gd` 提供 `can_pickup`,只有为 true 时才能拖拽。
|
||||
|
||||
**item.gd 本次改动**:加了 `class_name PickupItem` 和说明注释,功能不变。
|
||||
```gdscript
|
||||
class_name PickupItem
|
||||
extends Node
|
||||
@export var can_pickup: bool = true
|
||||
```
|
||||
|
||||
### ⚠ 关键发现:脚本挂载位置 ≠ 射线打中的节点
|
||||
|
||||
用户在 `world/main.tscn` 第 155 行把 item.gd 挂在了 `SM_Bottle_12` 上,但那个节点**不是刚体**。
|
||||
实例来源 `res://assets/Furniture_FREE-af040129/SM_Bottle_1.glb`,实际结构是:
|
||||
|
||||
```
|
||||
SM_Bottle_12 (Node3D) ← item.gd 挂在这一层(glb 实例的根)
|
||||
└── SM_Bottle_1 (RigidBody3D) ← 射线实际打中的是这一层
|
||||
├── SM_Bottle_1 (MeshInstance3D)
|
||||
└── CollisionShape3D
|
||||
```
|
||||
|
||||
**实测确认**:glb 内部节点的 `owner` 指向实例根(`SM_Bottle_1.owner == SM_Bottle_12`),
|
||||
再往上为 null。所以「沿 owner 链向上找标记」正好一步命中。
|
||||
|
||||
### 实现(`player_pickup.gd`)
|
||||
|
||||
- 新增 `@export var allow_unmarked: bool = false`
|
||||
- **false(默认)= 白名单**:只有挂了 `PickupItem` 且 `can_pickup=true` 的才拖得动
|
||||
- true = 黑名单:没挂标记的默认可拖,只有显式设 false 的不能拖
|
||||
- 新增 `can_grab(collider) -> bool`:先判 `is RigidBody3D`,再查标记
|
||||
- 新增 `_find_item_marker(body)`:顺序 **刚体自身 → 直接子节点 → owner 链向上**
|
||||
- 向上时**只查节点自身、不查子节点** —— 否则走到 World 层会遍历几百个子节点,而这是每物理帧都要跑的
|
||||
- `_update_interact_state()` 的 hovering 判定改用 `can_grab()`
|
||||
- `_grab()` 里再判一次(悬停状态来自上一物理帧,其间 can_pickup 可能已被改掉)
|
||||
|
||||
### 实测验证(headless,全部符合预期)
|
||||
```
|
||||
can_grab(SM_Bottle_1 RigidBody3D) = true ✓
|
||||
can_grab(SM_Bottle_12 Node3D) = false ✓(不是刚体)
|
||||
can_grab(Can2 内部刚体) = false ✓(严格/白名单模式)
|
||||
allow_unmarked=true 后 Can2 = true ✓
|
||||
```
|
||||
|
||||
### ⚠ 副作用(需告知用户)
|
||||
默认白名单模式下,场景里**所有没挂 item.gd 的刚体都拖不动了**
|
||||
(`Can2`、饭盒、水果等)。要么逐个挂标记,要么把 `allow_unmarked` 勾上。
|
||||
|
||||
### MCP 备注
|
||||
4 次 `script_patch` 均返回 `replacements: 1` 但伴随 `gdscript_reload_failed (code 43)`
|
||||
假报错(`fallback_line: true`)—— 与 10-10 记录的是同一现象。
|
||||
离线 `--check-only` 两个脚本均通过;`PickupItem` 已进 `global_script_class_cache.cfg`。
|
||||
Reference in New Issue
Block a user