目录微信 |
1 场景搭建函数 2 Mesh调节器性能 2.1 准备测试 2.2 顶点速度flex 3 Mesh 调节器的输入url 3.1 输入检测spa 3.2 施加力.net 3.3 力偏移翻译 4 最基础的变形3d 4.1 将力转换为速度 4.2 移动顶点 5 保持形状 5.1 弹簧 5.2 阻尼 6 处理变换 6.1 调整缩放 |
本章内容重点
向对象投射射线并绘制调试线。
将力转换为顶点速度。
用弹簧和阻尼保持形状。
补偿对象转换。
这篇教程的主要内容是介绍一下网格变形。把网格变成一个弹力球,而后戳它。
本教程是CatLikeCoding系列的一部分,原文地址见文章底部。“原创”标识意为原创翻译而非原创教程。
这篇教程是基于上一篇 立方体球 的。它复用了同一个网格,并在此基础上作增长更多的测试模型。本示例适用于Unity5.0.1及以上版本。
(施加了一些按压操做)
1 场景搭建
咱们会从一个以单个立方体球体为中心的场景开始。你既能够从头开始,也能够复用上一章 立方体球 的场景,而后删除全部多余的东西。
为了得到平滑的变形效果,球体应该包含至关数量的顶点。我把球体的网格大小设为20,半径设为1。
(从一个规则的立方体球开始)
2 Mesh调节器
建立一个新的MeshDeformer脚原本处理变形。就像立方体球面组件同样,它须要一个mesh filter组件来处理。
(添加完组件以后的展现)
这里须要注意,和前面的章节不一样,这里咱们只须要mesh filter。这里咱们不在意它是如何获得网格数据的。而如今正在使用咱们的程序生成的 立方体球,但其实它能够是任何网格。
2.1 准备
要进行任何的变形,咱们都须要访问Mesh。一旦咱们有了Mesh,就能够提取到原始的顶点位置。除此以外,还必须跟踪变形过程当中的位移点。
在Start方法中对网格及其顶点进行赋值,并将原始顶点复制到移位点。
之因此要使用Start,是由于咱们须要在Awake时生成过程网格,由于Awake老是在Start前被调用。这种方法依赖于其余组件在Awake时处理好他们自身的东西,Awake自己的前后顺序并不能保证,因此你其实能够在Unity的设置里本身调节脚本执行顺序,以强制执行第一和最后的脚本。
2.2 顶点速度
当网格变形是由顶点移动形成的。因此咱们还必须存储每一个顶点的速度。
这样咱们就有了支持网格变形的基本成分了。
3 Mesh 调节器的输入
咱们须要一些手段来控制mesh如何变形,这里就要用到用户输入,也就是交互。无论何时用户触碰了物体,都会给这个点施加一个力。
MeshDeformer 类会处理实际的变形逻辑,可是它并不关心输入。咱们须要建立另一个单独的类来处理用户输入。给这个组件配置一个能够自定义输入的力变量。
把这个组件附加到相机上,由于它表明了用户的视角关注点。绑在其余物体上也行,但不该该绑定到须要变形的网格对象上,由于场景中可能有不少网格对象。
(把 mesh deformer input组件绑定在摄像机上)
3.1 输入检测
当按住鼠标按钮时,咱们就须要处理用户的输入。并根据后续的操做,能够获得点击或拖动操做。
拿到鼠标事件以后,还须要找出用户的指向位置。能够经过把镜头中的光线投射到场景中来实现这一点。经过抓取场景的主摄像机,并使用它将光标位置转换为光线。
使用物理引擎来投射射线并存储关于它碰撞信息。若是光线与某物发生接触,就能够从被击中的对象中检索 MeshDeformer 组件。
Physics.Raycast 是如何工做的?
这是一个静态的方法,用来把射线投影到3D的场景里。它有不少个变体方法,最简单的一个就是传递一个ray参数,而后返回是否击中了对象。
咱们使用的版本有一个附加参数。它是RaycastHit类型的输出参数。里面包含被击中的信息和接触点的结构。
3.2 施加力
若是咱们击中了一个物体,而且该某物有一个 MeshDeformer 组件的话,就可使它变形了!所以,如今须要在接触点增长变形的力。
固然,这段代码调用了 MeshDeformer 组件有AddDeformingForce方法。因此须要在相应的组件里添加这个方法。
不过,咱们暂时不作任何变形。而是画一条调试线从主摄像机到点,以便以可视化的力的状况。
3.3 力偏移
咱们想要实现的效果是网格被用户按压和凹陷。
这就须要将接触点附近的全部顶点推动表面里。然而,变形的力并无指定内在的方向。它会平等地应用于各个方向。这将会致使平面上的顶点被向周围推开,而不是向内推。
经过将力点从表面拉出,咱们能够增长一个方向。一个轻微的偏移就能够保证顶点老是被推入表面。而接触点处的法线正好能够做为偏移方向。
(不一样力的方向产生的偏移效果)
4 最基础的变形
如今能够开始作一些变形效果了。MeshDeformer .AddDeformingForce 必需要循环遍历全部当前移位的顶点,并将变形力分别应用到每一个顶点才能够。
4.1 将力转换为速度
一个力被施加到网格的每一个顶点以后,网格就会变形。当顶点被推入的时候,它们须要得到一个速度。随着时间的推移,顶点就会改变它们的位置。若是全部顶点都经历彻底相同的力的话,整个物体就会移动而不改变其形状了。
想象一个爆炸。若是你在边上,就必死无疑。但若是你离的远些,可能会被气浪撞倒。而当你在很远的地方的时候就几乎受到影响。
也就是说,力是会随着距离的推移而减弱的。结合方位的差别,就会产生方向上的衰减,这也是形成物体变形的原理。
因此咱们须要知道每一个顶点变形力的方向和距离,而二者均可以从力点指向顶点位置的矢量导出。
能够用逆平方定律找到衰减力,只需将力除以距离平方便可。
地址:https://en.wikipedia.org/wiki/Inverse-square_law
而实际上,我除以1加上距离平方。
这能够确保当距离为零的时候,力处于全力状态。不然,力就会在距离1的地方达到最大的强度,而且越靠近点,它就会朝无穷远的方向飞去。
(红色是改良后的力衰减)
如今咱们有了力,而后能够把它转换成速度。实际上,力首先转化为加速度。
而后加速度会改变速度。
为了计算简单,咱们将忽略质量,就好像它是均匀分布的,每一个顶点的都同样。因此最后的速度变化是:
在该点上,咱们已经有了一个速度了,但尚未方向。这能够经过规范最开始使用的法线向量来获得。而后咱们能够把结果加到顶点速度上。
4.2 移动顶点
顶点有速度以后,咱们就能够移动它们了。添加一个更新方法来处理每一个顶点的位置。而后,将位移顶点分配给网格,使其实际发生变化。由于网格的形状再也不是恒定的,咱们也必须从新计算它的法线。
更新顶点是调整其位置能够经过:
这些顶点会一直更新下去吗?
是的,每一个update 全部的顶点都被移位,而后分配给网格,而后法线被从新计算。即便没有施加力,由于这个函数就是每帧执行的。可是若是用户没有让网格变形,这个方法能够被认为是浪费性能。所以,只有当网格处于不断变形的时候,再使用这个方法。
(累计的速度)
5 保持形状
一旦咱们对顶点施加了一些力,他们就会开始移动,但他们并不会停下来。若是它们不停地移动的话,物体的原始形状就会消失。如今咱们来让物体进行回弹以恢复到原来的形状。
真实的固态物体,在变形的过程当中会被压缩和拉伸,可是它们自身能抵抗这种变形。一旦不受干扰,就能够恢复到原来的形状。
而咱们并无真正的体积,只是一个描述表面的顶点集合而已。因此咱们不能用它来进行真实的物理模拟。但这并非问题,咱们真正须要的是看上去像就能够了。
5.1 弹簧
在前面,咱们已经能跟踪到每一个顶点的原始和变形位置。假设咱们在每一个顶点的两个版本之间附加一个弹簧。每当变形的顶点被移离原始顶点时,弹簧就会把它拉回来。变形顶点越远,弹簧的拉力就越大。
(偏移的顶点被拉回)
咱们能够直接利用位移矢量做为速度调整,乘以一个可配置的弹簧力。简单,而且听上去也不错。
(变形后反弹)
5.2 阻尼
顶点如今抵抗变形,跳回原来的位置了。可是他们跳得太快了,并且不停地弹。这是由于弹簧力一直在拉它,而顶点却在自我校订,从而提升了它的速度。并且它只有在向后移动很远后才会减速。
这里能够经过不断地减缓顶点的速度来防止这种永恒的振荡。这种阻尼效应能够替代电阻、阻力、惯性等。是一个简单的因素,它会随着时间的推移而下降速度。
阻尼越高,物体的弹性就越小,表现的速度也就越慢。
(恢复到它先前的形状)
6 处理变换
网格变形的功能如今是完整的了。可是若是咱们要对物体的transform进行变换的话,还须要一些些处理。如今全部的计算都是在局部空间进行的。移动或旋转咱们的球体。你会发现变形力会被不正确地施加。
咱们必须补偿物体的transformation。经过将变形力的位置从世界空间转换到局部空间来实现这一点。
(正确的位置,可是不一样的缩放)
6.1 调整缩放
力如今被施加在正确的位置,可是其余的地方仍然是错误的。向上或向下均匀地缩放球体。你会注意到变形鳞片的数量是同样的。但这是不对的。小的和大的物体应该受到一样的物理的影响才对。
因此过程当中就必须补偿对象的缩放。首先,咱们须要知道它的统一缩放值。这能够经过检查一个transform的local scale轴来找到。并且每次更新都要这么作,这样咱们就能够在某种程度上处理那些动态改变其规模的对象了。
若是不统一的缩放该怎么办?
你能够用一个3D向量代替一个单一的值。而后分别调整每一个维度的补偿。但实际上,你不会想处理不均匀的尺度。
如今修正 AddForceToVertex ,方法是经过统一标度缩放点 pointToVertex 。这确保了咱们使用正确的距离。
对Update顶点中的位移也作一样的操做。如今咱们的速度是正确的。
对于一个没有缩放的物体,咱们的速度如今是正确的。但因为咱们的对象其实是缩放的,咱们也必须调整顶点的运动。这一次咱们须要除以它,而不是乘。
(不一样的缩放值,相同的物理表现)
如今全部工做都完成了。在任意位置、旋转和均匀比例上都能正常展现的变形网格。请记住,这是一个简单和相对廉价的视觉效果。这并非一个软体物理模拟。物体的碰撞也不会改变,因此物理引擎仍是不知道物体的形状的。
本文翻译自 Jasper Flick的系列教程
原文地址:
https://catlikecoding.com/unity/tutorials

本文分享自微信公众号 - 壹种念头(OneDay1Idea)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。