Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Trying to set Material using an Editor script gives weird error...

Discussion in 'Scripting' started by DanTaylor, Mar 17, 2021.

  1. DanTaylor

    DanTaylor

    Joined:
    Jul 6, 2013
    Posts:
    119
    Hi there...
    I am trying to automate some character set-up stuff in Unity.
    I've written a script that does most of the work.
    However, I am struggling to set the Materials on my MeshRenderer.

    The code:
    Code (CSharp):
    1. //Set the materials
    2.         Material characterMaterial = AssetDatabase.LoadAssetAtPath<Material>("Assets/00 - Thunderbox/Materials/Characters/Characters(Teleport).mat");
    3.         Material lightMaterial = AssetDatabase.LoadAssetAtPath<Material>("Assets/00 - Thunderbox/Materials/Environment/Light Pattern Faster.mat");
    4.         crewMesh.sharedMaterials[0] = characterMaterial;
    5.         if (crewMesh.sharedMaterials.Length > 1) crewMesh.sharedMaterials[1] = lightMaterial;
    This looks pretty legit... I am using the shared materials, so it should be OK...

    WRONG!

    The script doesn't assign the materials, and, instead, throws up 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_materials()
    initCharacter:Execute() (at Assets/00 - Thunderbox/Scripts/Editor/initCharacter.cs:29)


    .. but I am indeed calling the shared material!!!

    I've searched the web for hours for a solution, but no joy. Any ideas would be most appreciated. Thanks!
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Most (all?) arrays coming from Unity objects are copies of the data, so you're not actually modifying what you think you are. Try this:

    Code (csharp):
    1.  
    2. // make a copy
    3. Material[] materials = crewMesh.sharedMaterials;
    4.  
    5. // do your edits
    6. materials[0] = characterMaterial;
    7.  
    8. if(materials.Length > 1)
    9. materials[1] = lightMaterial;
    10.  
    11. // assign it back
    12. crewMesh.sharedMaterials = materials;
    13.  
     
    DanTaylor likes this.
  3. DanTaylor

    DanTaylor

    Joined:
    Jul 6, 2013
    Posts:
    119
    Hmmm. Solved it.
    1) There was a typo in my asset path.
    2) You have to set the entire material array, not individual materials.
    New code...
    Code (CSharp):
    1. Material characterMaterial = AssetDatabase.LoadAssetAtPath<Material>("Assets/00 - Thunderbox/Materials/Characters/Characters (Teleport).mat");      
    2.         Material lightMaterial = AssetDatabase.LoadAssetAtPath<Material>("Assets/00 - Thunderbox/Materials/Environment/Light Pattern Faster.mat");
    3.         if (crewMesh.sharedMaterials.Length == 1)
    4.         {
    5.             crewMesh.sharedMaterial = characterMaterial;
    6.         }
    7.         else
    8.         {
    9.             crewMesh.sharedMaterials = new Material[2] {characterMaterial,lightMaterial};
    10.         }