2026-10-16
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
# 2026-10-16
|
||||
|
||||
## 修复:第一人称相机高达 1.16 m(玩家缩放被静默抹掉)
|
||||
|
||||
- 现象:进游戏后第一人称视角像一米多高看得见 woman 的胸口;DebugPanel 显示
|
||||
「相机高度 1.161 m / 5.80 身高」。
|
||||
- 根因:`world/main.gd` 的 `_create_player()` 里写 `player.global_position = ...`,而该节点
|
||||
**此时还没入树**(MultiplayerSpawner 之后才 add_child)。`Node3D.get_global_transform()`
|
||||
在未入树时 `ERR_FAIL` 返回**单位矩阵**,`set_global_transform()` 顺势把 Player 根节点的
|
||||
basis 换成单位阵 → **player.tscn 那层 0.096096 缩放被抹掉**。
|
||||
- 无头探针对照(复现两种写法,同一份 player.tscn):
|
||||
|
||||
| 写法 | Player.global_scale | 模型世界高 | 相机相对脚底 |
|
||||
|---|---|---|---|
|
||||
| 旧 `global_position` | 1.0 | 1.561 m | **1.1610 m** |
|
||||
| 新 `position` | 0.096096 | 0.150 m | **0.1116 m** |
|
||||
|
||||
旧写法的 1.1610 m 与游戏内面板的 1.161 m 逐位吻合;控制台每个玩家还会刷一条
|
||||
`ERROR: Condition "!is_inside_tree()" is true.`。
|
||||
- 修复:`player.position = player_spawn_pos.position`(Main 与 PlayerSpawnPos 同级、Main 无变换,
|
||||
局部坐标即世界坐标)。`--check-only` 通过。
|
||||
- 离屏渲染三张对照图(woman 1.703 m 站位旁):`probe_fix_A.png`(同框,旧写法巨鼠几乎挡住
|
||||
woman)、`probe_fix_B.png`(woman 脚边,修复后 15 cm 小鼠)、`probe_fix_C.png`(修复后
|
||||
第一人称,面板读数 0.112 m / 0.56 身高)。
|
||||
- 附带确认:`InteractionRay` 世界长度在两种状态下都是 0.25 m(`Camera3D` 全局缩放恒为 1.0),
|
||||
所以修缩放不影响拾取距离。
|
||||
@@ -1,7 +1,9 @@
|
||||
# agame 项目长期笔记
|
||||
|
||||
Godot 4.7.2(Forward+,Jolt Physics,D3D12)。编辑器位于
|
||||
`D:\_yvmou\Godot\Godot_v4.7.2-stable_win64.exe\Godot_v4.7.2-stable_win64.exe`(另有 mono 版)。
|
||||
Godot 4.7.2(Forward+,Jolt Physics,D3D12)。**可用编辑器(2026-10-16 实测):
|
||||
`E:\Godot_v4.7.2-stable_mono_win64\Godot_v4.7.2-stable_mono_win64\Godot_v4.7.2-stable_mono_win64.exe`
|
||||
(mono 版;同目录另有 `..._console.exe`)。**
|
||||
⚠️ 旧记录里的 `D:\_yvmou\Godot\...` **已失效 —— D 盘根本没有 `_yvmou` 目录**,别再照抄。
|
||||
|
||||
## 代码约定
|
||||
|
||||
@@ -153,3 +155,58 @@ Godot 4 的 `fragment()` 里 `NORMAL` / `TANGENT` / `BINORMAL` 都处于**视图
|
||||
正确做法(若将来真要开法线贴图):只写 `NORMAL_MAP = 原始切线空间值` +
|
||||
`NORMAL_MAP_DEPTH`,让引擎合成;不要自己写 `NORMAL`,也不要预先做 `*2-1` 重映射
|
||||
(引擎自己做,蓝通道由引擎重建)。
|
||||
|
||||
## 玩家尺寸 / 相机高度(2026-10-16 查证)
|
||||
|
||||
全在 `character/player/player.tscn`,「大小」是三层缩放叠加:
|
||||
|
||||
1. **`Player` 根节点整体 scale = 0.096096**(第 38 行)—— 主开关,模型+碰撞+相机一起缩放。
|
||||
2. **`Body/mouse` 模型自身 scale = 0.18240134**(第 87 行,X 为负 = 180° 翻转朝向);
|
||||
实际模型缩放 = 0.096096 × 0.1824 ≈ 0.0175。只想改模型不动碰撞就改这里。
|
||||
3. **碰撞胶囊(局部)** `CapsuleShape3D: radius 0.54541016 / height 1.4063476`(第 33-35 行),
|
||||
`Collision` 节点 y = 0.7031738(= height/2,贴地)。
|
||||
|
||||
- ⚠️ **相机高度与缩放联动,改一个必须同步改另一个**:站立视线高 = `CameraRig.position.y`
|
||||
(当前 1.6,第 46 行),世界高度 = 1.6 × 0.096096 ≈ **0.154 m**;而 `Camera` 节点自身
|
||||
scale = **10.4062605 = 1/0.096096**(第 49 行),唯一作用就是**抵消父级的 0.096 缩放**,
|
||||
让相机在世界空间回到 1:1(否则 near/FOV 异常)。动了 `Player` 的 scale,这个倒数必须一起改。
|
||||
- **无头探针实测(2026-10-16,真实实例化 `player.tscn`)**:`Player.global_scale = 0.096096`;
|
||||
模型 `Body/mouse.global_scale = 0.017528`;**视觉包围盒 = 0.158 × 0.150 × 0.135 m(约 15cm)**;
|
||||
胶囊世界尺寸 = 半径 5.24cm / 总高 13.5cm;**相机在脚底上方 0.1116 m**。
|
||||
⚠️ 相机净高度 ≠ 1.6 × 0.096 = 0.154 —— `Camera` 自身局部还带 `y = −0.439`,
|
||||
实际 = (1.6 − 0.439) × 0.096096 ≈ **0.1116 m**(`DebugPanel._camera_height()` 用
|
||||
`camera.global_position.y − player.global_position.y` 读数就是这个值)。
|
||||
- ⚠️⚠️ **2026-10-16 定位并修复的重大 bug:`world/main.gd` 的玩家生成会把 Player 根节点的缩放静默抹掉。**
|
||||
旧代码在 `spawn_function` 里写 `player.global_position = player_spawn_pos.global_position`,
|
||||
但该节点**此刻还没入树**(spawner 之后才 add_child)。`Node3D.get_global_transform()` 未入树时
|
||||
直接 `ERR_FAIL_COND_V(!is_inside_tree(), Transform3D())` 返回**单位矩阵**,于是
|
||||
`set_global_transform()` 把 Player 的 basis 整体换成单位阵 —— **0.096096 那层缩放没了**。
|
||||
实测后果(与游戏内 DebugPanel 逐位吻合):玩家模型 **1.561 m**、第一人称相机 **1.1610 m**,
|
||||
面板显示「相机高度 1.161 m / 5.80 身高」;控制台每生成一个玩家刷一条
|
||||
`ERROR: Condition "!is_inside_tree()" is true.`。
|
||||
修法:`player.position = player_spawn_pos.position`(Main 与 PlayerSpawnPos 同级、Main 无变换,
|
||||
局部坐标即世界坐标)。**通用规则:未入树的节点只能写局部 position/transform。**
|
||||
- 全项目**只有** `player.tscn` 一个 CharacterBody3D;`main2.tscn` 的 `World` 根节点无缩放(1:1),
|
||||
所以 15cm 就是游戏内真实绝对尺寸。玩家是**约 15cm 高的小老鼠**,有意为之(见
|
||||
`player_motor.gd` / `debug_panel.gd` 注释里的「小人国玩法,身高约 0.2 m」基准;
|
||||
走速 2.419 m/s ≈ 12 身长/秒就是按 0.2 m 身高定标的 —— 缩放被抹掉时手感同样全错)。
|
||||
- 相机自身 `scale = 10.4062605 = 1/0.096096`,作者意图是**抵消父级的 0.096**;实测
|
||||
`Camera3D` 的全局缩放两种玩家缩放下都是 1.0,所以 `InteractionRay.target_position = (0,0.25,0)`
|
||||
在世界里恒为 0.25 m —— **不随玩家缩放变化,改缩放时不用动它**。
|
||||
- `ui/character_select.tscn`(选人界面)的预览模型只挂了 `0.18240133` **一层**缩放
|
||||
(没有 Player 那层 0.096),模型 ≈ 1.56 m,机位 `PreviewCamera` 在 `(0,0.62,1.5)` 看向 `(0,0.45,0)`
|
||||
也是按这个尺度配的。它是**进游戏前的展示界面**,与游戏内 15cm 天然不同尺(要一致就再乘 0.096
|
||||
并把机位挪到 ~0.15 m 高)。
|
||||
- **渲染/骨骼实测(2026-10-16)**:`main2.tscn` 的 `woman` AABB 高 **1.703 m**(世界是 1:1 真人尺度);
|
||||
绕开 `main.gd` 直接实例化 `player.tscn` 时,玩家渲染出来约 15 cm、`Skeleton3D` 骨骼竖直跨度
|
||||
0.099 m。⚠️ 这一组数据只对「直接实例化」成立 —— 走真实生成路径时缩放会被上面那条 bug 抹掉。
|
||||
- ⚠️ **探针技巧**:`player.gd` 的 `_ready()` 会把**整只模型** `Body/mouse` 设为 `visible = false`,
|
||||
探针里只把下面的 `MeshInstance3D` 设成 `true` **没用**(父节点还藏着),
|
||||
必须显式 `player.get_node("Body/mouse").visible = true`。这个坑踩了三轮才排掉。
|
||||
- ⚠️ 量 skinned mesh 时不能只看 `mi.global_transform * mi.get_aabb()`:那是 **mesh 资源**的
|
||||
包围盒,**不含骨骼变换**,位置/尺寸都可能偏(实测玩家 mesh AABB 落在 Player 原点**下方**,
|
||||
而真实骨骼在原点**上方**)。要真实数据就查 `Skeleton3D.get_bone_global_pose()`,或者直接渲染截图量像素。
|
||||
- 蹲伏高度由 `player_look.gd` 的 `crouch_height_ratio = 0.6` 从 `CameraRig.position.y` 推导,
|
||||
改 rig 的 Y 会自动跟随,不用改脚本。
|
||||
- `world/main.tscn` 根节点 `Main`(Node3D)无缩放,`MultiplayerSpawner.spawn_path = ".."`,
|
||||
所以 Player 的 0.096 即最终世界缩放。(`PlayerSpawnPos` 在 y=4.8,出生会先坠落。)
|
||||
|
||||
Reference in New Issue
Block a user