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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Change child materials of a GameObject without creating instances of materials

Discussion in 'General Graphics' started by TxAg03, May 29, 2015.

  1. TxAg03

    TxAg03

    Joined:
    May 20, 2015
    Posts:
    21
    What I'm trying to do is select a single object of a parent and fade the rest to a specified transparent value. I'm using recursion to iterate through all the children of the parent and set all that aren't selected to a fade_material and those that are selected to an opaque_material.

    I have searched this topic for days and have not found a working solution.

    I've tried using Renderer.material and Renderer.sharedMaterial.


    Here's my recursive code that seems to make instances of materials vs just changing the material:

    private void ChangeMaterial(GameObject parent, bool excluded)
    {
    foreach (Transform child in parent.transform)
    {
    // Check if child is a parent to other children
    if(child.childCount > 0)
    {
    // More children... check if parent node is selected
    if(excluded || (child.gameObject == selectedObject))
    {
    ChangeMaterial(child.gameObject, true);
    }
    else
    {
    ChangeMaterial(child.gameObject, false);
    }
    }
    else
    {
    if(excluded || (child.gameObject == selectedObject) || (transparencySlider.value == transparencySlider.maxValue))
    {
    // Opaque
    Renderer rend = child.GetComponent<Renderer>();
    rend.material = child.GetComponent<ItemInfo>().opaqueMaterials[0];
    }
    else
    {
    // Fade
    Renderer rend = child.GetComponent<Renderer>();
    rend.material = child.GetComponent<ItemInfo>().fadeMaterials[0];

    }
    }
    }
    }

    Does the loop used have any affect over this issue?

    Thank you for your help...
     
  2. chrismarch

    chrismarch

    Joined:
    Jul 24, 2013
    Posts:
    465
    I've had some luck with creating one Material instance per desired material to use across a group of objects, and then assigning that Material instance to the sharedMaterial of all the objects I wanted to use it.
     
  3. testure

    testure

    Joined:
    Jul 3, 2011
    Posts:
    81
    That's pretty much what you're supposed to do if you want to avoid material duplication.

    Also- in the future use the Insert Code button so it's properly formatted for the forum, most people aren't going to bother reading your post if it's like that.
     
  4. TxAg03

    TxAg03

    Joined:
    May 20, 2015
    Posts:
    21
    Thank you chrismarch. That works. I was trying to create/store the material on each instance of a script and that was causing me my problems. Moved the material array variable to something more global, like a GameController, and referenced from there and all problems are fixed.

    Looked, but never hard enough to find the code insert until you mentioned it testure... thank you.