ハツェの真時代傾向璋

興味を持ったことを書いていく鱗片的な場所から先の未来の場

PostProcessingの各Overrideの値をスクリプトで制御する in HDRP

動き出せ!HDRP!
ということでこんばんは。ハツェです。
今回はいくら調べてもあんまり出てこなかったので備忘録として書きます。
動作環境はUnity 2019.3.0f1です。
ちなみにきっかけはこれを作ったことでした。
HDRPがpreviewから外れるみたいなので、そろそろ触ろうかなと思って作った感じです。



目次


そもそも名前空間は何?

HDRPになってからはPostProcessing自体の名前空間はなくなってます。
今まではUnityEngine.Rendering.PostProcessingでよかったりしたんですが、どうもHDRPになってからは最初からPostProcessingが組み込まれているせいか(もしかしたらVolumeの範囲が拡大したからかもしれないが...)名前空間も変わっていました。
といっても消滅したわけではないです。
スクリプトの紹介時にまた説明しますが、UnityEngine.RenderingUnityEngine.Rendering.HighDefinitionを使います。

実際の仕組み

動作における取得から書き換えまでは今までとはほとんど変わっていませんが、ProfileからVolumeに変わっていることにだけ注意しておけば問題ないと思います。

GameObjectのOverrideComponentを取得するまで

例えとしてPost-processing内のVignetteをいじるとすると、取得は以下の感じになります。

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;

private Volume _Volume;
private Vignette _Vignette;
[SerializeField, Range(0, 1)] private float _Parameter;

private void Start()
{
    _Volume = GetComponent<Volume>();
    _Vignette = null;
    _Volume.profile.TryGet<Vignette>(out _Vignette);
}

上から順に説明していきましょう。
まず、Volumeクラスを使うために名前空間UnityEngine.Renderingが、Vignetteクラスを使うために名前空間UnityEngine.Rendering.HighDefinitionがそれぞれ必要となります。

_Volume = GetComponent<Volume>();

まずこれでVolumeがアタッチされたGameObjectから取得します。
ただのGetComponentなので、SerializedFieldから引っ張ってきてもらっても全く問題ないです。

_Vignette = null;
_Volume.profile.TryGet<Vignette>(out _Vignette);

次に出力先を設定します。
TryGet<T>(out )はVolumeProfileクラス内の関数で、特定の変数をprofileの出力先にするためのものです。
Tはジェネリクスであり、( )内は出力とする変数を入れるため修飾子outをつけます。
今回で言うなら結果をVignette変数に代入して、それをprofileに反映するといった感じです。
ちなみに今回、出力変数をVignetteとすることから念のため_Vignette = nullをしていますがこの書き方なら無くてもよかったですね。

Rangeで変更する値を反映させる

private void Update()
{
    _Vignette.intensity.value = _Parameter;
}

これは非常に単純です。
RangeのAttributeのついたParameter変数をintensityのvalueに代入しているだけです。
出力のあれこれはStart関数内のTryGetで既にしているため、代入だけですべて済みます。

全文

これより、ソースコードの全文は以下のようになります。namespaceはお好みでどうぞ。

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;

public class VolumeControl : MonoBehaviour
{
    private Volume _Volume;
    private Vignette _Vignette;
    [SerializeField, Range(0, 1)] private float _Parameter;

    private void Start()
    {
        _Volume = GetComponent<Volume>();
        _Vignette = null;
        _Volume.profile.TryGet<Vignette>(out _Vignette);
    }

    private void Update()
    {
        _Vignette.intensity.value = _Parameter;
    }
}

終わりに

なんだかんだ今でもHDRPの環境は変化し続けています。
そのため、公式ドキュメントとにらめっこしながら色々作ると良いということを今回知ったので、みなさんも参考にしてみてください。
(ちなみに上のScripting APIタブを押すことで、スクリプトAPIやリファレンスとかが見れます。)
docs.unity3d.com