あるオブジェクトにアサインされている特定のマテリアルを別のマテリアルに置き換えたかったので、次のようなコードを書いた。
[SerializeField]protected Renderer rend; //Target Renderer [SerializeField]protected Material matFrom; //Change from this material [SerializeField]protected Material matTo; //Change to this material <途中省略> void Change() { Material[] mats = rend.sharedMaterials; Debug.Log("ChangeMaterial: mats.Length= "+mats.Length); for(int i=0;i<mats.Length;i++) { Debug.Log(i+" Spec Int "+mats[i].GetFloat("_SpecInt")); if(mats[i] == matFrom) { Debug.Log("ChangeMaterial:Material("+i+" changed"); mats[i]= matTo; //Replace the material } } rend.materials = mats; //Reassign Materials }
ところがこれは機能しない。マテリアルはRunTimeでインスタンス化されるが、インスペクタでアサインしたマテリアルはインスタンスではない。このため、mats[i] == matFrom
という比較が真にならない。
そこで、マテリアルの名前で比較しようと思い、比較分の箇所を
if((mats[i].name == matFrom.name)...
と書いたが、これもうまくいかない。マテリアルがインスタンス化されると名前も変わるからだ。
結局、
if(mats[i].name == (matFrom.name+" (Instance)")) {
と、元の名前の後に" (Instance)"を加えれば、一応うまくいった。
しかし、もっとスマートな比較方法がないものだろうか…。