自学产物,方法非完全原创,有大量参考,欢迎大家指出错误

效果如下

确定裙子骨骼的旋转方向一致(eg都是以z轴旋转)

创建一个locator1放在大腿的骨骼下,用父子约束控制loc的旋转位移

在每个裙子骨骼和loc1创建距离工具

在Node Editor中创建两个multiplyDivide节点并将计算方式改为divide,一个remapValue节点,一个multiplyDivide节点

连接节点

将distanceDimensionShape的distance(记录为距离x)连接到multiplyDivide1的input2X,并将input1X设为1;【乘除节点的运算方式为除法,所以经过其计算后得到的结果x=1/d,当大腿骨骼的locator越接近裙子骨骼的locator,也就是d越小,x越大。由此,可以设定当x大于某个值时,可以看做大腿骨骼已经接触到裙子骨骼,裙子骨骼可以开始旋转了】

multiplyDivide1的输出值outputX连接至multiplyDivide2的input1X,并将input1X的值复制到input2X(此处可利用mel:【getAttr "multiplyDivide1.input1X";】来获得精准的数据);【当大腿骨骼处于初始位置时,x的数值固定,之后所有的变化数值都将与x做对比,将这个常数x记作x1,也就是input2X上的数值。所以经过这个乘除节点计算后得到的结果为y=x/x1,input1X上的数值会根据距离的变化而变化,所以x也会跟随变化,且x1的数值固定,也就是说,d越小,x越大,y越大。】

将multiplyDivide2的输出值连接至remapValue的输入值inputValue【在没有移动大腿骨骼的情况下,inputValue应该为1】

将remapValue的输出值连接至multiplyDivide3的input1X【remapValue的作用是设定输入范围和输出范围,任何在输入范围内的值都会转换为输出范围内值,比如输入范围为-100~500,输出范围0~1,当输入-100时,输出值为0。由于0~1的输出范围太小,需要再加上一个乘除节点,将结果乘以50(或任何合适的数字),将乘除节点的输出值连接到裙子的旋转Z】

对所有裙子的骨骼重复以上操作

对另外一条腿骨骼重复操作

对应骨骼数量增加plusMinusAverage节点,将同一骨骼对应的两个距离节点的计算结果连接至plusMinusAverage的input1D,并输出至骨骼的旋转轴;并对其他骨骼进行同样的操作【比如裙子正前方的部分,需要考虑两条腿的旋转,所以需要加减节点,同时控制裙子骨骼】

根据抬腿等动作的测试,确定所有remapValue的input Min和input Max【确定方法:先测试抬腿在x轴时即将碰到裙子的点,查看此时remapValue的输入值,即为输入范围的最小值;再抬腿到x轴的极限,查看此时remapValue的输入值,即为输入范围的最大值】

PS:其实自动碰撞最重要的原理是如何让电脑判定大腿骨骼靠近了裙子骨骼,这里用的是简单易懂的距离变换+一次函数,其实用方向和角度的判定也是可以的,比如萌芽大佬新出的教程【BV1oT4y1a7DN】

原文件:

链接:https://pan.baidu.com/s/1EQlo2aBZMpx0Uv20FVZE1Q 

提取码:7iiz

Thanks for watching

推荐内容