Changing the colour of many objects at once (efficient material instancing)

I have 250+ objects in a grid pattern on screen that change colour depending on the current audio (like a flashing disco floor). I want to be able to change the colour of each objects material every tick at runtime. To do this I obviously have to return an instance of the material, which gives me 250+ instances of a material being looped through every tick, with changes to their colour. This drops my frame rate from 900~ to 350~.

Is there a more efficient way to be able to change the colour of many objects at once?

My code to run through them is:

 for (int a = 0; a < hexArray.Length; a++)
            {
                GameObject[] curRow = hexArray[a];

                for (int b = 0; b < curRow.Length; b++)
                {
                    GameObject grabHex = curRow**;**

if (grabHex != null)
{
Material material = grabHex.GetComponent().material;
//set colour
float colNum = AudioScript.amplitudeBuffer;
colNum = Mathf.Clamp(colNum, 0f, 1f);

Color newCol = new Color(colNum, colNum, colNum);
material.SetColor(“_Color”, newCol);
material.SetColor(“_EmissionColor”, newCol);
}
}
}

Cache your material’s for each gameobject in a dictionary so you don’t have to use getcomponent every frame, but only once for each gameobject.

private Dictionary<int, Material> _materialCache = new Dictionary<int, Material>();

Implement it like this:

    if (grabHex != null)
    {
        Material material;
        if (!_materialCache.TryGetValue(grabHex.GetInstanceID(), out material))
        {
            material = grabHex.GetComponent<Renderer>().material;
            _materialCache.Add(grabHex.GetInstanceID(), material);
        }

        //set colour
        float colNum = AudioScript.amplitudeBuffer;
        colNum = Mathf.Clamp(colNum, 0f, 1f);

        Color newCol = new Color(colNum, colNum, colNum);
        material.SetColor("_Color", newCol);
        material.SetColor("_EmissionColor", newCol);
    }