テラシュールブログ

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

【Unity】CullingGroupについて

CullingGroupとは

CullingGroupは、見えないオブジェクトや遠いキャラクターのギミックに対して制御を行うためのAPI群です。
大きな機能は二つ、「オブジェクトが実際に見えている場合、もしくは見えない場合にのみ処理を行う」と「オブジェクトとの相対距離で処理を切り替える」といった物です。

docs.unity3d.com

オブジェクトが実際に見えている場合のみ処理を行う

3Dゲームにおいて「見えている判定」というのは非常に難しい問題です。実際に目に見えていなくとも、ピクセルが塗られていなくとも、3D空間内には描画されているケースが多々あります。これはOcclusionCullingによって不要な部分を表示しないようにする事が可能です。

http://cdn-ak.f.st-hatena.com/images/fotolife/t/tsubaki_t1/20150422/20150422221909.gif

tsubakit1.hateblo.jp

今回の話のCullingGroupは、OcclusionCullingと似たような感じで、カメラから見えているかの判定をスクリプトから取得し、処理をスキップしたりする事が出来ます。

例えば下のGifアニメは、見えていないキャラクターのアニメーションをスキップしています*1

f:id:tsubaki_t1:20160107233159g:plain

他にも、見えていないオブジェクトの揺れものはIKを停止させたり、AIの更新頻度を下げたりといったアプローチにも使えます。

また座標ベースで行うので、Rendererが無くても動作させることが可能です。むしろカリングチェック対象のGameObjectが無い・非アクティブであっても動作させることが出来ちゃいます。
なので、視界範囲に入りそうならリソースを読み込んでインスタンス化、外れたら削除みたいな使い方も出来る気がします。

下のGIFアニメでは、見える少し前にリソースを読み込みオブジェクトを生成、見えなくなったら破棄しています。

f:id:tsubaki_t1:20160108005653g:plain

Renderer.isVisible

似たような扱いにRenderer.isVisibleがあります。こちらはCullingGroupと異なりRenderer単位で行います。OcclusionCullingとのも連動するので、単純に「見えてるか」の判定を考えると、こっちの方が楽かもしれません。

なお、SceneViewから見ても「見えた判定」になるので注意が必要です。

gist.github.com

オブジェクトとの相対距離で処理を切り替える

もう一つの機能として、相対距離による処理の切り替えがあります(勿論見えていない時はOFF)。これも話は簡単で、遠くのオブジェクトは詳細に見る事が出来ないので、目のLookatや揺れもの、その他諸々をOFFにする事で、負荷を下げるアプローチです。

下のGifアニメでは距離に応じて色を変更しています。(1m:白、5m:緑、30m:青、視界外:黒…といった感じ。人は実は高さ4mくらいあります)

f:id:tsubaki_t1:20160108000715g:plain

機能的にはLODに近いです。というか、Unity標準のLODより調整しやすい分、使い勝手が良いかもしれません。

tsubakit1.hateblo.jp

サンプル

サンプルです。

gist.github.com

使い方はこんな感じで、TargetsのTrasnfromにカリング対象となるオブジェクトを登録するだけです。

f:id:tsubaki_t1:20160108003129j:plain

 

もう少し色々なケースの使いかたは今度。

*1:Animatorの場合、Culling ModeをCull Update Transform等に設定しておけばカメラ範囲外の時にアニメーションをスキップします。VRでダンス物をやる場合、これが足を引っ張るケースがあるので注意です