MaterialPropertyBlock
下記記事で作成していたVRお絵描きアプリに
色の変更機能を設けようとした際にMaterialPropertyBlockを活用しました。
【参考リンク】:【Unity(C#)】ハンドトラッキングで簡易版VRお絵かきアプリ
描いた線ごとに色を変更したかったのですが、
描く予定の線の分だけマテリアルを用意するのは
あまりにも手間ですし、その都度Instantiateするのも
負荷的にどうなの?と感じたのでMaterialPropertyBlockの使い方を学ぶことにしました。
デモ
リアルタイムに色違いのキューブがランダムに生成されるデモです。
マテリアルは1つしか使っていません。
コード
usingSystem.Collections;usingUnityEngine;/// <summary>/// 色違い場所違いキューブ自動生成プログラム/// </summary>publicclassCubeCreate:MonoBehaviour{[SerializeField]privateGameObject_cube;privateMaterialPropertyBlock_materialPropertyBlock;privateintpropertyID;privatevoidStart(){_materialPropertyBlock=newMaterialPropertyBlock();//プロパティーのIDを取得しておく SetColorをstringで指定しても結局intに変換してるらしく、無駄らしいpropertyID=Shader.PropertyToID("_Color");StartCoroutine(InstantiateColorCube());}/// <summary>/// ランダムな位置にランダムな色のキューブを生成 /// </summary>privateIEnumeratorInstantiateColorCube(){while(true){//ランダムな値floatrandomValueA=Random.Range(-1.0f,1.0f);floatrandomValueB=Random.Range(-1.0f,1.0f);floatrandomValueC=Random.Range(-1.0f,1.0f);//ランダムな値floatrandomMagnification=Random.Range(0.0f,5.0f);//ランダムな位置にキューブ生成Vector3randomPos=newVector3(randomValueA,randomValueB,randomValueC);GameObjecttmp=Instantiate(_cube,randomPos*randomMagnification,Quaternion.identity);//MaterialPropertyBlockで色を変更 元のマテリアルの色はそのままMeshRenderermr=tmp.GetComponent<MeshRenderer>();ColorrandomColor=newColor(randomValueA,randomValueB,randomValueC);_materialPropertyBlock.SetColor(propertyID,randomColor*randomMagnification);mr.SetPropertyBlock(_materialPropertyBlock);yieldreturnnull;}}}SetColor , SetPropertyBlock
色をセットするためにSetColorを使います。
第一引数にShaderで定義されている色のProperty名を指定します。
(今回はIDで指定しています)
その後、Rendererに反映させるためにSetPropertyBlockを呼び出します。
Shader.PropertyToID
Shader.PropertyToIDを使うことで
Shader内で定義されている特定のプロパティ名を
ID(int型)に変換することができます。
先ほどのSetColorの第一引数に渡すことができます。
メリットしてはStart関数内でIDを取得しているので
何度も指定したShader内プロパティの文字列→ID(int型)
という処理を行わずに済み、負荷が軽くなります。
