新機能紹介
Quantum SDK 3.1は、Quantum 3のパフォーマンスとスケーラビリティを向上させています。
現在開発中(今後提供予定)の機能や改善点については、ロードマップをご覧ください。
Table Components(テーブルコンポーネント)
QuantumのECSはこれまで、コンポーネントの値の保存にスパースセットのみを使用していました。各コンポーネント型には、エンティティと値を紐づけるスパースセット(辞書の一種)が関連付けられていました。
スパースセットのコンポーネントは、追加/削除が高速ですが、異なる順序で格納されている異なるエンティティに対して、複数を一度に反復処理を行うと速度が低下してしまいます。フィルターは通常、最初のコンポーネントの値のみをシーケンシャルアクセス可能で、それ以外はランダムなルックアップを必要とします。
Quantum 3.1では「table(テーブル)」と呼ばれる新しいコンポーネントストレージが追加されました。テーブルはすべてのエンティティのコンポーネントの配列を保存し、そこに特定のテーブルコンポーネントの組み合わせが含まれています。テーブル内の各エンティティは、各「列(配列)」の「行(インデックス)」になります。エンティティのテーブルコンポーネントを変更する際は、異なるテーブルへ移動させる必要があります。
テーブルコンポーネントでは、利点と欠点が逆転します。反復処理が高速な分、追加/削除は遅くなります。
デフォルトでは、コンポーネントはスパースセットを使用します。テーブルを使用するには、DSLのコンポーネント宣言にtableキーワードを追加するだけです。
table component Health {
FP Value;
}
同じエンティティ内で、テーブルとスパースセットを自由に組み合わせることが可能なため、両方の利点を最大限に活用できます。APIは従来のものと変わりませんので、コードの変更は不要です。なお、組み込みコンポーネント(Transform・ Collider・PhysicsBodyなど)は、すべてテーブルで保存されるようになっています。
新しい物理ソルバー
Quantumの物理エンジンはステートフルになり、ウォームスタートを備えたProjected Gauss-Seidelソルバーが搭載されました。(従来の動作を維持したい場合、従来のソルバーを選択することも可能です)
この新ソルバーは時間的コヒーレンスを活用して、従来のソルバーと比較して主に2つの点が改善されています。
- 優れたスタック処理:複数のフレームに渡って適切な解に収束させることで、物体のスタックや複雑なジョイント(例:ラグドール)など、複雑な制約のシステムを処理することが可能になりました。
- オーバーシュートの軽減:反復処理が相互に関連するようになり、中間のオーバーシュートを補正できるため、より正確な解が得られるようになりました。
新しいソルバーによる物体のスタック:
従来のソルバーによる物体のスタック:
ヒープとメモリストレージの改善
Quantum 3.1では、フレームのヒープにいくつかの改良が加わっています。
- 大型ブロック:ブロックはページサイズに制限されなくなりました。補助メモリのチャンク全体(「セグメント」と呼ばれる)を、一つのブロックとして割り当てることも可能です。
- 遅延拡張:フレームのヒープが既存のメモリセグメントを使い切った場合は、新しいメモリ割り当てが行われます。
新種のフレームのヒープを導入し、同一サイズのブロックではなく可変サイズのブロックを保持できるようにすることで、ヒープの断片化を軽減できます。このヒープを使用するには、SimulationConfigで「block-based」ヒープ管理を選択してください。
スパースセットのコンポーネントのブロックも、遅延割り当てが行われるスパースバッファチャンクで再実装されました。これによって、エンティティとコンポーネントが大量にあるケースにおいて、フレームのCopyFrom呼び出しにかかる時間が大幅に削減されます。
シミュレーターのコールバック
新しいコールバックによって、シミュレーターの内部処理の一部がSimulatorContextを通して公開されます。これによって、シミュレーションフローに関する情報の取得や制御が可能になります。
これらは、シミュレーション処理を厳密に制御する必要があるプロジェクトで便利です。
- シミュレーター統計:確定/予測フレーム数・目標ティック・現在のステージ・ストール状態などを取得できます。
- 予測ロールバックのスキップ:予測精度とパフォーマンスのトレードオフのため、選択的に予測ロールバックをスキップします。ただし、ロールバックは最終的に必ず実行する必要がある点に注意してください。これによって、「ロールバックや再シミュレーションを行わずに、確定フレームを複数回進める」「複数回進められるだけ確定フレームが存在しない場合は、ロールバックして完全な再シミュレーションによって予測ミスを修正する」を実行できます。
- シミュレーション数の制限:各更新において、確定/予測するティック数を制限します。実践的に上記の機能と組み合わせることで、可能な限りスムーズなパフォーマンスを実現できます。
新しいコールバックは、シミュレーションの確定/予測ステージの前後で呼び出されます。
さらに、SimulationFinishedなどの既存のコールバックもSimulatorContextを持つようになりました。
| コールバック | 説明 |
|---|---|
| CallbackBeforeSimulationStage | 各シミュレーションステージ(確定/予測)の開始前に一度呼び出されます。 |
| CallbackSimulationStageFinished | 各シミュレーションステージ(確定/予測)の終了時に一度呼び出されます。 |
| CallbackSimulateFinished | フレームのシミュレーション(確定/予測)が完了した際に呼び出されます。 |
ロードマップ
これらは、現在開発中またはアーリーアクセス期間中に実装予定の機能です。一部は将来のメジャーリリースに延期される可能性がありますが、新しいSDK 3.1の安定版では完成する予定です。
- 3Dキャラクタージョイント:(テスト中)ラグドールや、ボールソケット型ジョイントの適用を可能にします。
- ステートフルな物理エンティティ:(テスト中)より大量のオブジェクトが使用可能になります。
- AdditiveなQuantumマップ:(開発中)実行時に複数のマップをロード可能にします。
- 複合エンティティプロトタイプ:(開発中)エンティティのグループが簡単にスポーン・リンク可能になります。
- 決定論的ナビメッシュベイク:(開発中)Unityナビメッシュベイクを決定論的に置換します。
- フレームコピーのパフォーマンス改善:(実装予定)補間や誤差修正にのみ使用される2つの余分なフレームのコピー(
PredictedPreviousとPreviousUpdatePredicted)を回避します。完全なフレームデータではなく、必要なtransformデータ(エンティティビュー用)のみを保存します。