3DGS シーンを歩く:コリジョン対応
LCC4Unreal はコリジョンデータの動的読み込みに対応しており、キャラクターが 3DGS の世界を自由に歩き回ってインタラクションできる。
前提条件
コリジョンはデータに付属するコリジョンファイルに依存し、形式によって要件が異なる。
| 形式 | コリジョンデータ | 対応状況 |
|---|---|---|
.lcc | データディレクトリ内の collision.lci。旧バージョンは collision.bin | 対応 |
.lcc2 | データディレクトリの data/mesh/ 内の .ply ファイル | 対応 |
.sog / .spz / .ply | データ自体には含まない。Pro 版はガウシアンから自動生成できる | 対応(Pro 版) |
.lcc と .lcc2 については、プラグインが collision.lci → collision.bin → data/mesh/*.ply の順でデータに付属するコリジョンファイルを検出し、3 つとも存在しない場合は警告を出力してコリジョンを無効にする。
単一ファイル形式(.sog / .spz / .ply)はデータ自体にコリジョンデータを持たない。Pro 版はガウシアンからコリジョンメッシュを自動生成できる(単一ファイルモデルのコリジョン自動生成を参照)。無償版ではコリジョンを自分で構築する必要がある。
データを読み込んだ後、HaveValidCollisionData() で現在のデータに使用可能なコリジョンデータが含まれているかを確認できる。
注:
collision.lciは LCC Studio v1.6.1 以上のバージョンでエクスポートする必要がある。それより古いバージョンでエクスポートしたデータはcollision.binを使う。
読み込みの仕組み
コリジョンデータはレンダリングデータと同様に空間ごとのブロックに分けて格納されている。プラグインはコリジョンを一度にすべて読み込むのではなく、カメラ周辺の一定範囲内のブロックだけを読み込み、カメラの移動に応じて動的に入れ替える。
カメラ位置が変化する
│
▼
範囲内で読み込むべきコリジョンブロックの集合を計算する
│
▼
前回の集合と比較する ── 同じ ──▶ スキップして何も処理しない
│ 異なる
▼
新しいブロックを読み込む → 物理システムにベイクさせる → コリジョンボディを生成する
実装上のポイントをいくつか挙げる。
- 読み込み範囲は
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 メートル) |

コリジョンの有効状態と最大読み込み距離を設定する
単一ファイルモデルのコリジョン自動生成(Pro 版機能)
単一ファイルモデル(.ply / .spz / .sog)はデータ自体にコリジョンデータを持たない。プラグインはガウシアン自体からコリジョンメッシュを生成し、モデルの隣に <名前>.collision.ply としてキャッシュする。以降は既存の PLY コリジョン経路で読み込んで再利用する。
これは Pro 版機能であり、App Key を登録して初めて生成される。エディションとライセンス を参照する。未ライセンスではコリジョンメッシュを生成しないため、自動生成を使わない場合の手動の手段に従って自分で構築する必要がある。
使用手順
- LCC Actor のパネルで bEnableCollision にチェックする。
- 単一ファイルモデル(
.ply/.spz/.sog)を読み込む。 - 初回の読み込みでは
Generating状態に入り、その場でコリジョンメッシュを生成する。所要時間はデータ量に応じて数秒から数分かかる。生成が完了するとLoadedに移り、モデルの隣に<名前>.collision.plyが書き出される。 - 以降、同じモデルを再度読み込むと、キャッシュファイルがあればそのまま
Loadedになり、生成をスキップする。

コリジョンを有効にすると、単一ファイルモデルの初回読み込み時に右下にコリジョンメッシュ生成中の通知が表示される
生成とコリジョンの状態は GetCollisionState() でクエリするか、OnCollisionStateChanged イベントをリッスンして取得できる。取りうる値は ULCCComponentBase - 状態クエリ を参照する。
ヒント:実行時に生成を省きたい場合は、生成済みの
<名前>.collision.plyをモデルと一緒に配布またはパッケージ化すればよい。実行時にキャッシュを検出すればそのまま再利用する。ヒント:パッケージ化したゲーム内でコリジョンを生成する際には組み込みの UI 通知がない。「コリジョンを生成中」とプレイヤーに知らせるには、
OnCollisionStateChangedのGenerating状態をリッスンして自分で表示する。ヒント:生成に失敗すると
Failed状態に移る。具体的な原因は Output Log を参照する。コリジョンをいったんオフにして再度オンにすると再試行できる。生成過程を再テストしたい場合は、先にモデルの隣の.collision.plyキャッシュファイルを削除する。
自動生成を使わない場合の手動の手段
コリジョンの形状を完全に制御したい場合、またはデータが生成に適さない場合は、自動生成を有効にせず、シーン内に自分でコリジョンを構築することもできる。
- Blocking Volume:エンジンのブロッキングボリュームで地面や壁など遮る必要のある領域を組み立てる。規則的な形状に適し、コストが最も低い
- 近似メッシュ:3DGS の形状に合ったメッシュを配置してそのコリジョンを有効にする。形状が複雑なシーンに適する。このメッシュは プロキシメッシュ を再利用でき、コリジョンプリセットを遮りに参加する設定に変更すればよい
この手動の 2 つの方法は LCC のコリジョン読み込みの仕組みとは無関係で、CollisionLoadMaxDistance の影響を受けず、カメラの移動に応じて動的に入れ替わることもない。
コリジョン領域のクリッピング
コリジョンは クリッピングボリュームと断面プレーン に合わせてクリッピングでき、コリジョンの範囲をレンダリング画面と一致させられる。クリッピングボリュームは既定ではレンダリングにのみ作用し、切り取られた領域は画面が消えてもコリジョンは残るため、キャラクターが見えない壁にぶつかってしまう。Clip Collision を有効にすると、コリジョンもクリッピング領域内で同時に取り除かれる。
使用手順
- シーン編集 に従って LCC Actor にクリッピングボリュームまたは断面プレーンを追加して設定し、レンダリング画面が想定どおりにクリッピングされていることを確認する。
- LCC Actor のパネルで コリジョンを有効にする(bEnableCollision) にチェックする。
- パネルで Clip Collision にチェックすると、コリジョンがクリッピングボリュームに従って切り取られ、切り取られた領域にはコリジョンボディが生成されなくなる。
下図は「Visibility Collision」ビューモードで Clip Collision のオン・オフ前後のコリジョンのワイヤーフレームを比較したものである。オフのときはコリジョンが領域全体を覆う。

「Clip Collision」未チェック:コリジョンのワイヤーフレームが領域全体を覆う
有効にすると、クリッピングボリューム内のコリジョンも一緒に切り取られ、レンダリングと一致する。

「Clip Collision」チェック:クリッピング領域内のコリジョンも一緒に切り取られる
ヒント:Clip Collision はコリジョンを先に有効にしておく必要があり、単一ファイルモデルで自動生成したコリジョンにも同様に有効である。
コリジョン状態のクエリとイベント
コリジョンの現在の状態をクエリしたり、コリジョン状態の変化をリッスンしたりできる。「コリジョンが準備できてからキャラクターを配置する」「生成中は進捗を表示する」といったロジックに使える。
GetCollisionState()は現在の状態を返す:NoCollision(オフ、またはモデルがない)/Generating(単一ファイルモデルがコリジョンメッシュを生成中)/Loading(カメラ付近のコリジョンを読み込み/cook 中)/Loaded(カメラ付近のコリジョンが準備完了)/Failed(提供できない)。OnCollisionStateChangedイベントは状態が変化したときにディスパッチされ、Loadedの後にキャラクターの移動を有効にしたり、Generatingのときに通知を表示したりできる。
完全な API と使用上の約束は ULCCComponentBase - 状態クエリ を参照する。
ヒント:
Loadedはカメラ付近のコリジョンが準備できたことを指し、モデル全体にコリジョンがあることを意味しない。コリジョンはカメラの移動に応じて継続的にストリーミング読み込みされる。「足元で地面をすり抜けない」ことが必要ならLoadedを待てばよく、遠くのコリジョンが必要なら読み込み距離を大きくする。
注意事項
- コリジョンを有効にすると、UE エンジン自身の LineTrace でコリジョンボディに基づいたレイキャストを行える。検出範囲も同様に読み込み範囲の制限を受ける
- コリジョンデータが使用するメモリは
stat xgridsのCollision Data Usageで確認でき、更新の処理時間はUpdate Collisionで見られる。パラメーターの意味は パフォーマンスパラメーター を参照する