コードからShaderのプロパティにアクセスするにはどうすれば良いか悩んだので解決策を書きます。
できたもの
Outline Widthに影響しているプロパティを作成し、コードから制御しています。
流れとしては、
1:shaderにプロパティを作成する
2:プロパティ名を確認する
3:コードからプロパティを更新する
になります。
あと大切なマテリアルの取得についても書きます。
1:shaderにプロパティを作成する
まずは、コードから変更するためのプロパティを作成します。
右クリックでメニューを出し、Properties/以下のメニューを選択して、PropertieNodeを作成します。
このとき、どのタイプのプロパティを作成したのかちゃんと確認しておくこと。
今回は、Outline widthに使用するプロパティなので、float型のプロパティを作成しました。
プロパティノードを作成した直後だと、node_****みたいな名前になのでとりあえず aaa に変更しました。
あとは普通にOutline widthに接続しました。
2:プロパティ名を確認する
Shader Forgeによって作成されたシェーダーをプロジェクトviewで選択し、インスペクターを見ます。
Properties という欄があり、そこに
_Color と _aaa というプロパティの存在が確認できます。
ここに記載されているプロパティ名を使ってコードからアクセスしていきます。
3:コードからプロパティを更新する
public GameObject sphere;
public Slider slider;
void Awake ()
{
slider.OnValueChangedAsObservable ()
.Subscribe (value => {
sphere.GetComponent <Renderer> ().sharedMaterial.SetFloat ("_aaa", value);
});
}
めっちゃ適当なのですが、
UniRxを使って、sliderの値が変化したときにシェーダーのプロパティを更新しています。
ようは、
shaderを管理しているマテリアルを取得し、そいつにSetHoge("name",value)してあげることでプロパティを更新することができます。
(Hogeの部分はプロパティの型が入ります。今回はfloat型を使ったのでSetFlot()ですね)
大切なマテリアルの取得について
マテリアルはRendererクラスが管理しています。
Rendererからマテリアルを取得する方法は、2種類あり、取得の仕方によって動作が大きく変わってしまうので注意が必要です。
1つめの取り方
GetComponent <Renderer> ().sharedMaterial
ですね。
sharedMaterialでマテリアルを取得し、シェーダーのプロパティを更新すると、
そのシェーダーを使っている全てのオブジェクトに影響が及びます。
こんな感じに。
マテリアルが共通で使われているのでstatusの SetPass callsも4 のままになっています。
2つめの取り方
GetComponent <Renderer> ().material
ですね。sharedMaterialがただのmaterialになりました。
そのため、1つのmaterialに対しプロパティを更新することができます。
こんな感じですね。
しかし、見てください。
statusの SetPass callsが6 になっています。
今回作成したシェーダーは2だけSetPass callsを増やします。
しかし、GetComponent ().materialで1つのマテリアルを取得し、プロパティを更新すると全く違うmaterialとしてゲーム世界に存在するので、またSetPass callsが2増えてしまいます。
SetPass callsの値が大きくなるとゲームパフォーマンスに影響してくるので安易に増やさないようにしましょう。
といっても僕もよくわからないので今後記事にしていきたいと思います
ドローコールやSetPass callsについては
http://qiita.com/baba_s/items/5260807ced7fc3c02ca6
これが良い感じにまとまってるのかな・・・?