unity布料⾃碰撞_Unity基础教程-物体运动(六)——更复杂
的重⼒(Planes,S。。。
200+篇教程总⼊⼝,欢迎收藏:
放⽜的星星:[教程汇总+持续更新]Unity从⼊门到⼊坟——收藏这⼀篇就够了z huanlan.zhihu
本⽂重点内容:
1、⽀持多重⼒源
2、限制重⼒半径
3、让重⼒随距离递减
4、创建平⾯、球形、和⽴⽅体重⼒源
这是有关控制⾓⾊移动的教程系列的第六部分。它通过⽀持多个重⼒源(包括平⾯,球体和⽴⽅体)扩展了我们的⾃定义重⼒。
本教程是CatLikeCoding系列的⼀部分,原⽂地址见⽂章底部。
本教程使⽤Unity 2019.2.21f1创建。它还使⽤ProBuilder软件包。
在两个球体和⼀个⽴⽅体之间跳跃
1 多重⼒源
如果你只需要相同的重⼒源,那么前⾯教程中介绍的⽅法就⾜够了。但是如果你需要使⽤不同种类的重⼒,或者每个场景⼀个不同的重⼒,或者在同⼀个场景中多个不同的重⼒,那么就需要更通⽤的⽅法。
1.1 默认重⼒源
为了在场景中⽀持多个重⼒源,我们将创建⼀个新的GravitySource组件类型,使⽤类似于CustomGravity中具有单个位置参数的公共GetGravity⽅法,只是在这种情况下它不是静态的。最简单的实现是仅返回avity。将其⽤作默认重⼒源,可以将其添加到任何场景中,这将使我们的球体可以使⽤标准物理重⼒进⾏⼯作。
1.2 重⼒源列表
为了每个场景⽀持多个重⼒源,CustomGravity必须跟踪所有活动源。我们将为此提供⼀个静态的源列表。
调整仅具有位置参数的GetGravity⽅法,以使其遍历源并累积其重⼒。
在另⼀个GetGravity⽅法中执⾏相同的操作,该⽅法也提供向上轴。现在我们别⽆选择,只能通过归⼀化和求反最终重⼒⽮量来得出轴。
当只有⼀个来源时,我们可以优化它吗?
当然可以,但是我们不会对源的数量做任何假设。如果⼀次只使⽤⼀个源,那么循环就没有必要了。
GetUpAxis也必须以同样的⽅式进⾏调整。
使⽤列表是最好的⽅法吗?
如果仅同时有⼏个重⼒源处于活动状态,则列表是最简单的⽅法,也是最佳⽅法。只有在有许多资源发挥作⽤??时,才开始考虑更智能的空间分区策略(例如,限制体积层次结构)会更有收益。⼀种替代⽅法是使⽤碰撞和触发器来确定哪些对象受哪些重⼒源影响,但这会增加⼤量开销。还有⼀种⽅法是禁⽤离玩家太远⽽不会影响游戏体验的重⼒源。但是本教程将使其保持尽可能简单。
同时请记住,拥有多个强引⼒源且彼此接近的区域是不直观的。现实中我们没有这⽅⾯的经验。有⼏个引⼒源的场景可能会很有趣,但在⼀个有很多引⼒源的空间⾥航⾏可能会让⼈反感。
1.3 注册和反注册重⼒源
为了能够更改重⼒源,请添加公共Register和Unregister⽅法。他们只是在列表中添加或删除给定的重⼒源。
这个想法是单个来源只能注册⼀次,否则其效果将成倍增加。同样,仅取消注销先前已注册的源才有
意义。可以多次注销和注册同⼀源。可以通过调⽤Debug.Assert来添加断⾔来验证这⼀点,以捕获编程错误。
Debug.Assert有什么作⽤?
如果第⼀个参数为false,则使⽤第⼆个参数消息(如果提供)记录断⾔错误。第三个参数是如果在控制台中选择了消息,则在编辑器中突出显⽰的内容。此调⽤仅包含在开发版本中,不包含在发⾏版本中。就好像是Debug.Assert(...); 从未出现过⼀样。因此,这是在开发过程中添加不会影响最终版本的检查的好⽅法。
我们可以通过分别在其GravitySource的OnEnable和OnDisable⽅法中进⾏注册和注销。这样,当创建,销毁,激活,停⽤,启⽤,禁⽤源代码以及跨编辑器热加载时,它就可以⼯作。
现在,我们可以将所有场景调整为再次使⽤默认重⼒,只需向每个场景添加带有GravitySource组件的游戏对象即可。
默认的重⼒源
1.4 允许扩展
这个出发点是GravitySource是其他种类的重⼒源的基础,就像MonoBehaviour是我们创建的所有⾃定义组件类型的基础⼀样。新的重⼒源类型将通过使⽤⾃⼰的实现重写GetGravity⽅法来完成其⼯作。
为了使之成为可能,我们必须声明此⽅法为virtual⽅法。
virtual关键字是什么意思?unity 教程
持久化对象 教程末尾的解释
参见 持久化对象
2 重⼒平⾯
默认的物理引⼒只定义了⼀个⽮量,代表了⼀个普遍向下的拉⼒。这个想法最简单的扩展就是定义重⼒平⾯。除了平⾯会将空间分成上下两部分之外,它的作⽤完全相同。我们可以⽤它来限制平⾯的重⼒范围。
2.1 重⼒源类型
创建⼀个继承⾃GravitySource的新GravityPlane组件类型。给它⼀个可配置的重⼒场。这是它应⽤于其范围内的所有物体的加速度。因此,正值表⽰通过重⼒的法向吸引⼒,⽽负值表⽰排斥,表⽰反重⼒。
覆盖GetGravity,使其返回指向正向上的向量,并按负配置的重⼒对其进⾏缩放。重写⽅法必须通过向其添加override关键字来显式完成。
现在,我们可以创建⼀个重⼒平⾯,如果将其配置为指向下⽅,则该重⼒平⾯的⼯作原理与默认物理重⼒⽮量相同。
重⼒平⾯组件
我们也可以通过使⽤游戏对象转换的向上⽮量来⽀持任何⽅向的平⾯。
2.2 可视化平⾯
为了更容易查看平⾯的位置,我们将使⽤⼀些Gizmos将其可视化。如果启⽤了开关选项,它们将在场景窗⼝以及编辑器的游戏窗⼝中绘制。虽然平⾯是⽆限的,但我们需要使⽤有限的可视化效果,因此我们使⽤正⽅形。
通过添加OnDrawGizmos⽅法并使⽤Gi??zmos类的各种静态⽅法和属性来完成绘制Gizmos。⾸先将lor设置为黄⾊,然后通过位于原点的Gizmos.DrawWireCube绘制线框⽴⽅体,其⼤⼩设置为(1,0,1),以使其展平为正⽅形。
默认情况下,Gizmos在世界空间中绘制。为了正确定位和旋转正⽅形,我们必须使⽤平⾯的转换矩阵,⽅法是将其localToWorldMatrix分配给Gizmos.matrix。这也使我们能够缩放平⾯对象,以便更容易看到正⽅形,即使这不影响平⾯的重⼒。
例如,我制作了⼀个⼩场景,包含两个相对的20x20矩形区域和伴随的重⼒平⾯,放置在它们上⾯和
下⾯⼀点。下⾯的区域是正常的,⽽上⾯的区域是颠倒的。因为顶部平⾯旋转了,所以它也是上下颠倒的,这意味着它的重⼒翻转了。
两个对⽴的平⾯,缩放为20
我们是否需要在OnDrawGizmos中重置颜⾊和矩阵?
不需要,那是⾃动发⽣的。
2.3 重⼒范围
当两个具有相同重⼒的平⾯在相反⽅向上拉动时,它们会相互抵消,从⽽根本不会产⽣重⼒。如果我们想要⼀个重⼒在⼀个地⽅向下⽽在另⼀个地⽅向上的场景,则必须限制每个平⾯的影响。通过在GravityPlane中添加⼀个可配置范围来做到这⼀点。它表⽰相对于平⾯本⾝有效的重⼒,因此最⼩范围为零。平⾯的影响⼒没有极限,可以⼀直持续下去。
我们可以通过获取平⾯上⽮量和该位置减去平⾯位置的点积来到GetGravity中位置的距离。如果距离⼤于该范围,则合成重⼒应为零。
我们不能只切断平⾯上⽅的重⼒吗?
可以,但是稍后我们将使⽤范围逐渐减⼩重⼒,⽽不是使其变为⼆进制的有和⽆。
我们可以通过画第⼆个正⽅形来想象这个范围,最初是⼀个单位。我们给它⼀个青⾊。
但在本例中,我们想使⽤范围作为偏移量,⽽不受平⾯游戏对象的缩放的影响。可以通过矩阵4x4⾃⼰构造⼀个矩阵来实现传递位置、旋转和缩放。我们只需要⽤范围替换物体local scale的Y分量。
对这些平⾯进⾏了配置,以使它们的平⾯范围最终位于完全相同的位置。因此,它显⽰了重⼒翻转的平⾯。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。