[Unity] C#からシェーダーのパラメーターを弄る時のメモ

題名の通り、アタッチしたGameObject以下のシェーダーをまとめて操作したいときのメモ。

やりたい事は、アタッチしたゲームオブジェクト以下のシェーダーを暗転やホワイトアウトやらフェードやらをしたい ということだったのですが
調べて出てくる materialsを使用してのシェーダー操作の場合

こんな感じで、GetComponentsInChildrenでRendererを取得して
materials でマテリアルを取得して、その数分SetFloatをする方法がでてきました。
一応これでもできるのですが、コレでやった場合プロファイラでもはっきりと分かるぐらい処理負荷が高くなってしまいました。

それは(おそらくですが)こんな感じで閣オブジェクトごとにすべてインスタンスのマテリアルが
生成されているからのようで、オブジェクトが多ければ多いほど処理が露骨に遅くなっているようでした。
むむむ・・・これはシェーダー周りをスクリプトから弄ろうとするとNGになるのかな?
と思ったら、取得の方法が違っていました。

インスタンスではなく、直接マテリアルを変更したい場合は、 sharedMaterials(1つならsharedMaterial)にすればインスタンスにならずに処理ができました。

変更後はこう。
この場合は(Instance)がつきません。

この場合の注意点は、インスタンスの場合、スクリプト再生前の値は保存されたまま
新しくインスタンスが作成されて値が入るため、スクリプトを止めれば元の数値に戻ります。
しかし、sharedMaterialsの場合は(当たり前ですが)マテリアルの数値を直接書き換えるので
実行を止めてたあともマテリアルの数値は変更されたままになります。
また、同じマテリアルを複数のオブジェクトに使用している場合、
当たり前ですがそのはりつけているオブジェクト側もマテリアルの数値が変わります。

よくよく考えたら、MaterialsはシーンではなくMaterialsというファイルとしてあるわけなので
直接書き換える=Materialsファイルを更新する
扱いだから、変更を止めても戻らないわけですよね。

なので、オブジェクトごとに(マテリアル関係なく)フェードなどの処理をしたい場合はmaterials
そうではなく一律で処理をしたい場合はsharedMaterilasにすればOKということのようです。

なるほど。

HELPに書いてあったのに完全に見逃してました。うーむ。

こういう細かい書き方とか使い分けをもっと覚えていきたいです。

コメントを残す

メールアドレスが公開されることはありません。

*