テラシュールブログ

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

【Unity】LODGroupの設定を一気に変更する

f:id:tsubaki_t1:20191015221051g:plain

LODGroup

 視覚上のポリゴンを削減するという用途でLODGroupという機能は非常にありがたい機能です。これは単純にローポリのモデルに差し替えるというだけではなく、遠距離に要るキャラクターのメッシュを非表示にする(≒アニメーションとスキニングのコストを削減出来る)といった点でもありがたい技術ではあります。

 このLOD Group、モデル切り替えの条件が「画面内におけるモデルの高さ」という条件で、調整には少し苦労するかもしれません。距離ベースのLODと異なり、近づいた時にいきなり巨大なオブジェクトが唐突に表れるという事は無いのですが、どの距離で表示するのかといった事は開発者のノリに依存します。

f:id:tsubaki_t1:20191015222835g:plain
元々の大きさに関係なく、画面の占有率(高さベース)でLODが切り替わる

複数のLODを編集したい

 このLODの仕組みで困るのが、複数のLODを一括変更できないという点です。複数のLODを選択すると、Multi Object Editing not supportと表示され、編集ができません。

 これは少し面倒くさいです。例えばキャラクター等をLODでカリングしようと思ったとき、キャラクター毎にLOD Groupを調整する必要が出てきます。LOD Groupは複数の設定項目を持てる上、数字入力が出来ないので本当に面倒くさいです。

 

f:id:tsubaki_t1:20191015223457j:plain
LODGroupを複数調整する場合、本当に面倒くさい

LODの設定を一気に上書きするコード

 LODの設定はスクリプトから一気に更新してしまいます。例えば下のようなコードで

using UnityEngine;

public class LODGroupSettings : MonoBehaviour
{
    [SerializeField] LODGroup src;

    void Start()
    {
        UpdateLOD();
    }

    [ContextMenu("UpdateLOD")]
    public void UpdateLOD()
    {
        var dst = GetComponent<LODGroup>();
        var srcLOD = src.GetLODs();
        var dstLOD = dst.GetLODs();

        for (int i = 0; i < srcLOD.Length; i++)
        {
            dstLOD[i].screenRelativeTransitionHeight = srcLOD[i].screenRelativeTransitionHeight;
            dstLOD[i].fadeTransitionWidth = srcLOD[i].fadeTransitionWidth;
        }
        dst.SetLODs(dstLOD);
    }
}

src にコピー元となるLODGroup(コピー先と同じLODの数)のPrefabを登録します。これで実行時にLODの設定が差し変わる他、コンテキストメニューからUpdateLODを選択すればLODが切り替わります。

 

f:id:tsubaki_t1:20191015224349j:plain
コピー元を登録して、コンテキストメニューでUpdateLODを選択する場合

注意:複数編集にPresetが使えそうに見えるが、使ってはいけない

 複数編集という点で、使えそうな設定にPresetという機能があります。この機能を使用すると、確かにLODを一気に更新することができますが、実はコレは罠です。フフフ…

 Presetの設定はコンポーネントの設定をコピーしてくれますが、実はLODGroupで表示・非表示を切り替えるメッシュもコピーしてしまいます。つまり、階層下ではない別のLODGroupに所属するRendererを対象にしてしまいます。これでLODが効かなくなったり、レンダラーの登録が全て剥がれたりして大惨事を引き起こすかもしれません。

f:id:tsubaki_t1:20191015225338g:plain
違う階層のLODを参照してしまっている図

感想

 LODの切り替え距離それ自体はProjectSettings>QualityのLOD Biasで大雑把に調整出来ますが、全体で調整されてしまうので、特定の物をテンプレートに従って一気に差し替えられるというアプローチは、便利と感じています。

 まぁ現状モバイルだとポリゴンを削減するという点でのLODは(一画面1200万ポリゴンとか行ってないなら)そこまで気にしなくても良いと思いますが。ポリゴン数以外でも、スキンメッシュやAnimatorの計算を距離で削減出来るのは、ゲームによっては結構アリかなと思います。