Search Unity

Unity 2018.3 における物理関連の主な変更は、3D 物理エンジンの PhysX 3.3.3 から PhysX 3.4.2 へのアップグレードです。その時点での最新版の PhysX が搭載されるのは今回が初めてのことです。私達の目標は、パフォーマンスと安定性を向上させ、プロジェクトのアップグレードをごく簡単に行えるようにすることです。本記事では今回のアップグレードについて、Unity 2018.3 での物理演算の使用に関わる具体的な変更事項や新機能の詳細を含めてご紹介します。

PhysX 3.4 は、計算物理学の分野における数年間の進化の結晶です。従来、PhysX 新バージョンの Unity への組み込みは、そのバージョンが十分に安定したものになるまで 1 年程の期間を置いてから行っていました。今回は、可能な限りのテストを行った上で、最新のバージョンを公開します。

また今回は、既に正常に機能している中核的な部分により重点を置くために、新機能の追加は控え目にしています。目標は退行を出来るだけ無くすことです。ぜひ Unity 2018.3 ベータ版プログラムにご参加の上、お試しになってみてください!
PhysX 3.4 へのアップグレード
PhysX 3.4 は、様々な形で目に見える改善をもたらす大きなリリースです。1 つ目には、非常に多数のバグ修正が行われました。例えば、Convex 対 Convex の衝突検出とフィードバックが大幅に向上したため、PCM 衝突検出が有効になっている場合に発生していた、地面からの意図しない不規則な突起が無くなります。また、細長い三角形に対する物理クエリが改善されたほか、地形との接触計算の精度が向上しました。2 つ目には、物理エンジンによるスレッドへの物理ジョブの追加性能が大幅に向上しました。ブロードフェーズと衝突検出とソルバは記述し直されて出来る限り多くのアトミックなジョブ内に分割されました。この結果、1 フレームのシミュレートに掛かる時間が以前よりも短縮されました。

3 つ目には、物理クエリモジュールが従来の倍速になりました。

PhysX 3.4 には素晴らしい新要素が数多く追加されています。以下に、Unity 2018.3 の対応する機能について、詳しくご紹介して行きます。
マルチシーン物理
従来 Unity では、単一の物理シーンに、すべての Unity シーンからのすべてのボディとコライダーが追加されていました。当然ながら、特定のケースにおいてはこれが制約となってしまうことがあったため、今回、複数の物理シーンの作成を可能にしました。この変更により、特定の Unity シーンにデフォルトの物理シーンを使用させるか専用のローカルのシーンを使用させるかを指定することが可能となりました。追加シーンは、デフォルトのシーンとまったく同様ですが、すべての通常の Physics API に無視される点だけが異なります。これは、すべてのシーンが完全に個別に作成されるためです。追加シーンは様々な使い方ができます。追加シーンは PhysicsScene.Simulate を使って任意の周波数でシミュレートできます(ワールド内の異なる部分が異なる周波数でシミュレートされると考えてください)。またこれとは別の面白い使い方として、軌道を予測するための非表示の物理シーンを作成するために使用することもできます。この改良は、3D 物理と 2D 物理の両方に適用されます。

バッチ物理クエリの追加

バッチ物理クエリは、物理クエリをメインスレッド外で実行する方法のひとつです。通常の API を別のスレッドから実行することはできないため、この API が必要になります。Unity 2018.1 では、メインスレッド外でレイキャストを計算するのに役立つ RaycastCommand.ScheduleBatch を公開しました。Unity 2018.3 ではこれを拡張し、SphereCast、CapsuleCast、BoxCast などの、単一の結果をもたらす他のクエリも追加しました。Unity では現在、将来的なリリースに向けて、Overlap や Sweep などの複数の結果をもたらすクエリの提供を妨げている技術的制約に関して、調査を行っています。

決定論の強化

PhysX では、すべての入力がまったく同じ場合にはシミュレート結果が必ず同じになります。ところが物理エンジンの視点からは多くの要素が「入力」として扱われます。そのひとつは物理シーン自体です。2018.3 より以前は、暗示的な物理シーンの破棄は不可能でした。シーンに含まれるすべてのオブジェクトを破棄することしかできず、それでは不十分でした。これがマルチシーン物理によって簡単に回避可能になります。しかし、もうひとつ頻繁に発生していた問題は、遠くにあって一見他のオブジェクトとインタラクトしていないように見受けられる新しいボディの追加も、シミュレーションの結果を変える可能性があったことです。これは Unity の PhysX がオブジェクトを内部的にグループ分けしていたことに起因していました。この問題は、Physics Settings 内の特殊なオプションを有効にすることで回避可能となりました。パフォーマンス面で多少の負荷は掛かりますが、プロジェクトの実行を大幅に遅延させることはないはずです。

ハイトマップの統一

TerrainCollider が従来使用していた特殊な衝突検出アルゴリズムは、不正確な想定に基づいて接触の計算を行うもので、地形の厚みのような非自明的な要素もいくつか使用していました。Unity 2018.3 における衝突検出は、メッシュとの接触の計算に使用するものと同じアプローチを採用しています。

予測に基づく継続的衝突検出

Unity ではしばらくの間、連続型衝突検知が利用可能なオプションとして提供されていました。しかし、その処理がリニアな性質を持っていることがしばしば問題となっていました。内部的には「速度ベクトルに沿って、現時点から先の軌道にあるボディの走査を一定距離分行い、次の衝突までの時間を計算する」という処理が行われていました。このモデルでは角度の対応は不可能でした。

これが問題となるゲームの例として最も単純な例がピンボールです ― フリッパーは素早く回転する一方でリニアな移動はまったくしません。Unity 2018.3 では、代替的な継続的衝突検出アルゴリズムの追加によってこれが解決されました。このアルゴリズムは、接触点の生成に影響する接触オフセットを増大させることで機能します。その増大された距離に対してオブジェクトの位置が十分に近くなった時に実際に接触マニフォールドを生成します。このモードでは予測的リニア走査は使われなくなっているので、素早く回転または移動する様々なボディとの重なりを検出することから、より正確になる傾向にあります。

従来のアルゴリズム:

新しいアルゴリズム

ディレクショナル Friction

新しい Friction(摩擦)のタイプ が公開になります ― One Directional Friction Type とTwo Directional Friction Type です。デフォルトの Friction Type は 1 つの接触ペアにつき最大 4 つまでのスカラー制約を作成することで機能します。これは最も速く計算できるモデルで、収束も速く、必要とされるソルバのイテレーション回数が少なくなります。One Directional Friction Type と Two Directional Friction Type は両方とも、接触ペア毎ではなく接触点毎に機能します。これはより正確な結果をもたらし得ますが、収束するのにより多くのソルバのイテレーションを必要とし、接触ペア毎に生成される接触点の数が多い場合は、プロジェクトの実行速度が遅くなる可能性があります。

新しいプロジェクトにおける自動トランスフォームの廃止

デフォルトでは、Unity のトランスフォームへのすべての変更は、必要が見込まれる時点の直前に物理エンジンに同期されていました。つまり、レイキャストやシミュレーションが実行される度に同期されていたということです。同期の処理には少なからず時間がかかるので、その呼び出し回数の削減は理に適っています。このために、すべての自動同期ポイントをオフにする設定が提供されています。ユーザー自身が Physics.SyncTransforms を呼び出す必要があります ― これを行わなかった場合はトランスフォームはシミュレーションの直前にしか同期されません(=FixedUpdate)。

同期ポイントのもうひとつの問題は、同期自体がメインスレッドでしか実行できないことです。つまり、例えば同期を含むレイキャストは含めることができないことになります。基本的に、Unity がよりマルチスレッド指向のエンジンになるに従って、新しいプロジェクトでは自動同期ポイントをオフにしなければならないケースが多くなります。これを踏まえた上で、今回のリリースから、すべての新規プロジェクトの Physics.autoSyncTransforms のデフォルトの値を true から false に変更しています。この改良は、3D 物理と 2D 物理の両方に適用されます。

ガベージを発生させずに接触を取得

接触の情報の取得に伴ってはマネージヒープの割り当てが常に不可避でした。この割り当ては、Collision 構造体のインスタンスを、接触ポイントの配列を含めて、スクリプト内のハンドラー(例えば OnContactStay)に渡すために行われていました。しかし一部のプロジェクトでは、イベントの頻度によってパフォーマンスに悪影響を与えることがありました。

2018.3 では、新しいプロパティ Physics.reuseCollisionCallbacks が公開されました。これはデフォルトでは、既存のプロジェクトをアップグレードした際に挙動を一貫させるためにオフになっています。しかし、オンにすると Collision インスタンスが共有されます。これは事実上、コールバックが発火される度に再使用される Collision クラスのインスタンスが 1 つしかないことを意味します。この結果、ガベージが一切発生しなくなります。ただし、コールバック内で受領される衝突の情報は、必要に応じて手動でコピーされる必要があります。この改良は、3D 物理と 2D 物理の両方に適用されます。

品質向上のために

私達は、本リリースへのアップグレードをごく簡単に行えるようにすることを目標としています。これを実現するため、これまで以上にじっくり時間を掛けてテストとレビューを行う決断をしました。まず、アーリーアダプターの皆様にビルドを提供させていただきました。次に、限定的な機能アップグレードを Unity 2018.2 に実装し、それを 2018.2 アルファ版の期間中にテスト用のスピンオフビルドとして入手可能としました。そしてバージョン 2018.2 の一般公開後にフォーラムでスレッドを立ち上げ、熱心なユーザーの皆様にフィードバックの提供をお願いしました。結果、生産的な意見交換が成され、いくつかのバグ修正と機能追加が行われました。2018.3 ベータ版の公開後、そこにアップグレードブランチをマージし、これが現段階では一週間に 10000 件を超えるエディターのセッションで使用されています。Unity では引き続きフィードバックを募集していますので、ぜひベータ版にご参加のうえ、Physics フォーラムまたは 2018.3 ベータ版フォーラムに投稿をお寄せください!

35 コメント

コメントの配信登録

コメント受付を終了しました。

  1. When will we be able to receive the collision message before the collision solver is called?

  2. Glad directional friction and convex-convex collision detection and feedback are being fixed. I’ve been stuck on Unity 5.4 because of the convex thing. Also had to create my own directional friction when that was suddenly taken out in the PhysX 3 update of Unity 5.

  3. Kimmo Keskinen

    1月 3, 2019 2:05 pm

    Would possibly be helpful to hear a more in-depth explanation on the added developer responsibility of calling Physics.SyncTransforms in code; examples on cases where to use etc.

  4. fantasitic software

  5. lolthatdidntworkoutasplanned

    12月 8, 2018 12:30 am

    lol nope you are not shipping with the latest since 4.0 will be available soon :)

  6. Is there any chance of getting inverted primitive colliders, e.g. sphere, capsule, box colliders that act as containers so things on the outside can get in but anything inside can’t get out. I know this can be done with a mesh with flipped normals and mesh colliders, but with a performance cost.

  7. Well since nobody has asked, does this mean we might actually be able to have physics-based networked character controllers now, or must we continue with the faked raycast stuff?

  8. Yevhen Bondarenko

    11月 21, 2018 1:42 pm

    Great work! :)
    Can’t wait to try out all new features in the full release.

    Quick question: in Nvidia docs it is said that Trigger/Trigger collision callbacks are getting deprecated in PhysX 3.4.2. Will we still receive them in Unity when two Triggers collide?

    1. Anthony Yakovlev

      11月 21, 2018 5:08 pm

      Yes, I can confirm you’re still going to receive the trigger/trigger events going forward.

      1. Yevhen Bondarenko

        11月 22, 2018 2:02 pm

        Perfect!!

        Is there already an approximate release date for 2018.3 available (when it goes out of beta)?

  9. Luke Mitchell

    11月 20, 2018 11:07 am

    When is 2018.3.0b11 being released? I’m looking forward to the garbage free collision callbacks in it, as none of my projects will open in the alpha versions which include it. I feel like a little kid waiting for Christmas. :)

  10. Is there somewhere we can read more about Multi-scene physics? Is this already playable with in the 2018.3 beta? I’m curious specifically if this will allow us a new alternative to floating point precision correction issues, especially for a headless authoritative server attempting to control multiple players across vast distances.

  11. Tyler Befferman

    11月 16, 2018 6:11 pm

    Will Physics.BoxCast, CapsuleCast, etc. be updated to support rotating collisions?

    1. Anthony Yakovlev

      11月 17, 2018 1:16 pm

      Could you elaborate? Not sure I understand the question right I’m afraid. Thanks.

      1. Tyler Befferman

        11月 19, 2018 5:51 pm

        From the blog post:
        “Continuous collision detection has been an option in Unity for a while. However, the linear nature of the process was a common problem. All it did internally was to sweep the bodies some specific distance forward along the velocity vector to compute the time until next hit. This model didn’t allow for rotations support.”

        Physics.BoxCast and CapsuleCast currently share this problem since they only support linear sweeps. I was wondering if these methods will be updated to support continuous collision detection for rotation, perhaps by adding an angular velocity parameter. The blog post makes it sound like the speculative continuous collision detection added in 2018.3 will only be available on rigid bodies, but I prefer using the Physics API in my game because it is more flexible in some scenarios.

        1. Anthony Yakovlev

          11月 20, 2018 10:14 am

          Sorry for the confusion. As pointed out above, speculative collision detection doesn’t rely on sweeps — it’s a completely different approach based on inflating the contact offsets.

  12. Is there an download for that pool table physics scene example?

  13. Isaac Surfraz

    11月 13, 2018 10:08 am

    This is absolutely magical. thanks for this!

  14. 这些更新听起来很不错!期待Physics.reuseCollisionCallbacks的使用。

  15. This is a great update! Nice one!

  16. Doug Richardson

    11月 12, 2018 8:06 pm

    Physics.reuseCollisionCallbacks doesn’t appear to be available yet in 2018.3.0b9. What is the ETA for that API?

    1. It’s in 2018.3.0b11 & 2019.1.0a7.

  17. Ian Pretorius

    11月 12, 2018 6:08 pm

    Thanks for the updates , it is going to be a great improvement a quesion i have is when is the unity rigidbody going to have options for quadratic drag??

  18. A good API is nothing without good documentation, the ConfigurableJoint is very powerful but still lacks decent documentation … how come it’s been neglected for so long ?

    https://docs.unity3d.com/Manual/class-ConfigurableJoint.html

  19. Very nice! Thanks a lot!

    When receive contact enter or stay, How we can get contact force ?

    1. Anthony Yakovlev

      11月 13, 2018 10:43 am

      Use Collision.impulse. It’s the same as force applied over the span of delta time.

  20. Excellent and directional friction!
    Only thing you could help with is joints. Those things are soo awkward to setup, just trying to simulate some suspension for a dropped car (not a full wheel collider car) seems very hard to work out with spring joints

    1. Anthony Yakovlev

      11月 13, 2018 10:41 am

      Thanks for the feedback. As to the quality of joints simulation — we’ll be bringing articulation joints based on Featherstone’s algorithm soon. Those are not as stretchy as the ones we have currently. Concerning the difficulty of configuring the SpringJoint — not exactly sure what you mean by that, but maybe a natural frequency/damping ratio model would work better than raw stiffness/damper value?

      1. Well spring joint seems to just be a loose wobbly spring and not configurable as a suspension arm (or fixed-axis spring) which some might expect or want. Is there any way to recreate a suspension-arm (with local axis) beyond the wheel collider?

        1. Anthony Yakovlev

          11月 13, 2018 2:19 pm

          The SpringJoint is just that — a simple spring that attracts two objects towards each other. What you describe sounds directly achievable with a ConfigurableJoint if you lockout the relative rotations and enable only one degree of local linear freedom.

  21. physX 3.4.2 means better wheel collider too?

    1. Like one that has full wheels not just a downward facing ray?! If only

      1. yeah really hoping that they added ShapeCast or MeshCast into the physics system, that would be a great improvement for wheel collider

  22. Best upgrade to physics for a very long time :) thank you very much (all of this is useful to me in my main project!)

    1. Anthony Yakovlev

      11月 13, 2018 10:44 am

      Thanks!