本日は MRTK の小ネタ枠です。
MixedRealityToolkit/StandardShaderのテクスチャを動的に切り替えた時にInspectorを開いたときのみ反映される問題の対処を記事にします。
問題事象
以下のようにテクスチャが設定されていない MixedRealityToolkit/StandardShader のマテリアルを持つオブジェクトを用意します。
次にスクリプトを用意し、ボタンを押下したときに指定のテクスチャをマテリアルに反映してみます。
・TextureChangeTest.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TextureChangeTest : MonoBehaviour { [SerializeField, Tooltip("変更テクスチャ")] private Texture2D changeTexture; private MeshRenderer meshRenderer; public void ChangeTexture() { // 確認用ログ Debug.Log("ChangeTexture"); // メッシュレンダラーの参照を取得する meshRenderer = this.GetComponent<MeshRenderer>(); // マテリアルのテクスチャを変更する meshRenderer.material.SetTexture("_MainTex", changeTexture); } }
試しにシーンを再生してみます。
ボタンを押下して、関数が実行されてもテクスチャが反映されません。
しかし、対象オブジェクトの Inspector からマテリアルの情報を開くと、このタイミングでテクスチャが反映されて表示されるという事象が発生します。
この事象は HoloLens 上でも再現します。
ただし HoloLens で発生した場合は Inspector を開いたりはできないため、ボタンを押下してもテクスチャが反映されることはありません。
問題の解決方法 その1
(2021/5/31 解決方法 その1 を追記)
問題を解決するにはテクスチャの動的差し替えを行う MixedRealityToolkit/StandardShader のマテリアルに[Assigned at Runtime]のチェックを入れておきます。
同じようにオブジェクトにスクリプトを追加し、ボタンを押下したときに設定したテクスチャをマテリアルに反映してみます。
シーンを再生してみます。
ボタンを押下すると即座にテクスチャが反映されました。
こちらの設定であれば HoloLens 上でも正常に動作します。
ボタンを押下するとテクスチャが即座に反映されます。
問題の解決方法 その2
または問題を解決するには MixedRealityToolkit/StandardShader のマテリアルを再作成して、マテリアルの参照を差し替えます。
以下のようにマテリアルの差し替えを行うスクリプトを作成しました。
1.MixedRealityToolkit/StandardShader から新規マテリアルのインスタンスを作成する
2.変更前のマテリアルの情報を新規マテリアルに引き継ぐ
3.新規マテリアルにテクスチャを設定する
4.マテリアルの参照を差し替え
・MaterialChangeTest.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MaterialChangeTest : MonoBehaviour { [SerializeField, Tooltip("ベースシェーダ")] private Shader baseShader; [SerializeField, Tooltip("変更テクスチャ")] private Texture2D changeTexture; private MeshRenderer meshRenderer; public void ChangeMaterial() { // 確認用ログ Debug.Log("ChangeMaterial"); // メッシュレンダラーの参照を取得する meshRenderer = this.GetComponent<MeshRenderer>(); // 指定 Shader から新規マテリアルのインスタンスを作成する Material initializeMaterial = new Material(baseShader); // 変更前のマテリアルの情報を新規マテリアルに引き継ぐ initializeMaterial.SetColor("_Color", meshRenderer.material.color); // 新規マテリアルにテクスチャを設定する initializeMaterial.SetTexture("_MainTex", changeTexture); // マテリアルの参照を差し替え meshRenderer.material = initializeMaterial; } }
ベースとなるシェーダには MixedRealityToolkit/StandardShader の参照を設定しています。
シーンを再生してみます。
ボタンを押下するとテクスチャが反映されたマテリアルに即座に切り替わりました。
こちらのスクリプトは HoloLens 上でも正常に動作します。
ボタンを押下するとテクスチャが即座に反映されます。
事象の原因
2021/05/31 現在、私には分かっていません。
解決方法 その1にある通り、マテリアルの設定で解決できることから、以下の記事のシェーダバリアントに起因する事象と同じ原因である可能性が高いです。
ただし、コードを確認しても原因がシェーダバリアントによる無効化とは確認できませんでした。
bluebirdofoz.hatenablog.com
その他
テクスチャ設定済みのMixedRealityToolkit/StandardShader
本事象はテクスチャが設定されていない MixedRealityToolkit/StandardShader のマテリアルでのみ発生します。
以下のように予め別のテクスチャが設定されたマテリアルに対し、テクスチャ差し替えのみ行う1つめのスクリプトを試してみます。
シーンを再生してみます。
ボタンを押下するとテクスチャが即座に切り替わりました。
こちらのパターンは HoloLens 上でも正常に動作します。
Unity/Standard
また Unty/Standard シェーダ利用時は本事象は発生しません。
以下のようにテクスチャが設定されていない Unity/Standard マテリアルに対し、テクスチャ差し替えのみ行う1つめのスクリプトを試してみます。
シーンを再生してみます。
ボタンを押下するとテクスチャが即座に切り替わりました。
本パターンも HoloLens 上で正常に動作します。