この記事でのバージョン
Unity 2018.3.4f1
はじめに
UnityはStandardというShaderがありますが、
今回はその中のEmissionをプログラムから切り替える方法の紹介です。
ちなみにStandardのコードは以下のページからビルドインシェーダーをダウンロードし、
DefaultResourcesExtraの中にあるStandard.shaderから確認する事が出来ます。
StandardのEmission
以前、マテリアルのプロパティをプログラムから変更する方法についての記事は書いたのですが、
Emissionはプロパティに載ってない(プロパティではない)ので、この方法では変更できません。
ではどうするのかと言うと、EnableKeyword(無効にする時はDisableKeyword)を使います。
スタンダードシェーダーの異なるバリアントを使うようにスクリプトからマテリアルを変更する場合、 ** EnableKeyword function を使って、バリアントを有効にしなくてはなりません
material.EnableKeyword("_EMISSION");
ただし、以下のような注意点があります。
上記のキーワードによるスクリプトからのマテリアルの変更は、エディター上で実行中でも問題無く行う事ができます。
ですが、ビルドに含むバリアントを割り出すために Unity がチェックするのは、プロジェクトで使われているマテリアルだけなので、実行中にスクリプトから一時的に変更した だけ のバリアントは含まれません。
このため、そのタイプのマテリアルを少なくとも一つ、アセットに用意して、 Unity にそのシェーダーバリアントを使う事を明示する必要があります。そのマテリアルは シーンで使われていなくてはなりません 。もしくは、 ランタイム時にリソースを読み込んで おくという方法もあります。そうしないと Unity からは、まだ使っていないように見えるため、ビルドから除外されてしまいます。
つまり、
- StandardのEmissionが有効なものと無効なものは別のShaderとしてビルドされる
- それぞれのShaderは使っていれば自動でビルドされる
- プログラムからEnableKeywordを使って有効にしても使っている事にはならない
という具合なので、最初からEmissionが有効なマテリアルが他に使われてなければ、
後からEnableKeywordで_EMISSIONを有効にする事はできません。
これに対する簡単な対処法は、
最初からEmissionが有効なマテリアルを作成し、Resourcesに配置する事です。
なお、エディタ上では特にこの問題は気にしなくて良いのですが、
Inspectorで開いてるマテリアルを変更すると有効になった後、すぐに無効になってしまうようです。
void Start() { GetComponent<MeshRenderer>().sharedMaterial.EnableKeyword("_EMISSION"); }
これの対処法をご存知の方はご一報頂けると幸いです!