I have a 5 sided cube (you don’t see one side), each face has a different texture. This is the code I use to set each texture:
//Top
GetComponent<MeshRenderer>().materials[0] = new Material(material);
GetComponent<MeshRenderer>().materials[0].mainTextureScale = new Vector2(transform.localScale.x / 2f, transform.localScale.y / 2f);
//South
GetComponent<MeshRenderer>().materials[1] = new Material(material);
GetComponent<MeshRenderer>().materials[1].mainTextureScale = new Vector2(transform.localScale.x / 2f, transform.localScale.z / 1f);
//West
GetComponent<MeshRenderer>().materials[2] = new Material(material);
GetComponent<MeshRenderer>().materials[2].mainTextureScale = new Vector2(transform.localScale.y / 2f, transform.localScale.z / 1f);
//North
GetComponent<MeshRenderer>().materials[3] = new Material(material);
GetComponent<MeshRenderer>().materials[3].mainTextureScale = new Vector2(transform.localScale.x / 2f, transform.localScale.z / 1f);
//East
GetComponent<MeshRenderer>().materials[4] = new Material(material);
GetComponent<MeshRenderer>().materials[4].mainTextureScale = new Vector2(transform.localScale.y / 2f, transform.localScale.z / 1f);
So how do I avoid leaking textures while getting the same results?
Also, I notice it isn’t actually creating an instance of the material, but just using the default “diffuse” material instead, why is that?
That’s quite a lot of code, Could be very much simplified.
MeshRenderer rend = GetComponent<MeshRenderer>();
Vector2 texScale = new Vector2(transform.localScale.x / 2f, transform.localScale.y / 2f);
for(int i = 0; i <= 4; i++){
//Loop through the materials. Setting scale and making instances of Diffuse
rend.materials[i] = new Material(Shader.Find("Diffuse")); //Create an instance of a material from Diffuse shader.
rend.materials[i].mainTextureScale = texScale;
}
Also what exactly do you mean by “texture leaking”?
Problem is that most of the code is a bit different (look at the texture scaling), so a for loop wouldn’t help much. Thanks though! And the editor is complaining of texture leaking.
That doesn’t seem to change anything. The errors are still coming up, and the material is still just going to the default diffuse rather than what I put into “material”.
I did a test to see if I could duplicate your error based on your code, so created an object and added this code:
[ExecuteInEditMode]
public class Test : MonoBehaviour
{
private void OnEnable()
{
// get renderer
var meshRenderer = this.GetComponent<MeshRenderer>();
// Get original material
var originalMaterial = new Material(meshRenderer.materials[0]); ;
// Replace with new material
meshRenderer.materials[0] = new Material(originalMaterial);
meshRenderer.materials[0].mainTextureScale = new Vector2(transform.localScale.x / 2f, transform.localScale.z / 1f);
}
}
I also added ExecuteInEditMode so I could test it in the editor. After doing this I got this error:
Instantiating material due to calling renderer.material during edit mode. This will leak materials into the scene. You most likely want to use renderer.sharedMaterial instead. UnityEngine.Renderer:get_material() Test:OnEnable() (at Assets/Scripts/Test.cs:16)
It looks like calling the materials property of the renderer causes the renderer to clone the materials and that’s why you’re getting the leak message.
Instead of using the getter component of the materials property you could create a local list of materials and then assign them to the renderer. For example:
[ExecuteInEditMode]
public class Test : MonoBehaviour
{
//Create local storage for your materials
Material[] localMaterials = new Material[1];
private void OnEnable()
{
// get renderer
var meshRenderer = this.GetComponent<MeshRenderer>();
// Recreate material
var material = new Material(Shader.Find("Diffuse"));
// Apply changes to material
material.mainTextureScale = new Vector2(transform.localScale.x / 2f, transform.localScale.z / 1f);
// Load into list, this is the important change
localMaterials[0] = material;
// Replace materials
meshRenderer.materials = localMaterials;
}
}
After doing this the error was gone, hope this helps
Thanks, worked like a charm! I still get a similar notification when saving the scene, but I think that is just because I update this script in the editor as well (makes level building easier).