投稿日更新日

【DOTS】Unity Physicsで大量のオブジェクトの物理演算を試す

はじめに

前回の記事でUnity Physicsの公式デモを触ってみました。

今回はUnity Physicsの真価を見るために、大量のオブジェクトを準備して物理演算してみようと思います。

検証環境

  • 機種: MacBook Air(m1)
  • OS: MacOS Monterey(12.3.1)
  • メモリ: 8GB
  • Unity: 2021.2.16f1(SILICON)

参考動画

Youtubeに、Unity Physicsを使ってキューブのタワーを召喚して、それを崩すような動画がありました。 動画の検証環境は、i7-8700k、GTX1080tiというかなり高スペックなPCです。

僕のM1 Macでは、どのくらいのオブジェクト数、FPSで処理できるか試してみたいと思います。

プロジェクトの準備

前回使用したUnity Physicsのデモプロジェクトを使いますので、Unityで開いてください。

SceneとPrefabの準備

Sceneを作成する

適当にSceneを作りましょう。

Planeを配置する

HierarchyからPlaneを配置します。 Scaleは(50,1,50)に設定しました。

次のようにコンポーネントを設定します。

  • Convert To Entityを追加
  • Physics Shapeを追加
  • Mesh Colliderを削除

キューブのPrefabを作成する

まず、HierarchyからCubeを配置します。

次のようにコンポーネントを設定します。

  • Convert To Entityを追加
  • Physics Bodyを追加
  • Physics Shapeを追加
  • Box Colliderを削除

最後にキューブをPrefabディレクトリにドラッグして、プレハブを生成します。

キューブをジェネレートするスクリプトを書く

TowerGeneratorという名前でスクリプトを作成します。 下のプログラムを入力してください。

using System.Collections; using System.Collections.Generic; using UnityEngine; using Unity.Entities; using Unity.Transforms; using UnityEngine.UI; public class TowerGenerator : MonoBehaviour { public GameObject cubePrefab; public int length; public int width; public int height; private Entity _cubeEntity; private EntityManager _entityManager; private BlobAssetStore _blobAssetStore; private GameObjectConversionSettings _settings; void Start() { _entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; _blobAssetStore = new BlobAssetStore(); _settings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, _blobAssetStore); _cubeEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(cubePrefab, _settings); for (int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { for (int l = 0; l < length; l++) { if (l != 0 && w != 0 && l != length - 1 && w != width - 1) { continue; } Entity cube = _entityManager.Instantiate(_cubeEntity); Translation cubeTranslation = new Translation { Value = new Unity.Mathematics.float3(l, h + 0.5f, w) }; _entityManager.SetComponentData(cube, cubeTranslation); } } } } private void OnDisable() { _blobAssetStore.Dispose(); } // Update is called once per frame void Update() { } }

スクリプトのアタッチ

作成したスクリプトを、シーン上のどのオブジェクトでもいいのでアタッチしてください。 キューブのプレハブをセットするのと、生成するタワーの大きさを設定します。 一旦全て10でやってみます。

実行

動画のように、キューブのタワーが生成されて崩れる様子が見れました。

キューブの数を増やす

タワーの大きさのパラメータを変化させて、実行時のFPSを測ります。 FPSの表示には、Lite FPS Counterというアセットを使用しました。

動画ではフレームレートが揃えられて滑らかに動いていますが、実行時には割とカクカクしています。

パラメータを全て50にした場合

フレームレートは20FPS前後でした。 動画はこちら

パラメータを全て100にした場合

動画のような感じです。フレームレートは8FPS前後でした。 動画はこちら

おわりに

今回は、UnityPhisicsを使って大量のオブジェクトの物理演算をしてみました。

M1 MacでもFPSこと下がりましたが、数万個のオブジェクトの物理演算ができるのはDOTSの恩恵だなと思います。 リアルタイム演算は難しいかもですが、動画のためにレンダリングする等の用途であれば、十分に使えそうです。

みなさまもUnity Physicsを応用されてみてください。

関連記事

に投稿

【Unity】Arduino Uno R4 Minimaとシリアル通信しようとしたらできなかった話

に投稿

【Unity】MediaPipeUnityPluginを使って超簡単に指認識をM1 Macで試す

に投稿

【Unity】M1 Macで"The Progressive CPU lightmapper is not supported on Apple silicon, switching to the Progressive GPU lightmapper."と警告が出たときの対処法

に投稿

【Unity】Mapbox SDKでマップ上の任意の緯度経度の座標にオブジェクトを配置する

に投稿

【Unity】Mapbox Maps SDK for Unityで3D地形マップを召喚する

© 2022 はるとんのブログ