0
\$\begingroup\$

I want to have one material applied to multiple objects that has a random color on each object. How can I achieve this so that I don't need to use a different material for every object? This is in Unity 5 by the way.

\$\endgroup\$
  • 1
    \$\begingroup\$ What is your code environment, platform etc? \$\endgroup\$ – madneon Nov 23 '16 at 3:36
  • \$\begingroup\$ Good point, I'll add it to the description \$\endgroup\$ – mr-matt Nov 23 '16 at 4:22
  • \$\begingroup\$ Vertex colours, texture atlassing, mutliple UV channels, worldspace colouring, material property blocks, instanced rendering, lots of options. What kinds of objects are you colouring, and what do they need to do? \$\endgroup\$ – DMGregory Nov 23 '16 at 4:58
  • \$\begingroup\$ Those are some good ideas thanks. The transom colors after for the shirts a group of 100+ people so I don't want them all to have the same shirts. \$\endgroup\$ – mr-matt Nov 23 '16 at 5:13
  • 1
    \$\begingroup\$ Possible duplicate of How can I change the color of an object at runtime? \$\endgroup\$ – Philipp Nov 23 '16 at 9:33
2
\$\begingroup\$

You can change the color of the same material, on different objects, from script. Do the following:

  1. Create a materialand assign it to the target game object.

  2. Create a new C# script, and copy in the following code. Inside "parent" the objects whose color should change is placed in the unity editor.


using UnityEngine;
using System.Collections.Generic;

public class RandomColor : MonoBehaviour 
{
    public Transform parent;

    List<Transform> objectstoColor;

    void Start () 
    {
        objectstoColor = new List<Transform>();

        foreach (Transform item in parent)
        {
            objectstoColor.Add(item);
        }
    } 

    <summary>Method for changing the material color</summary>
    public void SwitchColors()
    {
        foreach (Transform item in objectstoColor)
        {
            Renderer rend = item.gameObject.GetComponent<Renderer>();
            rend.material.color = Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f);
        }
    }   
}

Creating material and game object Assigning the Script to any gameobject in the scene Calling the Method when button is clicked.

\$\endgroup\$
  • \$\begingroup\$ Changing renderer.material.color is a quick but dirty solution. A better way to do this is with a MaterialPropertyBlock. I marked this question as a duplicate of another question where I posted an answer which explains why that solution is better and how to do it in detail. \$\endgroup\$ – Philipp Nov 23 '16 at 9:34
  • \$\begingroup\$ Thanks philipp for that information. I am not familiar with that. I shall see that for sure. \$\endgroup\$ – Shuvro Sarkar Nov 23 '16 at 10:52
  • \$\begingroup\$ @Philipp your solution looks really good. How can I do that for multiple materials? I have 5 materials on each character, each one changing at runtime. Can that be done with your way? \$\endgroup\$ – mr-matt Nov 24 '16 at 23:00
  • \$\begingroup\$ @MatthewInglis If you have further questions about that other answer, please ask them there. \$\endgroup\$ – Philipp Nov 24 '16 at 23:21
  • \$\begingroup\$ @Gnemlock That shouldn't be the case with the way it's written here. Accessing the .material getter creates a copy of that material unique to that Renderer instance. (See the docs: "Modifying material will change the material for this object only. If the material is used by any other renderers, this will clone the shared material") You may be thinking of .sharedMaterial, which returns a reference to the current material without copying it. \$\endgroup\$ – DMGregory Dec 25 '16 at 4:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.