制作/修改动画器
其实制作动画器,真正需要手动操作的,只有上一页面提到的Driver层,其他可以通过OSCmooth来一键生成,当然如果想做到新版本Jerry模版那些细致的功能,可能需要我们去修改代码或者手动更改。
1. 创建一个属于自己的BlendTree
选做:从零开始自己建立混合树
只需要在空白处右键选择From New Blend Tree,就可以自动生成一个混合树,双击进入,初始的BlendTree是什么都没有的,参数也是默认的GestureLeftWeight。
修改为Direct类型,然后从加号处添加新的混合树
在新的混合树中添加控制形态键的动画,同时调整参数为对应的FT/v2/xxxxxx
参数没有的话需要自己手动添加,具体使用何种参数,请参考VRCFaceTracking Parameters | VRCFaceTracking (vrcft.io)
参数在这个阶段是"FT/v2/"前缀,这是没有经过平滑的,后期会经由OSCmooth自动转化为"OSCm/Proxy/FT/v2"前缀
反复进行这些操作,可以制作出来一份完整的Driver图层,但是从头开始做不仅麻烦,还可能会漏掉一些动作,徒增一些没必要的参数消耗,所以我们这里可以选择第二套方案,从模版中进行拷贝动画器,然后使用OSCmooth还原动画器。
从模板中还原动画器
一般来说在Package中的文件比较难加以修改,所以我们可以直接把Jerry的模版从Package中移动到Asset中
这个操作也许需要一点时间,而且期间Unity不会有卡顿感,这会让你觉得没有移动成功,几分钟后切换一下窗口,模版就移动过来啦~
移动成功后,把我们需要的动画器(不想动源文件可以Ctrl+D复制一份)放入一个模型当中,本文以夏菲为例
这时候导入我们的OSCmooth-Github,将我们的模型拖入到其中
选择下方的Revert OSCmooth from Layer,这样就可以将Driver层所有参数的"OSCm/Proxy/FT/v2"前缀,转化回原始的"FT/v2/"前缀,这时候,应该只有Driver一个State,没有Binary图层和Smooth图层。
我们也需要删除一些参数,需要保留的仅有"FT/v2/"前缀的参数,并且不是1/2/4的二进制压缩参数
参数名 | 动画器/本地 | 参数表/远程同步 | 描述 |
EyeTrackingActive | Float | Bool | 眼球追踪开启 |
LipTrackingActive | Float | Bool | 面部追踪开启 |
EyeDilationEnable | Float | Bool | 瞳孔追踪开启(瞳孔放大缩小,仅Tobii系可用) |
FacialExpressionsDisabled | Bool | Bool | 关闭手势表情 |
VisemesEnable | Bool | Bool | 口型同步开启 |
FT/v2/xxxxxx | Float | - | 原始输入的浮点值 |
下面是需要删除的参数,特别注意FT/v2/xxxxxx是要保留的,FT/v2/xxxxxx1;FT/v2/xxxxxx2;FT/v2/xxxxxx4是要删除的
FT/v2/xxxxxx1;FT/v2/xxxxxx2;FT/v2/xxxxxx4 | Bool | Bool | 原始输入的布尔值,之后会经由Binary转换为BinaryOut/FT/v2/xxxxxx |
BinaryOut/FT/v2/xxxxxx | Float | - | 经过Binary后的值,之后会经由Smooth转换为OSCm/Proxy/FT/v2/xxxxxx |
OSCm/Proxy/FT/v2/xxxxxx | Float | - | 经过Smooth后的值,之后会在Driver图层直接驱动形态键 |
OSCm/BlendSet | Float | - | 混合树同时进行的关键参数,请保持为1 |
OSCm/Local/FloatSmoothing | Float | - | 本地参数的通用平滑程度 |
OSCm/Local/PupilDilationSmoothing | Float | - | 本地参数的瞳孔平滑程度 |
OSCm/Remote/EyeLidSmoothing | Float | - | 远程参数的眨眼平滑程度 |
OSCm/Remote/FloatSmoothing | Float | - | 远程参数的通用平滑程度 |
OSCm/Remote/PupilDilationSmoothing | Float | - | 远程参数的瞳孔平滑程度 |
其实正常的删除参数的话,能删除就说明该参数已经没有对应的动画器占用了,所以只要删掉能删掉的就行,如果出现这个提示,说明就是这个参数是不能删的。(前提是已经删掉了Binary和Smooth层)
这时候就可以开始编辑我们想要的Driver层了
2. 修改动画器
1.简单调整动作的幅度
参数从0变到1的过程,LipPucker的形态键也从0变到100
如果想要让LipPucker更快的到达100,那么就需要降低阈值。例如将Lip_Pucker.anim的阈值从1降到0.7,这样能够让参数到达0.7的时候,LipPucker就已经到达100了。
参数相当于是在0-0.7的变化过程就走完了原先的0-1的变化过程,所以更加灵敏了也更加快速了。但这样做会导致参数在0.7-1.0的变化过程中,形态键都会一直在100固定。
而如果觉得不动作效果那么夸张,或者想让动作更慢一些,就需要调高阈值。
同理将Lip_Pucker.anim的阈值从1升到2,那么参数即使达到了1,也只有原先0.5的效果,形态键也就只有50。
一般来说参数的取值范围都是[0,1]或[-1,1],所以降低阈值也是降低了最大值。
还有另一种方法来实现降低动作幅度,就是修改动画的形态键值,可以让Lip_Pucker.anim的关键帧降为70,这样即使是参数到达了1,也只能驱动70的形态键。
2.添加限制
一般情况下,单个动作直接伸出是不会穿模的,但组合动作则会很容易穿模,我们假设一个情况,如果LipPucker单独为100,没问题,JawOpen单独为100,没问题,但LipPucker和JawOpen同时为100的时候,会出现一个穿模问题,那我们现在就需要加以限制。
我们一般在比较不重要的动作做出限制,而重要的动作则直接驱动,相比之下,JawOpen是张大嘴巴,而LipPucker是噘嘴,JawOpen重要性大,我们在LipPucker上加一些逻辑限制。
我们的大体思路是,LipPucker=1且JawOpen=0的时候,形态键LipPucker=100,但如果LipPucker=1且JawOpen=1,则形态键LipPucker=0
那我们就需要修改原本在Lip_Pucker位置的动画为混合树,删除原来的Motion,添加新的BlendTree
修改参数为JawOpen,添加两个Motion。
为了实现JawOpen的限制效果,我们这样填入动画文件
然后最后就有这么一个逻辑:
3.添加联动动作
这里提供一个制作简单联动的例子,供大家参考思路。
在最顶级的根混合树添加一个新的混合树,请记得更改参数让这个混合树正常加入计算,如果想要常驻,那就使用FT/DirectBlend,如果要让联动的动作与眼追或嘴追一起开启,那就更改为LipTrackingActive/EyeTrackingActive。
我们现在要制作一个张大眼睛的时候,如果是嘟嘴,就触发星星眼的效果。这需要联系两种参数,EyeLid和LipFunnel。
首先我们需要录制一个模型的Body上的一个星星眼表情,根据需要可以录制多帧或者单帧。同时我们需要录制一个相同形态键的0值的动画。
如果是多帧动画不想循环,请关闭Anim文件的LoopTime(循环时间)以避免动画循环播放,单帧动画也建议关闭
逻辑:EyeLidLeft和EyeLidRight>0.9,且LipFunnel>0.5时,触发Star
逻辑图如上,需要注意正常的眨眼参数是:0.8默认;0.8→1.0瞪眼;0.8→0闭眼,所以我们选择0.9的时候触发
Star0的位置是靠近且小于0.9的一个数值,而不是正常眼睛下的0.8,因为如果使用0.8到0.9触发的话,会让Star表情有一个慢慢出来的动作,可能会导致一些不必要的视觉BUG,所以要尽可能的缩短这一个行程。关于2D混合树的详细解释,请见本章上一页:动画器详解 | VRCD 文档库。
第二层嵌套使用1D混合树,用LipFunnel参数,同样的,使用了靠近且小于0.5的数值,尽可能让这个行程缩短,不要让Star有渐入渐出的效果。