关节 布料
关节
铰链关节(Hinge Joint):将两个物体以链条的形式绑在一起,当力量过大超过链条的固定力矩时,两个物体就会产生相互的拉力。
固定关节(Fixed Joint):将两个物体永远以相对的位置固定在一起,即使发生物理改变,它们之间的相对位置也不会发生改变。
弹簧关节(Spring Joint):将两个物体以弹簧的形式绑定在一起,挤压它们会得到 向外的推力,拉伸它们会得到两边对中间的拉力。
铰链关节(HingeJoint)
在 Unity3D 基本关节中,铰链关节是用途很广的一个,利用铰链关节不仅可以做门、风车的模型,甚至可以做机动车的模型。铰链关节的功能是将两个刚体束缚在一起, 在两者之间产生一个铰链的效果。
属性: | 功能: |
ConnectedBody | 连接目标,指与主题构成铰链组合的目标刚体。 |
Anchor | 主体围绕其摇摆的轴的位置。该位置在局部坐标空间中定义。 |
Axis | 主体围绕其摇摆的轴的方向。该方向在局部坐标空间中定义。 |
AutoConfigureConnected | 当勾选该属性值时,仅给出锚点的坐标,系统将自动计算出目标锚点的坐标。 |
(设置为false以后可以手动设置ConnectedAnchor的位置,此时如果游戏对象在 | |
Anchor | |
旁边游戏开始游戏对象会自己开始摇摆) | |
ConnectedAnchor | 当勾选该属性值时,仅给出锚点的坐标,系统将自动计算出目标锚点的坐标。 |
UseSpring | 关节组件中是否使用弹簧,只该属性被勾选时,弹簧(Spring)属性才有效果。 |
Spring | 弹簧力,表示维持对象移动到一定位置的力。 |
Damper | 阻尼,指物体运动所受到的阻碍的大小,此值越大,对象移动越缓慢。 |
TargetPosition | 目标角度,表示的是弹簧旋转的目标角度,弹簧负责将对象拉到这个目标角度。 |
UseMotor | 使用电动机,规定了在关节组件中是否需要使用电动机。 |
Target Velocity | 目标速率,表示对象试图达到的速度,其将会以此速度为目标济宁加速或减速。 |
Force | 此属性表示用于达到目标速率的力。 |
FreeSpin | 是否自由旋转,若启用马达如果被施加一个过大的力,只会还是这个加速,不会减速。禁用的话会还原到设置的目标速率。 |
UseLimits | 固定了在关节下的旋转是否受限。 |
Min | 规定了该刚体旋转所能达到的最小角度。 |
Max | 规定了该刚体旋转所能达到的最大角度。 |
Min Bounce | 规定了刚体达到最小限值时的弹跳值。 |
Max Bounce | 规定了刚体达到最大限值时的弹跳值。 |
BreakForce | 给出一个力的限值,当关节收到的力超过此值时关节会损坏。 |
BreakTorque | 给出一个力矩的限值,当关节收到的力矩超过此值时关节会损坏。 |
关节是依附在刚体上的,也就是说一个对象必须先挂载一个刚体组件,然后才能添 加铰链关节组件。
依次点击“GameObject→3D Object→Cylinder”创建一个圆柱体,再依次点击“GameObject→3D Object→Cube”创建一个立方体,然后再设置这两个对象的Position为(0,0,0),使其重合在原点处。
分别调整Cylinder和Cube对象的大小和位置,以模拟出门和门轴的模型大小,然后分别选中这两个对象,依次点击“Component→Physics→Rigidbody”分别为其添加刚体组件。
接下来为圆柱体添加一个铰链关节组件。 先选中 Cylinder 对象, 依次点击 “ Component → Physics → Hinge Joint ” 为 圆 柱 体 添 加 一 个 铰 链 关 节 , 并 在 “Inspector”面板中修改其参数。
此时使用第三人称角色去碰撞这个门板,我们可以发现门会开。门虽然会被我们推 动但是自动关上。那我们来看下 Use Spring、Motor 和 Limits 这三个属性。
将 Target Position 设置为 0。这样就代表如果门被推动了以后,门会以 100 的弹簧 力回归到角度为 0 的位置。但是我们会发现这样的门还是有问题,他可以直接一直被 推动好几圈。之后不用弹簧,我们再看 Motor。这个就是相当于门会自动旋转,明显不是我们要用的。 比如 Target Velocity 设置为 100,Fore 设置为 100,Free Spin 选中以后可以发现门自动旋转。
关闭 Motor,Limits 限值旋转角度,将 Min 设置为-90,再启动 Spring 以后 我们可以发现门开到 90 以后如果没有碰撞物了会自动还原。
启用之后相当于开启了碰撞器。就是两个连接的刚体会相互碰撞。
print(hingeJoint.angle);//连接物体相对于自身的旋转角度 只读
print(hingeJoint.velocity);//获得当前的速度 只读
Motor 将会施加一个最大的力达到目标速度(单位:度/秒)。马达尝试去达到 targetVelocity 角速度(单位:度/秒)。如果 force 足够大,马达将会仅可能达到 targetVelocity。如果 targetVelocity 是负数,马达将会向相反的方向转动。Force 是马达可以发挥的最大转矩。如果它为零,马达将会禁用。如果 freeSpin 为 false, 当从外部施加力关节旋转快于 targetVelocity 时,最后会被还原。如果 freeSpin 为 true 当从外部施加力关节旋转快于 targetVelocity 时,最后不会被还原。
JointLimits jointLimits = hingeJoint.limits;//limits的返回值是JointLimits jointLimits.min = -90;//设置旋转的最小角度
jointLimits.max = 0;//设置旋转的最大角度
jointLimits.bounciness =0;//当达到最小或者最大角度限值时的反弹力 0-1
jointLimits.bounceMinVelocity = 0;//反弹的最小速度
hingeJoint.limits = jointLimits;//将设置的limits返回给对象
hingeJoint.useLimits = true;//启用旋转限制
马达一旦被启动,那么弹力将自动被禁用,当马达禁用以后,弹力将会重新启 用(如果弹力是 True 的时候)
JointMotor motor = hingeJoint.motor;//motor的返回值是
JointMotor motor.targetVelocity = 90;//设置目标速率
motor.force = 100;//设置里
motor.freeSpin = true;//马达是否可以被破坏
hingeJoint.motor = motor;//将motor赋值给
hingeJoint.motor hingeJoint.useMotor = true;//启用马达
Spring 通过增加弹力和阻碍力尝试达到指定角度。 spring 尝试达到指定角 度。一个大的值使该弹力装置更快达到指定位置。damper 阻碍角速度。一个大 的值使该弹力装置更慢达到指定位置。该弹力达到 targetPosition 角度相当于静 止角度。在模拟开始时关节静止角度为 0。
JointSpring hingeSpring = hingeJoint.spring;//spring的返回值是
JointSpring hingeSpring.spring = 10;//设置弹簧力
hingeSpring.damper = 3;//设置阻尼
hingeSpring.targetPosition = 70;//设置目标角度
hingeJoint.spring = hingeSpring;//将hingeSpring赋值给
hingeJoint.spring hingeJoint.useSpring = true;//启用弹簧力
固定关节(Fixed Joint)
在 Unity3D 基本关节中,固定关节起到的往往是组装的功能,利用固定关节可以 拼接刚体。固定关节将两个刚体束缚在一起,使两者之间的相对位置保持不变,永远不 会变化,在很多开发情况是非常有用的一个关节。
Connected Body | 连接目标刚体对象 |
Break Force | 给出一个力的限值,当关节受到的力超过此限值时关节就会损坏 |
Break Torque | 给出一个力矩的限值,当关节受到的力矩超过此限值时关节就会损坏 |
Enable Collision | 允许碰撞检测 |
Enable Preprocessing | 允许进行预处理 |
首先创建两个球体对象。依次单击“GameObject→3D Object→Sphere”分别创建 Sphere1 和 Sphere2 对象,再依次单击“Component→Physics→Rigidbody” 分别为这两个对象添加刚体组件,取消重力。再选中 Sphere1,依次点击“Component→Physics→Fixed Joint”添加一个固定关节。
此时我们可以发现 Sphere1 和 Sphere2 被连接在了一起,想是中间有一根无形 的绳子。
弹簧关节(Spring Joint)
在 Unity3D 基本关节中,弹簧关节的效果极佳,其模拟效果非常真实。利用弹簧 关节可以模拟多种物理模型。弹簧关节将两个刚体束缚在一起,使两者之间好像有一个 弹簧连接一样。
Connected Body | 连接目标刚体,是关节所依赖的可靠刚体参考对象,缺省时关节将连接至世界空间 |
Anchor | 锚点,基于本体的模型坐标系,表示弹簧的一端 |
Connected Anchor | 目标锚点,基于连接目标的模型坐标系,表示弹簧的另一端 |
Auto Configure Connected Anchor | 仅给出本体锚点,便自动计算目标锚点。 |
Spring | 表示弹簧的劲度系数,此值越高,弹簧的弹性效果越强 |
Damper | 阻尼,此值越高,弹簧减速效果越明显 |
Min Distance | 弹簧两端的最小距离 |
Max Distance | 弹簧两端的最大距离 |
Break Force | 破坏弹簧所需的最小力 |
Break Torque | 破坏弹簧所需的最小力矩 |
Enable Collision | 允许碰撞检测 |
Enable Preprocessing | 允许进行预处理 |
首先创建两个球体对象。依次单击“GameObject→3D Object→Sphere”分别创建 Sphere1 和 Sphere2 对象,再依次单击“Component→Physics→Rigidbody” 分别为这两个对象添加刚体组件,取消重力。再选中 Sphere1,依次点击“Component→Physics→Spring Joint”为其添加一个弹簧关节。
springJoint.spring = 10;//弹力大小 springJoint.damper = 1;//设置阻尼
springJoint.minDistance = 1;//最小距离
springJoint.maxDistance = 10;//最大距离
springJoint.tolerance = 0.025f;//容差 默认即可
//当前弹性长度和通过定义的最大距离和最小距离之间的长度之间允许的最小错误。
//如果容差设置非常高,解算器可能不会运行并且弹力可能实际上不存在。
//如果容差是设置接近零非常短的弹力是可能存在的,但是解算器的运行成本增加。
布 料
在 5.0 及以后的版本中,为提高布料的物理模拟效率,Unity3D 废弃了之前版本 中的 Interactive Cloth 和 Cloth Renderer 组件,转而使用 Cloth 和 Skinned Mesh Renderer 组件代替,以实现布料功能,其所有的参数属性也随之发生了变化。
Cloth 只能必须和 Skinned Mesh Renderer 搭配使用, 但是这不代表使用简单 的 物 体 时 还 必 须 在 Max 中 导 出 一 个 带 有 蒙 皮 信 息 的 FBX, 其 实 可 以 新 建 一 个 GameObject 然后赋予 Cloth 组件, 这会自动添加 Skinned Mesh Renderer 组件, 然后在 Skinned Mesh Renderer 组件中赋予基本体的 Mesh 上去并且设置正确的材 质也完全可以。
布料可以接受外部影响,但完全不会将影响赋予外部刚体, 换句话说, 布料系统的 物理模拟是单向的。
出于性能的考虑, 可以对 Cloth 产生影响的 Collider 只有两种, SphereCollider 以及 CapsuleCollider, 但是 SphereCollider 可以赋予两个为一组(当然了还可以只 赋予一个, 第二个保持 null), 那么通过组合这两个 SphereCollider 可以出现第三种, Unity 会将这组的两个 SphereCollider 进行相连, 那么就可以有圆锥形的 Collider
1. 蒙皮网格 在进行布料组件讲解前,很有必要介绍一下蒙皮网格的特性。蒙皮网格可以模拟出非常柔软的网格体,不但在布料中充当了非常重要的角色,同时还支撑了人形角色的蒙皮功能,通过运用该组件,可以模拟出许多与皮肤类似的效果。
Cast Shadows | 投影方式,包括关(Off)、单向(On)、双向(Two Sided)、仅阴影(Shadows Only) |
ReceIve Shadows | 是否接受其他对象对自身进行投射阴影 |
Materials | 为该对象制定材质 |
Use Light Probes | 是否使用灯光探头 |
Reflection Probes | 反射探头模式,包括混合(Blend Probes)、混合及天空盒(Blend Probes And SkyBox)、单 一(Simple)。 |
Anchor Override | 网格锚点,网格对象将跟随锚点移动并进行物理模拟 |
Lightmap Parameters | 光照烘焙参数,指定所使用的光照烘焙配置文件 |
Quality | 影响任意一个顶点的骨头数量,包括自动(Auto)、一/二/三个(1/2/3 Bones) |
Update When Offscreen | 在屏幕之外的部分是否随帧进行物理模拟计算 |
Mesh | 该渲染器所指定的网格对象,通过修改该对象可以设置不同形状网格 |
Root Bone | 根骨头 |
Bounds(Center) | 包围盒的中心店坐标,该坐标值基于网格的模拟体系,且不可修改 |
Bounds(Extents) | 包围盒 3 个方向的长度,不可修改,当网格在屏幕之外时,使用包围盒进行计算 |
2. 布料特性
Unity3D 将布料封装为一个组件,任何一个物体,只要挂载了蒙皮网格和布料组 件,就拥有了布料的所有功能,既能够模拟出布料的效果。
Stertching Stiffness | 布料的韧度,其值在区间(0,1]之内,表示布料的可拉伸程度 |
Bending Stiffness | 布料的硬度,其值在区间(0,1]之内,表示布料的可弯曲程度 |
Use Tethers | 是否对布料进行约束,以防止其出现过度不合理的偏移 |
Use Gravity | 是否使用重力 |
Damping | 该布料的运动阻尼系数 |
External Acceleration | 外部加速度,相当于对布料施加一个常量力,可以模拟随和风扬起的旗帜 |
Random Acceleration | 随机加速度,相当于对布料施加一个变量力,可以模拟随强风鼓动的旗帜 |
World Velocity Scale | 世界坐标系下的速度缩放比例,原速度经过缩放后成为实际速度 |
World Acceleration Scale | 世界坐标系下的加速度缩放比例,原加速度经过缩放后成为实际加速度 |
Friction | 布料相当于角色的摩擦力 |
Collision Mass Scale | 粒子碰撞时的质量增量 |
Use Continuous Collision | 是否使用连续碰撞模式 |
Use Virtual Particles | 为每一个三角形附加一个虚拟粒子,以提高其碰撞稳定性 |
Solver Frequency | 计算频率,即每秒的计算次数,应权衡性能和精度对该值进行设置 |
Sleep Threshold | 休眠阈值 |
Capsule Colliders(Size) | 可与布料产生碰撞的胶囊碰撞体个数,并在下方进行指定 |
Sphere Colliders(Size) | 可与布料产生碰撞球碰撞器的个数 |
First/Second | First 和 Second 两个球碰撞球相互连续组成胶囊碰撞器,适当的设置可调整成锥形胶囊体 |
3. 布料的简单案例
创建两个 Sphere 对象,命名为“Sphere0”和“Sphere1”,用来充当布料碰 撞体。
创建一个空对象,并将其命名为“Cloth”,然后依次点击“Component→Physics→Cloth”为其添加一个 Cloth 组件,此时在“Cloth”游戏对象上会同时挂载 Skinned Mesh Renderer 和 Cloth 组件。
设置 Cloth 对象上的 Skinned Mesh Renderer 组件上的参数,指定该组件的网 格类型为“Plane”。网格类型可设置为系统自带的网格类型,也可以设置为导入模型 的网格样式,从而创建出任意形状的布料,此时可以发现布料是粉红色的这是因为没有 给其材质。
设置 Cloth 对象上的 Cloth 组件上的参数,为使效果明显,将摩擦力调为最大值 1, 然后将 Sphere0 和 Sphere1 添加成为该布料的碰撞对向,并连接成胶囊体或锥形胶 囊体。
游戏开始以后可以发现 Cloth 会被两个小球形成的胶囊体顶住,一段时间以后掉落。
尝试一下如果直接使用 Plane 或者 Cube 等游戏对象放在布料下方对其进行阻挡 有效果吗?很明显不行。
4. 导入资源包“TestCloth” 现在来尝试做一个飘扬的国旗。首先将“qizi”这个图片附加到刚才的“Cloth”对象上,并将其设置到合适的位置,如果图片倒了就对其进行旋转等,设置下国旗的缩 放比例设置为长方形。
此时运行游戏,可以发现布料会自动掉下去。首先因为使用重力所以旗帜会掉下去。那我们取消重力再给旗帜一个风,也就是速度。但是这时候 运行游戏可以发现旗帜直接被吹着走了。那这怎么办呢?先将重力重新启用。
点击 Edit Constraints
很明显发现 Cloth 上面有一个个的黑点,那现在将右上角和右下角的黑点分别选 中,并勾上 Max Distance 将值设为 0。此时再运行游戏我们可以发现旗帜的右上角 和左下角感觉像是被固定住了。
Max Distance:设置每个顶点最大可移动距离. 最常用的用法是将不能动的顶点 的 Max Distance 设置为 0。
我们也可以将左上角的点设置为 Max Distance =3 那么最大移动距离为 3,是 一个半径为 3 的球形范围。
接下来自己在尝试下将 Mesh 设置为分别试下。
固定风或者随机风,正就表示为正轴方向,负表示负轴方向。