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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Can't change shared material of a gameobject at runtime, but am able to locate it via script

Discussion in 'Scripting' started by MatthewPlaudis, Dec 9, 2019.

  1. MatthewPlaudis

    MatthewPlaudis

    Joined:
    Apr 19, 2019
    Posts:
    2
    As the title says, I have looked through several posts and have not been able to do this successfully. Basically I have an object with several floors that have certain color codes assosciated with them. I would like to try to change the material using a scripted method using an on click listener. The problem seems to be the actual swapping from old material to new material. I know it it possible since I am able to do so using the inspector. The first thing I tried was setting the instance of .materials (there are 3 materials for each GO) equal to a new array of materials. did not work. Then, I tried the following using SharedMaterials:

    Code (CSharp):
    1. Material newMaterial = Resources.Load<Material>("Residential");
    2.             MeshRenderer meshRenderer = GameObject.Find("Level #" + (levels.Count - 1 - i) + "/Group1/Group2/Mesh1").GetComponent<MeshRenderer>();
    3.             Material oldMaterial = meshRenderer.sharedMaterials[1];
    4.  
    5.             Debug.Log("Applied material: " + oldMaterial.name);
    6.             meshRenderer.sharedMaterials[1] = newMaterial;
    7.    
    8.  
    9.             Debug.Log("Change Finished.");
    And here is the console log, showing it at least recognizes the right GO and component and element:


    When I Debug.Log the "new applied material":
    Code (CSharp):
    1.   Debug.Log("New Applied material: " + meshRenderer.sharedMaterials[1].name);
    The same (old) material from before the swap is returned.

    Any ideas on why it is not resetting the material(s)? I realize using shared materials results in a permanent change which is ok for now, I'd rather have some sort of change than no change at all.

    Thank you for your suggestions!!!!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,970
    Getting an array that lives inside the Unity engine will return a copy of the array, referencing the original materials.

    This means when you access meshRenderer.sharedMaterials you are getting a temp copy, so when you assign it, it goes nowhere, just dropping that modified temp array, leaving the original untouched.

    Instead, copy out the entire array (System.Array.Copy) to your own array, change any entries you want to change, then set the entire array back to the .sharedMaterials property.
     
  3. MatthewPlaudis

    MatthewPlaudis

    Joined:
    Apr 19, 2019
    Posts:
    2

    Thanks Kurt, I'll give that a try! :D