神様は有休消化中です。

Unity関連の技術ネタを書いてます。

【Unity】AssetBundle化したPrefabのシェーダー参照が壊れる現象

先日、AssetBundle化したPrefabのシェーダー参照が壊れる現象に遭遇したため解決策を共有。状況としてはこんな感じ。
・自作のUGUIオブジェクトにカスタムシェーダーを適用してPrefab化
・上記Prefabをシーンに追加して実行→正常動作
・上記PrefabをAssetBundleから読みこんで実行→表示が壊れる

FrameDebuggerで確認すると、シェーダー名称は適用したカスタムシェーダーの物になっているが、レンダーステートが明らかにおかしい・・・。

Google先生に聞くと、以下の記事を発見。
NGUIオブジェクトをAssetBundle化すると、シェーダー参照が壊れることがあるらしい。blog.livedoor.jp

古い情報だしNGUIだし、関係ないだろーと思いながらランタイムでシェーダーを再設定するとちゃんと表示できた。何ぞこれ。

private void Awake(){
   Material material = GetComponentInChildren<Material>();
   if(material != null){
      Shader s = Shader.Find("Custom/Hoge");
      if(s){
         material.shader = s;
      }
   }
}

ちなみに、上記のコードを実行した場合、UnitEditorと実機で適用されるシェーダーが変わる。
UnityEditor:/Assets以下に入っているカスタムシェーダー
実機:AssetBundleに入っているカスタムシェーダー
これはShader.Findの検索順に依存していると思われます。

しかし、Shader.Findでシェーダーが見つかるのに参照が壊れる理由が本当に不明。
シェーダーコンパイルやらの関係・・・?うーむ。
何か情報をもっている方がおられたら、コメント欄で教えて下さい。