总览

捏脸主要是通过复制一份骨骼(称为编辑骨骼)的Transform值,带动蒙皮来实现体型的变化,主要技术点在实现方式,编辑器开发,骨骼数据的组织方式,数据的存取。

主要的类和方法

CommonCustomizeDNA

自定义部位可以改变的值,包括Transform的各个分量,共9个,加一个整体缩放

public XXX
{
	scaleX,
	rotaionX
	...
}

CommonCustomizeDNAConfig

自定义部位可以改变的值范围,包括Transform的各个分量,共9个,加一个整体缩放

public XXX
{
	scaleXmin,
	scaleYmin,
	...
}

BodyCustomizeDNA

预定义的可调节部分,可能作用于单根骨骼,也可以一个参数作用于多个骨骼,也可以改变整体缩放(单独处理)

还包括了自定义的DNA属性

//在z轴方向缩放,改骨骼scale值
[LabelOverride("胸腔前后","上身")]
[Range(160,60)]
public upperBodyFB;

//偏移
[LabelOverride("胸部左右","上身")]
[Range(160,60)]
public bustOffsetLR

BodyCustomizableSlot

数据类,可编辑的最小单位,主要存数据,包括操作的细项属性,原骨骼,编辑的骨骼

BodyCustomizableController

  • 定义每个槽位的信息,包括了名字,操作的骨骼名字,编辑模式(改变自身,改变自身和子对象,改变自身以及非BIP骨骼)
  • 初始化做了
    1. 根据固定槽位列表,找到对应的bone
    2. 整合固定的槽位列表和自定义的槽位列表
    3. 根据上面的数据,按模式生成编辑骨骼,生成一份一模一样的骨骼(Transform信息也一致),放到原骨骼下面,如果编辑模式为修改自己以及子对象,则把原骨骼的子对象都放到编辑骨骼下面。生成一份新的骨骼放在原骨骼的子节点,编辑骨骼可以受到动画和自定义值的双重影响,其子节点能受到自定义值得影响。
    4. 把编辑骨骼替换原有骨骼整合到蒙皮中,mesh.bones,使其能够影响蒙皮
  • ApplyDna方法,主要把配置的值(BodyCustomizeDNA)赋值到可编辑骨骼中
    1. 根据BodyCustomizeDNA值对BodyCustomizableSlot的编辑骨骼进行三维度缩放(放大缩小效果)
    2. BodyCustomizeDNA的配置值直接对特定BodyCustomizableSlot的编辑骨骼进行旋转处理(偏移效果)
    3. 处理自定义槽位的编辑骨骼旋转缩放位置,以及镜像编辑骨骼的旋转缩放位置
  • LateUpdate中处理某些父子骨骼的位置关系(脖子和头),子骨骼跟着父编辑骨骼走,主要针对BIP骨骼会被anim控制,也希望能受到父编辑骨骼的影响。

体型变化实现原理

分三种操作类型

1. 整体缩放

改根节点缩放

2. 骨骼节点的各方向缩放

直接调scale的分量

3. 骨骼节点偏移

左右:直接改旋转值的Y值

localRotation = Quertnion.Euler(0,左右偏移值,0)

上下

localPosition = Quertnion.Euler(0,0,0)*Vetor3.up*上下偏移值
//好像就是等于y值。。

数据存取方式

JSON进行存储,打包时用prefab索引起来,读取时也用prefab,后续可以打成二进制,比较省

高维控制

实际上就是把多个BodyCustomizableSlot打包成一个集合,可以初始化值,后面再做一下统一的缩放。比如改胖瘦,会同时改动腰部,胸部,大腿手臂等节点。

捏脸实现

底层逻辑和捏体型一致,不同点

  • 可以指定部位镜像处理,比如,改了左眼会同时改变右眼
  • 一个部位有多个维度可以调整,代码预先设置好可以调整的细项,比如,对眼睛可以进行旋转平移拉伸共九个维度,加一个整体的缩放
  • 体型可以调整的范围比较粗略,脸部每个部位的细项大多可以调整

几个问题

  • 问:怎么避免受到动画控制器影响

  • 答:复制一个节点用于调整,加入蒙皮

  • 问:复制节点后怎么保证能影响到子节点

  • 答:把非bip节点放到编辑节点下,bip节点在lateupdate中跟随编辑父节点同步位置(好像只同步了位置,没有做旋转和缩放的处理)