Can't Change Material of Multiple gameObjects?

I’m trying to change the material of multiple gameObjects (that all share the same material) when a certain requirement is met.

using UnityEngine;
using System.Collections.Generic;

public class U1 : MonoBehaviour
{
    private double U1TimesBought;
    private double U1TimesBoughtMax;

    public List<MeshRenderer> objectsToChange;
    [SerializeField] private MeshRenderer rend;
    public Material Purchased;
    public Material Unpurchased;
    public Material Maxed;
    public Material NotMaxed;

    void Update()
    {
        if (U1TimesBought == U1TimesBoughtMax)
        {
            foreach (MeshRenderer renderer in objectsToChange) {
                gameObject.GetComponent<MeshRenderer>().material = Purchased;
            }
            rend.material = Maxed;
            connector.SetActive(true);
        }
        else
        {
            foreach (MeshRenderer renderer in objectsToChange)
            {
                gameObject.GetComponent<MeshRenderer>().material = Unpurchased;
            }
            rend.material = NotMaxed;
            connector.SetActive(false);
        }
    }
}

(The objectsToChange and rend are two different things, that’s why they’re separate)

I don’t exactly know what to put in the “void Update()” but everything i’ve tried has not worked and I don’t know why. I’ve tried researching for at least an hour but I’ve found nothing that helps.
Is there something I’m missing?

maybe instead of using

foreach (MeshRenderer renderer in objectsToChange)
{
    gameObject.GetComponent<MeshRenderer>().material = desiredMaterial;
}

you should use

for (int i = 0; i < objectsToChange.Count; ++i)
{
    objectsToChange[i].material = desiredMaterial;
}

edit: i forgot the .material in the objectsToChange[i]

1 Like

I tried this and it says something along the lines of “This variable does not exist anymore.”

This should be:

            foreach (MeshRenderer renderer in objectsToChange) {
                renderer.material = Purchased;
            }

Right?

Because what your code does is change the script’s (current) game object renderer’s materials multiple times, once for every objectsToChange which doesn’t seem to make any sense.

Also note that you should use sharedMaterial rather than material or else every object will get its own copy of the same identical material.

what does that mean? could you please just copy the error message? (i.e. cs9999: this an error)

your solution doesn’t work, it causes a compiler error. (cs1656: Cannot assign to ‘renderer’ because it is a ‘foreach iteration variable’)

from Unity - Scripting API: Renderer.sharedMaterial

It is not recommended to modify materials returned by sharedMaterial. If you want to modify the material of a renderer use material instead.

so maybe don’t use sharedMaterial? just saying.

“MissingReferenceException: The variable objectsToChange of U1 doesn’t exist anymore.
You probably need to reassign the objectsToChange variable of the ‘U1’ script in the inspector.”


Like the error said, you should add the references for the objects you want to change to the objectsToChange variable, by pressing ‘+’ or ‘-’ to add or remove elements to the list, then dragging the objects to the desired element number. Also make sure the other variables have references, by again dragging the your materials and meshrenderer/object that contains the meshrenderer component (for the rend variable).

The OP’s code doesn’t change the material (properties), it changes the material assigned to the renderer. In that case: sharedMaterial.

When modifying a material properties at runtime, use material to avoid the Material asset from being permanently changed as well.

Ok. Thanks for letting me know the difference between them!

adios.

I’ve checked, the list has all the objects both in the editor and in the Game tab while running.

I tried this and it still shows the exact same error that I stated.
Also, how would I use sharedMaterial in this scenario?

Just try reassigning it in the inspector since I noticed that it’s a runtime exception, not a compilation error.

It is in the inspector. It always has been in the inspector. I double checked.

I’ve found this post quite interesting. Maybe you should read it, specifically the post itself, post no.5, no.6, no.8, and no.9.
If nothing works out for you, then just search missingreferenceexception unity on google and basically hundreds of other people have a similar problem as you do. Maybe you should even read them too.