如果你曾经尝试使用unity原生的HingeJoint2D和Rigidbody2D组件来建立一个动态的构造系统,比如像Poly Bridge那样, 那么你一定知道这个过程。 你会把你的梁放置好,一辆重卡就将会驶过它们,碰撞器会重叠一毫米多一点, BOOM — 碰撞引擎就会过度补偿,导致架子升空。

我花费了好几个星期的时间才能够克服这个难题。今天,我想要分享我所开发的“皮肤与骨骼”体系,来设计出完美无瑕,坚不可摧(直到你想要它们破碎) 的桥梁,使用混合的Verlet系统。

1. “皮肤与骨骼”体系概念

Unity 的关键错误是迫使对齐点来同时处理可视性和结构性同时。 我分离了它们:

  • (Verlet Integration) 皮肤 (Skin): 实际上是汽车驶过的路面,一个自定义的 Verlet绳条, 可以处理美观的下陷、张力以及连续 EdgeCollider2D 更新。
  • 骨骼(Anchors): 连接梁的对齐点是原生的 Unity rigidbody。

花穴: 我用 Physics2D.IgnoreCollision() 强制忽略梁与节点之间的碰撞。汽车驶在由数学驱动的Verlet曲线上,而Quiet Unity 的骨骼则依偎地处理结构性张力。没有碰撞器的重叠,也无任何抖动。

2. 事件驱动脱耦合

桥梁破裂后,你不想要物理脚本进入你的UI或者音频管理器。这个整个体系建立在数据-事件驱动架构(使用 ScriptableObject 作为事件)上。

当BridgeHealthModule 发现桥梁严重下陷后,它不会直接摧毁物体。它仅仅广播一个OnBridgeSnapped GameEvent。 节点通过监听这个事件来取消注册物理连接,让重力来控制其行为。零硬依赖。

3. 密密当铺的秘密醋 :

这是这个项目最难的地方。要不让桥梁在汽车的重量下不断跳跃,你需要高的linearDamping (像稠浓的糖浆一样)。然而,当桥梁下陷后,要加速该桥梁下陷的破裂运动却会像这张糖浆的阻力一样变慢。

解决方案: 我删除了线性阻尼,使用了Vector Projection (Vector2.Dot) 。 脚本仅仅计算出节点的velocity 只是在轴向梁方向。

如果桥梁在跳跃那么引擎就会消耗冲击。如果桥梁破裂并进入自由落体状态,引擎就会去掉“降落伞”,让桥梁自由落于空中并像一个完美的弹簧一样在各个点处震荡。

自己来玩 ! 🎮

我把这个架构编入了一个模块化的框架。

如果你想看到物理效应,我建议你通过浏览器右键可以直接在浏览器中打开这个 Free WebGL Demo

🔗 ITCH.IO

如果你想跳过几个月的碰撞调试并将它应用到自己的项目中,全源码可以通过浏览器右键下载。

我真的很想听听对Verlet与原生物理引擎的讨论! 在下边的评论中,告诉我有关数学或体系架构你的疑问。 祝好运!