【Unity】カメラのカリングの隠し機能!レイヤーごとに表示限界を変更できるぞ

カメラカリングの隠し機能! Unity

Unityでオープンワールドゲーム等を作るときに必須の最適化手法として、カメラに映るメッシュの描画距離を制限する「カリング機能」があります。これを使うと、例えばカメラから1000m以上離れたゲームオブジェクトは表示しない…というようなことができるので描画負荷を軽くすることが可能です。

しかしこのカリング機能だとあらゆるメッシュの表示・非表示が一緒くたに判定されてしまうので、

  • 巨大なオブジェクトは遠くまで見えるようにしたい
  • 逆に小物は早めに非表示になるようにしたい

といった細かい制御は不可能…だと私は思い込んでいました。ところが先日、よくよく調べてみるとカメラのカリング機能には上のような制御を可能にする隠し機能があることを発見し、最適化大好き人間(?)の私は一人で勝手に感動してしまいました。

このような次第で、この記事では今回発見した隠し機能について説明していきますね。

カリング距離はレイヤーごとに変更できる!

では早速ですがその隠し機能をご紹介しようと思います。それは一言でいうと見出しのとおり

実はカメラのカリング距離はレイヤーごとに変更できる

ということです。これはC#スクリプトからでないと設定できないので、私もまったく気づきませんでしたしほとんどの方が知らないと思います。

この隠し機能を使うと何が便利なのかといえば、例えばの話

  • 「Buildings」という大きな建物用のレイヤーに分類されるゲームオブジェクトは、カメラからかなり離れても非表示にしない
  • 逆に「Props」という小物用のレイヤーに分類されるゲームオブジェクトは少し離れたら非表示する

といったことが可能になるので手軽に描画の最適化を行うことができます。

さて具体的な設定方法についてですが、カメラに「layerCullDistances」という変数があるのでそれを変更するだけです。

Camera-layerCullDistances - Unity スクリプトリファレンス
レイヤー単位のカリング距離。

Unityのレイヤーは0~31番まであるので、32個の要素を持つfloat型の配列を作ってこの変数に代入すればOKです。

カメラのカリング範囲を調整するC#スクリプト

…とはいえ、そんな簡単な説明だけだとよく分からないと思いますので具体的なC#スクリプトを掲載しておきます。

using UnityEngine;

namespace KurokumaSoft.Common
{

    public sealed class CameraCullingSettings : MonoBehaviour
    {

        [SerializeField]
        Camera targetCamera;
        [SerializeField]
        bool layerCullSpherical = false;
        [SerializeField]
        float[] layerCullDistances = new float[32];

        public Camera TargetCamera { get; }

        void Start()
        {
            ApplyCullingSettings();
        }

        public void ApplyCullingSettings()
        {
            targetCamera.layerCullDistances = layerCullDistances;
            targetCamera.layerCullSpherical = layerCullSpherical;
        }

        public void SetLayerCullDistance(int layerIndex, float distance)
        {
            layerCullDistances[layerIndex] = distance;
        }

        public void SetLayerCullDistance(string layerName, float distance)
        {
            layerCullDistances[LayerMask.NameToLayer(layerName)] = distance;
        }

        public float GetLayerCullDistance(int layerIndex)
        {
            return layerCullDistances[layerIndex];
        }

        public float GetLayerCullDistance(string layerName)
        {
            return layerCullDistances[LayerMask.NameToLayer(layerName)];
        }

    }

}
※注:上記のスクリプトは作者を偽らなければ自由に使っていただいて構いません。

このスクリプトの使い方

設定方法

  • 適当なカメラに上記のスクリプトをアタッチして、「ターゲットカメラ」に設定対象のカメラを登録してください。
  • 各レイヤーにカリング距離を設定してください。なお距離が「0」の場合はカメラの元々のカリング距離が使われます。
  • 「Layer Cull Distances」の要素数は変更しないでください。

他のC#スクリプトからの変更方法

SetLayerCullDistance関数からカリング距離を設定し、設定がすべて終わったらApplyCullingSettings関数を呼び出してください。

おわりに

以上、簡単ではありますがカメラのカリングに関する隠し機能をご紹介しました。これを使えば簡単に描画を最適化できるので、ぜひ活用していただければと思います。

この記事がUnityでのゲーム開発のお役に立てば幸いです。