- Home /
Changing the material in an array of materials at run time
I've been going over this for a couple of days and I'm stumped. This is hopefully a clear update on a question I asked 2 days ago.
I have a ball object with script, collider, rigid body etc. attached. It also has a Plane mesh with a Mesh Renderer attached. The Mesh Renderer has a 2 element array to hold materials. Both are of shader type Particles/Alpha Blended so I don't have to worry about lighting. Element 0 is called m_BallRed. It has a texture map which was originally greyscale but I've set the Tint Color to a red color - that's what I want to change when the game is played. Element 1 is called m_BallHighlight. Element 1 won't change; it's a texture map with an alpha channel which sits on top of the main texture map so I can have highlights that aren't affected by the underlying Tint in Element 0.
When the game is playing I have many different coloured balls in play. I want to change the tint of element 0 of any particular ball to one of several different colors. I figure the best way is to have a series of materials called m_BallRed, m_BallBlue, m_BallYellow etc. When circumstances dictate I want to invoke a ChangeColor() function on the ball which currently contains the following line:
transform.Find("Plane").GetComponent().materials[0] = new Material(Shader.Find("m_BallYellow"));
Once that works I can set about customising the Function, maybe to accept a parameter to specify which color to change the ball to, but I'm getting a NullReferenceException at run time - 'UnityEngine.Material..ctor (UnityEngine.Shader shader)' for that line. So I guess I'm trying to access something that isn't there. Or I'm accessing the chlild Plane's MeshRenderer array of materials wrong. Or... or.... ? Anyone?
Answer by Ejlersen · Dec 16, 2010 at 02:19 PM
You could just have an array with the three materials, when wanting to change material you then use this array.
E.g.
MeshRenderer planeRenderer; Material[] mats; (You could use the inspector to assign the three materials)
Awake() { planeRenderer = GetComponentInChildren<MeshRenderer>(); }
ChangeColour(Color c) { if (c == Color.red) planeRenderer.material = mats[0]; else if (c == Color.blue) planeRenderer.material = mats[1]; else planeRenderer.material = mats[2]; }
Try not to use Find all the time, since that can be expensive. Instead cache the things you need.
- Oh, and the code is just off the top of my head, so if there are any mistakes in the code. Sorry :)
Yeah, much better approach to have it cached and look them up in an array.
...and that's helped me a lot! I had to tweak my code somewhat to get it to fit but I now have a good base to move forward with. Tak tak!
Whoops! I got my helpers mixed up! Tak tak = thanks a lot!
Answer by Statement · Dec 16, 2010 at 02:11 PM
But I'm getting a NullReferenceException at run time - 'UnityEngine.Material..ctor (UnityEngine.Shader shader)' for that line. So I guess I'm trying to access something that isn't there.
Yeah, your Shader.Find didn't find anything. (It return null if nothing was found).
So your question is basically condensed to:
Why doesn't Shader.Find("m_BallYellow") return my expected shader?
Your material is called m_BallYellow. With your code, you are trying to find the shader that is called m_BallYellow. But there is no such shader, only such material!
So my answer?
You probably want to find the "Particles/Alpha Blended" shader, and set properties on that.
Material newMaterial = new Material(Shader.Find("Particles/Alpha Blended"));
Thanks for getting back to me. You gave me some clear thinking here. Goodness knows what a programmer needs that for, but thanks again!
Your answer
Follow this Question
Related Questions
Change color of all buttons listed in array 3 Answers
How can I use the same script on multiple objects without conflicting variables. 2 Answers
Brightening the colour of a material that can be any colour without shaders. 1 Answer
Change material color of array objects 1 Answer
How to change the color of a material in an array at run time 3 Answers