你这情况现在是不是进入了死胡同呢?为什么绑骨骼这么难?
来自夹夹 QQ 群讨论,审核后公开 · 。查看原始讨论
提问
你这情况现在是不是进入了死胡同呢?为什么绑骨骼这么难?
回答
回复 群友 6814
不是死胡同,你卡的问题是:每轮都要先分清「骨架对不对、方块尺寸对不对、挂载偏移对不对」,但现在这三层错误混在一起,所以每次调整都像是在摸黑。骨骼绑定本身不难,难的是没有可验证的中间状态。
先说图里那份分析:它对了一件事,看错了另一件。对的是——17 根确实成立,因为 _build_skeleton 里有 LowerLeg、LowerArm、Foot、Hand,是我上次看场景树截图时你家骨架还没补,或者截图是旧场景实例。这个分歧到此结束,不用再纠结。看错的是「3 分钟时间差解释截图 8 根」:如果是旧场景实例没重载,你截图里应该连骨骼都看不到,而不会整齐排列出 8 根完整的链。更可能是你截图时用的是另一份场景/另一份脚本,或者那棵树是编辑器里手动加的临时节点。不用回头查了,验一次 get_bone_count 就够。
真正该记的一条:差值是位置不是长度。它自己承认了 Hips 差 0.11、往上 0.31–0.35 不再增长,这就是整体平移混在里面,不是骨架变矮。所以别用世界坐标相减去推方块尺寸,用骨长比:UpperArm→LowerArm 的向量长度、UpperLeg→LowerLeg 的长度,拿这两组比。
然后是你问的“为什么难”。三个具体原因,都不是绑骨骼这门技术本身的问题:
一,你是用代码 add_bone 现造骨架,不是导入现成骨架。手造骨架没有绑定姿态的参考系——Mixamo 的骨架自带 rest pose、旋转约定、骨骼局部轴朝向,这些都藏在文件里;你用 Basis.IDENTITY 加一个 position 建出来的骨头,每根骨的局部轴全是世界轴,所以方块一挂上去就横七竖八。这是你现在最本质的坑,比 17 还是 8 重要得多。
二,方块和骨头是两套尺度。骨头只在摆姿势时说话,方块有自己的尺寸,两者不同步时你看到的永远是重叠或悬空,而这跟动作质量无关。
三,中间没有一层能看到的东西。你每次只能靠最终画面判断对错,而最终画面把所有误差叠加在一起。这是死循环感的来源。
破法很简单,别急着做动画,做两件事:
第一,先把骨架的 rest pose 正视化。不要 BASIS.IDENTITY。把骨架设成:Hips 在原点上方 1.0 左右,Spine/Chest/Neck/Head 沿 +Y 递增,UpperArm.L 从 Chest 沿 +X 伸出、UpperArm.R 沿 -X,双腿沿 -Y。这一步做完,你现在这张图里的方块朝向就有一半是对的。手造骨架的骨骼朝向必须你自己定规矩,定完就再也不用猜。
第二,挂载只算一次。写个小函数遍历所有 BoneAttachment3D,取所在骨骼的世界变换逆矩阵,乘上方块目标世界位置,得到局部 offset 写死。这样 16 个方块一次全对,不用一个个试。挂完只看 Hips 和 Chest 两块是否重心对齐,对了就整具对。
第三,验证手段换成数值。它说看不到图这是它自己的限制,不影响你——你截图发我就行,我这边能看。真正省事的是另一条:打印每根骨的世界坐标和每块方块的中心,比对距离是否等于你算的骨长一半。数值对上了,画面一定对。
另外那个「17 根齐全」的证据留个心眼:get_bone_count 是运行时读的,可信;但你贴的代码里 15 个 key(Hips、Spine、Chest、Neck、Head、双臂各 3、双腿各 3)数下来是 15 或 17 都说得通,取决于有没有髋部两个子骨。让它打印完整骨骼树文本,比数 key 可靠。
最后一句实话:这段路程长不是你的问题,是「代码造骨架 + 方块拼装」这个组合本身缺少一个可视化的中间层。做完上面三步,你会发现剩下的都是体力活。现在先定骨架的 rest pose 规矩,把每根骨的朝向写下来贴给我,我给你核对一遍再动手挂方块。