3DGS シーンを歩く:コリジョン対応
LCC4Unreal はコリジョンデータの動的読み込みに対応しており、キャラクターが 3DGS の世界を自由に歩き回ってインタラクションできる。
前提条件
コリジョンはデータに付属するコリジョンファイルに依存し、形式によって要件が異なる。
| 形式 | コリジョンデータ | 対応状況 |
|---|---|---|
.lcc | データディレクトリ内の collision.lci。旧バージョンは collision.bin | 対応 |
.lcc2 | データディレクトリの data/mesh/ 内の .ply ファイル | 対応 |
.sog / .spz / .ply | なし | 非対応 |
プラグインは collision.lci → collision.bin → data/mesh/*.ply の順で検出し、3 つとも存在しない場合は警告を出力してコリジョンを無効にする。データを読み込んだ後、HaveValidCollisionData() で現在のデータに使用可能なコリジョンデータが含まれているかを確認できる。
注:
collision.lciは LCC Studio v1.6.1 以上のバージョンでエクスポートする必要がある。それより古いバージョンでエクスポートしたデータはcollision.binを使う。
単一ファイル形式の代替手段
.sog、.spz、.ply は単一ファイル形式でコリジョンデータを持たないため、プラグインはコリジョンを生成できない。コリジョンが必要な場合はシーン内に自分で用意する。
- Blocking Volume:エンジンのブロッキングボリュームで地面や壁など遮る必要のある領域を組み立てる。規則的な形状に適し、コストが最も低い
- 近似メッシュ:3DGS の形状に合ったメッシュを配置してそのコリジョンを有効にする。形状が複雑なシーンに適する。このメッシュは プロキシメッシュ を再利用でき、コリジョンプリセットを遮りに参加する設定に変更すればよい
どちらの方法も LCC のコリジョン読み込みの仕組みとは無関係で、CollisionLoadMaxDistance の影響を受けず、カメラの移動に応じて動的に入れ替わることもない。
読み込みの仕組み
コリジョンデータはレンダリングデータと同様に空間ごとのブロックに分けて格納されている。プラグインはコリジョンを一度にすべて読み込むのではなく、カメラ周辺の一定範囲内のブロックだけを読み込み、カメラの移動に応じて動的に入れ替える。
カメラ位置が変化する
│
▼
範囲内で読み込むべきコリジョンブロックの集合を計算する
│
▼
前回の集合と比較する ── 同じ ──▶ スキップして何も処理しない
│ 異なる
▼
新しいブロックを読み込む → 物理システムにベイクさせる → コリジョンボディを生成する
実装上のポイントをいくつか挙げる。
- 読み込み範囲は
Max Load Collision Distance(m)で制御し、この距離を超えた領域にはコリジョンがない - 初回の読み込みは同期的で、コリジョンが準備できていない状態でキャラクターが地面をすり抜けて落下するのを避ける。それ以降の更新はすべて非同期で、メインスレッドをブロックしない
- 頻度のスロットリングがあるため、カメラが連続的に移動してもフレームごとにコリジョンを再構築することはない
- 可視ブロックの集合が変化していない場合は直接スキップするので、その場でわずかに動いても再構築はトリガーされない
- メインカメラのみで計算するため、SceneCapture はコリジョンの読み込みに参加しない
利点
- メモリ使用量は読み込み範囲だけに関係し、データの総量とは無関係なので、大規模シーンでもコリジョンに対応できる
- 物理システムが処理するコリジョンボディの数が常に制御可能で、シーン規模が大きくなっても物理計算が遅くならない
代償と回避方法
| 問題 | 原因 | 回避方法 |
|---|---|---|
| ゲーム開始の瞬間にキャラクターが地面をすり抜けて落下する | コリジョンの構築が完了していない | PlayerStart を少し高い位置に上げる、またはコリジョンが準備できてからキャラクターの移動を有効にする |
| キャラクターが遠くから 3DGS シーンの範囲に入るとカクつく | スポーン地点がコリジョン読み込み範囲外にあり、初回進入時に同期読み込みが発生する | スポーン地点をコリジョン読み込み範囲内に配置する、またはコリジョンを一度にすべて読み込む |
| 遠くにコリジョンがなく、レイキャストが当たらない | 読み込み範囲を超えた領域はコリジョンボディを生成しない | Max Load Collision Distance(m) を大きくする、またはコリジョンに依存しない判定方法に変える |
| テレポートや高速移動の直後、短時間コリジョンがない | 新しい領域のコリジョンブロックがまだ読み込み中である | コリジョンを一度にすべて読み込む |
移動中にカクつきが出て Update Collision の処理時間が長い | コリジョンブロックの入れ替えとベイクが頻繁に起きている | 読み込み範囲を縮める、またはコリジョンが本当に必要かを確認する |
| ナビゲーションと併用するとナビゲーションメッシュが繰り返し再構築される | コリジョンの変化が NavMesh の更新をトリガーしている | 読み込み範囲を大きくして対象領域を一度に読み込み終え、Static のベイクを使う。詳しくは ナビゲーションシステム対応 を参照する |
コリジョンを一度にすべて読み込む
上記の代償のほとんどは実行時の動的な入れ替えに由来する。シーン規模が限られていてメモリに余裕がある場合は、Max Load Collision Distance(m) をシーン全体を覆えるほど大きくして、データ読み込み時にコリジョンを一度にすべて構築させることができる。
こうすると実行時にコリジョンブロックの入れ替えが起きなくなり、前の表にあった地面のすり抜け、テレポート後のコリジョンなし、移動中のカクつき、ナビゲーションの繰り返し再構築はいずれも発生しない。ナビゲーションシステムと併用する場合は特に推奨する。
引き換えに起動時の読み込み時間が長くなり、メモリ使用量はシーン全体のコリジョンのサイズで固定される。実行可能かの判断は、stat xgrids の Collision Data Usage を見て、全量読み込み後のメモリ使用量が許容範囲内かを確認する。
有効にする
LCCComponent->SetLCCCollisionEnable(true);
または Details パネルで bEnableCollision をチェックする。

Details パネルで LCC のコリジョンを有効にする

LCC シーン内でのキャラクターの動的コリジョンの効果
検証
ビューモードの設定で Player Collision または Visibility Collision を選ぶと、コリジョンが有効になっているかを観察できる。

Player Collision または Visibility Collision モードでコリジョンボディを検証する
関連するプロパティ
| プロパティ | 説明 |
|---|---|
| bEnableCollision | コリジョンを有効にする |
| CollisionLoadMaxDistance | コリジョンデータの最大読み込み距離(既定値 300 メートル) |

コリジョンの有効状態と最大読み込み距離を設定する
注意事項
- コリジョンを有効にすると、UE エンジン自身の LineTrace でコリジョンボディに基づいたレイキャストを行える。検出範囲も同様に読み込み範囲の制限を受ける
- コリジョンデータが使用するメモリは
stat xgridsのCollision Data Usageで確認でき、更新の処理時間はUpdate Collisionで見られる。パラメーターの意味は パフォーマンスパラメーター を参照する