Change color of all children

I have been banging my head against the wall with this problem for like 2 days and I can’t do this anymore. I need help. I I am trying to achieve a simple effect where when the player can place down an object, it turns green. If he/she cannot place it down, then it turns red. And when the player does place it down, the object turns back to its original color. This effect is SOOO simple, but yet the hardest thing I have ever ran into. I seriously do not even know what to ask. Like, the material of the parent does change, but the material of all of the children does not change. I do not know what to do anymore. Here is some code snippets, good luck:

This happens when an “Obtainable” object gets created

if(primary == Primary.Place) { //If object is going to get placed down
                Renderer renderer = GetComponent<Renderer>();
                parentMaterials = renderer.sharedMaterials; //Sets the parent materials
               
                for(int a = 0; a < transform.childCount; a++) { //Loops through every child of object
                    Transform child = transform.GetChild(a); //Gets the current child
                    Renderer childRenderer = child.GetComponent<Renderer>();

                    if(childRenderer != null) //Checks to make sure object has a Renderer component
                        foreach(Material mat in childRenderer.sharedMaterials)
                            childMaterials.Add(mat);
                }
            }

This happens when the player can place something down

/*
                        //Change to preview color
                        */
                        foreach(Material mat in renderer.materials) { //Loops through every material of the parent
                            //Sets material to the preview material
                            mat.color = previewColor;
                        }

                        for(int a = 0; a < currentHeldObject.transform.childCount; a++) { //Loops through every child of the held object(if it has any)
                            Transform child = currentHeldObject.transform.GetChild(a); //Gets the child
                            Renderer childRenderer = child.GetComponent<Renderer>();
                           
                            if(childRenderer != null) { //Makes sure that the child has a Renderer component
                                foreach(Material mat in childRenderer.materials) { //Loops through every material of the child
                                    //Sets material to the preview material
                                    mat.color = previewColor;
                                }
                            }
                        }

This happens when the player cannot place anything down

PlayerManager.Instance.interactSettings.primaryCanInteract = false;
                   
                    foreach(Material mat in renderer.materials) { //Loops through every material of the parent
                        //Sets material to the preview material
                        mat.color = errorColor;
                    }
                   
                    for(int a = 0; a < currentHeldObject.transform.childCount; a++) { //Loops through every child of the held object(if it has any)
                        Transform child = currentHeldObject.transform.GetChild(a); //Gets the child
                        Renderer childRenderer = child.GetComponent<Renderer>();
                       
                        if(childRenderer != null) { //Makes sure that the child has a Renderer component
                            foreach(Material mat in childRenderer.materials) { //Loops through every material of the child
                                //Sets material to the preview material
                                mat.color = errorColor;
                            }
                        }
                    }

This happens when the player clicks and wants to place down an item

if(obtainable.primary == Objects.Obtainable.Primary.Place) { //Makes sure held object is a placeable
                        renderer.materials = obtainable.parentMaterials; //Sets the material of the held object's parent to it's original material

                        for(int a = 0; a < currentHeldObject.transform.childCount; a++) { //Loops through every child of held object
                            Transform child = currentHeldObject.transform.GetChild(a); //Gets the child
                            Renderer childRenderer = child.GetComponent<Renderer>();

                            if(childRenderer != null) //Makes sure the child has a Renderer component
                                for(int b = 0; b < childRenderer.materials.Length; b++) //Loops through every material on the child
                                    childRenderer.materials[b] = obtainable.childMaterials[b]; //Assigns the correct material of the child
                        }
                    }

GetComponentsInChildren will probably make your code cleaner and easier to trace.

At a glance I can’t see the issue.

1 Like

Thank you man. God, its always a simple fix LOL. Right now, I do have a weird set up. I have a List of an array ha ha. Any tips on doing this better? Like, I make a variable called public List<Material[ ]> materials = new List<Material[ ]>();, and this is where every material on the object is stored. Whenever I want to change these materials, I do this:

Renderer[] renderers = currentHeldObject.GetComponentsInChildren<Renderer>();

for(int i = 0; i < renderers.Length; i++) {
    //The line below "resets" the materials
    //renderers[i].materials = obtainable.materials[i];
   
    //If I want to change to an entirely different material, I do this
    //renderers[i].materials = anArrayOfMaterials;
}

I mean, this works perfectly for me. But, having an array inside of an array can be a little tricky. Any tips on making this better?

1 Like