目录

1 场景搭建

2 Mesh调节器

2.1 准备

2.2 顶点速度

3 Mesh 调节器的输入

3.1 输入检测

3.2 施加力

3.3 力偏移

4 最基础的变形

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

Unity Mesh基础系列(四)mesh变形(制作一个弹力球)相关推荐

  1. [Unity 学习] - 进阶篇 - Mesh基础系列1:生成网格

    [Unity 学习] - 进阶篇 - Mesh基础系列1:生成网格 本文并非原创,只是本人的学习记录,原文是由放牛的星星老师翻译Catlike系列教程 链接: https://mp.weixin.qq ...

  2. Unity Mesh基础系列(一)生成网格(程序生成)

    目录 1 渲染事物 2 创建顶点网格 3 创建Mesh 4 生成附加顶点数据 本文主要内容: 1.创建一个点阵网格 2.用协程分析点阵网格的位置 3.用三角形定义表面 4.自动生成法线 5.增加纹理坐 ...

  3. Unity关于Oculus Quest2 基于XR Interaction Toolkit 基础开发 003-抓取功能-制作一个VR保龄球游戏

    学习目标: 制作一个VR保龄球游戏 学习内容: 1.创建一个Plane作为地板 2.创建XR Origin 3.手柄操作方式更改 4.创建保龄球和保龄球底座(Socket) 5.完善场景和玩法 6.打 ...

  4. 【有利可图网】PS实战系列:PS设计制作一个超赞的漂亮艺术花纹人像海报

    本篇教你如何巧用PS设计制作一个超赞的漂亮艺术花纹人像海报!教程清晰明了,制作过程灰常巧妙,许多曲线也是用花朵液化得到效果,这样既能省去画线条繁琐过程,也可让作品变得极具艺术感!

  5. Unity Mesh基础系列(三)立方体球(更好更圆)

    目录 1 适配圆角立方体 2 检查映射 3 用数学来玩 4 调整映射 本章重点: 1.把立方体变为球体 2.在Unity中可视化映射 3.分析换算的损耗 4.用数学优化算法 在本教程中,我们将创建一个 ...

  6. 零基础一天学会开发制作一个微信小程序【附源码】

    时至如今,微信已然成为一个全民通用的工具,相应的微信小程序开发已经是一个热门的开发项目. 小程序的前端代码和web是极其相似的,wxml和html.wxss和css以及js,现在还经常将wxss读作c ...

  7. JPA基础(四):第一个JPA实例与JPA主键生成策略

    写实体bean,映射的数据可以采用XML配置方式,也可以采用注解方式,在JPA中推荐大家用注解的方式,因为注解的方式开发应用效率是挺高的. 每个实体bean都要有个实体标识属性,这个实体标识属性主要用 ...

  8. unity 画球面_unity3d第一个例子--制作一个简单的球体碰撞墙面

    思路 当然首先应该先新建立一个地面,有地面才有一切(floor) 再建立一面墙WaLl,一面墙也就是用100个预制的正方体组成 我们不可能让发射的子弹bullet,朝着一个方向射击shoot 所以需要 ...

  9. html弹力球游戏源码,Flash游戏制作:弹力球

    二.游戏action控制代码的添加 1.为了方便我们对游戏进行修改和调试,我们一般都需要把大部分的控制代码专门放到一个独立的mc中,这也是一个制作的好习惯. 2.选取insertànew symbol ...

最新文章

  1. 从概念到技术,打通「中台」的任督二脉,别再说不知道中台是什么
  2. android怎么写本地图片,Android 开发图片保存在本地
  3. libpcap 源代码分析(二)
  4. linux 关闭密码复杂化,Linux系统设置复杂密码策略方法
  5. 全球及中国交联的高密度聚乙烯行业投资应用与供应需求规模分析报告2022版
  6. Python常用模块之time模块
  7. linux什么用户什么任务,Linux 用户
  8. [react-router] React-Router 3和React-Router 4有什么变化?添加了什么好的特性?
  9. 前端学习(2691):重读vue电商网站12之获取选中节点的keys:
  10. 七、华为鸿蒙HarmonyOS应用开发之Java UI框架、常用Text组件和Button组件使用
  11. 目标检测之空间变形网络(STN)
  12. 前端后台与接口的问题
  13. SQL server 2008 中的五个系统数据库详解
  14. [Linux] vimdiff 快速比较和合并少量文件
  15. 一步步开发自己的博客 .NET版(3、注册登录功能)
  16. js 定义函数的几种方法 以及如何调用
  17. 关于MAC安装yarn
  18. DNF11.22服务器维护到几点,11.22体验服更新详情,文字版。预计正式服更新是11.26...
  19. matplotlib配色
  20. 饱受诟病的白板面试,为什么沿用至今?

热门文章

  1. 2022.1-4月学习计划
  2. 从程序员到项目经理(十二):如何管理自己的时间
  3. 阿里云服务器Windows Server 2008 架设 Web 服务器教程(图文详解)
  4. PM都要懂这三种管理方式
  5. 文明6游戏 linux,《文明6》正式支持Linux/SteamOS 但不支持Intel核显和A卡
  6. Qt之Windows下禁用和启用中文输入法
  7. 深度学习---之对pad的一些理解
  8. 1万步21天钉钉运动大神赛
  9. 单纯的Java项目打成一个可运行jar包或者普通依赖包
  10. 国网GIM设备三维模型要求细则 - 干式电抗器