Changing a material at runtime changes for all custom materials

Hi there

So I have noticed that if I drop 3 instances of the same prefab in the scene, I can then change the textures on them, no problems. When I spawn these same prefabs at runtime, if I then go and change them in the Scene view then I can change the texture, no problem…

But it seems changing the texture via code changes the texture on all instances. How do I code the item to have random texture?

I tried simply saying:

renderer.material.mainTexture = newTex;

and I tried saying:

private var thisMaterial	: Material;
function AssignTexture(tex : Texture)
{
	thisMaterial = new Material(Shader.Find("Diffuse"));
	thisMaterial.mainTexture = tex;
	CellBlock.material = thisMaterial;
}

But in both cases I simple replace the prefab’s material (or it’s texture as the case may be) so all prefabs end up having whatever I assigned to the last one. How can I specify that the changes I am trying to make is for the current instance only?

Thanks in advance

Hmm, your first code snippet should work. Unity will automatically create a new material for the instance unless you used sharedMaterial. Are you doing this at runtime or as an editor script?

I am doing this for runtime.

I am thinking this must be because of the JavaScript vs pointer thing and that ifI redo this in C# it might work. I would prefer to keep all code in 1 language if possible so before I go about porting it I would like to find out what I am ding wrong here.

I had this error in another project I did and to solve it I placed the instances in the scene, exposed an array on a group object, dragged each instance to it and then told the other object to assign the textures when the game runs.

At design time you could clearly see that when you change the texture on the object that you are actually changing the material they all use. Yet, once it starts running, each gets it own material. So I tried changing the import settings but that didn’t really seem relevant nor did it, in fact, make a difference.

Hense, why I am stuck and why I am asking for help.

Okay, this is getting more weird by the minute…

So I load a couple hundred sprites at runtime, right… As I Instantiate them I assign them a texture, fine so they get the texture but they all share the last one. Fine, that much we have covered. But… when I instantiate them, I place them into a built in array to be able to reference them as required. Here is where the fun starts…

So now, where I change the texture when I instantiate them, I no longer do that. Instead, I go through the array. But this is the totally weird part… If I loop through the array and call Destroy(spriteArray[index]), all the gameobjects in my scene are destroyed. Brilliant.
But if loop through the same array and assign a new textures to that object’s renderer’s material, only the first item created has it’s texture changed. All the other sprites in the scene has the default texture… except the first…

So how in the world is THAT possible? Each entry in the array points to a separate game object, but each game object returns the same renderer and sets the material on the same gameObject…!!!

I am thinking that perhaps the fact that I am instantiating the object into a local variable before moving it into a global one might have something to do with it… Does this look like it might be a problem? Once I start accessing the components within each game object and set their values, I realise that all values behave as expected, so I find it hard to believe that if the components foe each GameObject is different that the game objects themselves are the same… Yet, if not that, then how in the world can it come to pass that each array entry returns the same renderer?

private var objects : GameObject[];
var prefab             : GameObject;
function Start()
{
objects = new GameObject[20];
for (x = 0; x < 20; x++)
{
var GO : GameObject = Instantiate(prefab);
objects[x] = GO;
}
}

Edit: I got it working. I still don’t know WHY it didn’t work, but it works.

I tried something interesting. After all the objects had spawned I clicked on each of them in turn and clicked on the exposed renderer in the inspector. Sure enough, every gameobject pointed to the renderer of the first object in the scene. Strange.

The renderer is actually the renderer of a sub object in the prefab so I just dragged it inside the prefab so it will be setup when it is instantiated. Then, when it is instantiated I tell it to find it anyways and even then it still doesn’t work. Sems for some or other reason when I say gameObject.Find(“marker”) inside a prefab, it keeps returning GameObject.Find(“marker”)

Perhaps this is a bug?

Anyways, what I did then was to expose not the Rendeder but the GameObject and drag the same object to the same location and then in code reference the render through the gameObjet… that works just peachy…

It seems thus the error was not withthe setting of the material but with the value returned by gameObject.Find()