テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】新しい物理演算、Unity Physicsについて

f:id:tsubaki_t1:20190420231232g:plain

Unity Physicsについて紹介します。

Unity Physicsとは?

Unity Physicsは、ECS上で物理演算を動かす為の追加機能です。この物理演算は過去Unityが使用してきた実績と安心のPhysXではなく、完全に新しくC#で作り直した物理演算になります。

Physicsの役割としては下の二通り。

  • 空間を探索して衝突等を探索する(接触判定、線形判定)
  • オブジェクトを実際に動かす(重力、バウンド、摩擦等)

f:id:tsubaki_t1:20190420215138j:plain

Unity Physicsはステートやキャッシュを行わず、複雑な衝突計算に対応しない代わりに軽量です。

また直前の状況に惑わされずその場その場で計算を行うという関係上、ネットワークといった事前状況がバラバラのゲームに向いていると言えるかもしれません。特にゲームでColliderを使用しているけど当たり判定しか使用していないといったケースでは、コチラのほうが良いと言えるのかもしれません。

従来のようなステート有りの物理演算向けとして、内部挙動をUnity PhysicsとHavok Pluginで切り替える事が出来るみたいです。 Havok Pluginでは複雑な状態を管理するのに向いているとの事。まだHavok Pluginはまだ公開されていません。

f:id:tsubaki_t1:20190420220552j:plain

なお現行のPhysXベースのColliderとUnity PhysicsのColliderは接触しません。Unity Physicsを使用する場合は他の全てのColliderをUnity Physics向けに変換する必要が出ます。

事前準備

導入環境はこちら

  • Unity 2019.1f2
  • Unity Physics preview1 0.0.2
  • Hybrid Renderer preview10 0.0.1

f:id:tsubaki_t1:20190420221316j:plain

Hybrid Rendererは実際には無くても良いのですが、描画関連を記述するのが面倒くさいので、Hybrid Rendererパッケージを導入します。*1

とりあえずシーンを用意

まずは、Roll a Ballよろしく板と玉を用意して、玉にRigidbodyを設定します。

再生すると下のように玉が坂を転がります。まだPhysXを使用している状態です。

f:id:tsubaki_t1:20190420222657g:plain

Unity Physicsに移行

Unity Physicsに移行します。

  • SphererにConvert To Entityを追加します。
  • PlaneにConvert To Entityを追加します。

これでSphereとPlaneオブジェクトは GameObjectからECSベースのUnity Physicsに変換 されます。

f:id:tsubaki_t1:20190420222954j:plain

f:id:tsubaki_t1:20190420223148j:plain

変換後は下のように、幾つかのComponentDataに変換されています。Entityを操作する場合はRigidbodyではなく下のコンポーネントを云々する必要がある点に注意してください。

f:id:tsubaki_t1:20190420225154j:plain

また動的にオブジェクトを増やす場合は下の記事を参考に。

tsubakit1.hateblo.jp

ステージのような大量の当たり判定のある物を一気にロード

Convert To Entityを使うのは悪くないのですが、これだと実行時に下のようなフローが入って勿体無い気もします。

  1. シーンをロード
  2. GameObjectをデシリアライズ
  3. Componentをデシリアライズ
  4. ComponentDataを生成
  5. GameObjectの破棄
  6. Convert To Entityの数だけ繰り返す

なのでサブシーンとして一気にデシリアライズしてしまいます。

  • 「とりあえずシーンを用意」の状態からスタート
  • SphererとPlaneを選択して右クリック
  • New SubScene from Selectionを選択
  • SubSceneコンポーネントのCloseを押す

これでステージ上のGameObjectがEntityに変換され、デシリアライズをほぼ挟まずにロード出来るようになります。

f:id:tsubaki_t1:20190420224852g:plain

新しく増えた設定を使いたい

Unity PhysicsはSubSceneやConvertToEntityでGameObjectのRigidbodyから変換するフローが用意されていますが、独自のコンポーネントも用意されています。

まず○○Collider系は、全てPhysicsShapeに統合されています。ねんがんの形状「Plane」も追加されているので、割と良いです

f:id:tsubaki_t1:20190420225530p:plain

Rigidbodyは`PhysicsBodyになります。

f:id:tsubaki_t1:20190420230215j:plain

パフォーマンス

PhysXと比べてどう?というのは機能の方向性が違うのでフェアな比較方法が思いつかなくてアレですが、非常に分かりやすい注意点として「エディターで動かすと遅い」というのがあります。

DOTS系は総じてそうなのですが、このUnity Physicsも同じくエディターで動かすと非常に遅く、IL2CPPでビルドすると化けます。 また実行直後(というかBurstのコンパイルが完了していない間*2)は更に遅いです。

コード制御関係

次で。

関連

Unity Physicsについての説明。意外とエグいと思ったのは自分だけではないと思いたい

www.youtube.com

紹介の公式ブログ

blogs.unity3d.com

nakamura001.hatenablog.com

*1:壊れてると思ったら古いAPIだった

*2:Burstはエディターで実行時に非同期でコードをコンパイルする。何故かキャッシュしてくれない