【Unity】MaterialPropertyBlock を使ってマテリアルのインスタンスを増やさない

DEVELOP, Unity

Unity では Material の色を変えたりUVを変更したりした時点で Material のインスタンスが複製されてしまいます。値の変更だけなのに…そんなMaterial インスタンスの複製を防ぐためのものが MaterialPropertyBlock です。 留意点として MaterialPropertyBlock を利用しても Draw Call は減りません。 勘違いしている人をちらほら見ます。

目次

確認環境

2019.3.06f

サンプルコード( MaterialPropertyBlock 未使用)

まずは MaterialPropertyBlock を使わずにサンプルコードを書いてみます。

using UnityEngine;
 
public class Sample : MonoBehaviour
{
    [SerializeField, Header("適用する色")]
    private Color m_color;
    public Color color
    {
        get { return m_color; }
    }
 
    [SerializeField, Header("メッシュレンダラー")]
    private MeshRenderer m_meshRenderer;
    public MeshRenderer meshRenderer
    {
        get { return m_meshRenderer; }
    }
 
    /// <summary>
    /// 開始
    /// </summary>
    void Start()
    {
        if (meshRenderer != null)
        {
            meshRenderer.material.SetColor(Shader.PropertyToID("_Color"), color);
        }
    }
}

これをUnity デフォルトのSphere にでも AddComponentして実行してみます。meshRenderer とかは適切に割り当ててね。

Color に赤と緑を指定して実行してみた図

結果

Mesh の マテリアル項目に(Instance) の表記があると複製されています。

サンプルコード( MaterialPropertyBlock 使用時)

using UnityEngine;
 
public class Sample : MonoBehaviour
{
    [SerializeField, Header("適用する色")]
    private Color m_color;
    public Color color
    {
        get { return m_color; }
    }
 
    [SerializeField, Header("メッシュレンダラー")]
    private MeshRenderer m_meshRenderer;
    public MeshRenderer meshRenderer
    {
        get { return m_meshRenderer; }
    }
 
    /// 追加!!!
    private MaterialPropertyBlock m_mpb;
    public MaterialPropertyBlock mpb
    {
        get { return m_mpb ?? (m_mpb = new MaterialPropertyBlock()); }
    }
 
    /// <summary>
    /// 開始
    /// </summary>
    void Start()
    {
        if (meshRenderer != null)
        {
            mpb.SetColor(Shader.PropertyToID("_Color"), color);
            meshRenderer.SetPropertyBlock(m_mpb);
        }
    }
}

結果

Material のインスタンスが複製されずにオリジナルのMaterial が割り当てられたままになっていることを確認できます。

まとめ

小さな最適化かもしれませんが、塵も積もれば山となる。丁寧に作っていきたいですね。

Posted by kazupon