Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Change color of an individual Game Object

Discussion in 'Scripting' started by aerende, Jun 9, 2010.

  1. aerende

    aerende

    Joined:
    Apr 27, 2009
    Posts:
    316
    If I instantiate a number of Game Objects from a PreFab, is it possible to change the color of an individual Game Object? I know how to do this using Sprites, but can't figure out how to do it for an individual Game Object.
     
  2. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    657
    That should be fairly simple, but this is untested, so look out for minor mistakes :wink:

    Code (csharp):
    1.  
    2. GameObject whateverGameObject = whatever;
    3. Color whateverColor = new Color(whateverRValue,whateverGValue,whateverBValue,1);
    4.  
    5. MeshRenderer gameObjectRenderer = whateverGameObject.GetComponent<MeshRenderer>();
    6.  
    7. Material newMaterial = new Material(Shader.Find("Whatever name of the shader you want to use"));
    8.  
    9. newMaterial.color = whateverColor;
    10. gameObjectRenderer.material = newMaterial ;
    Good luck
     
  3. aerende

    aerende

    Joined:
    Apr 27, 2009
    Posts:
    316
    @Kragh:

    If all the Game Objects are using the same material, is it possible to change the color of one Game Object and not the others?
     
  4. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    657
    Yeah, I think so. In my code example I did just create a new material, and put that on, though.

    If you do changes on the material property of a MeshRenderer, I believe it will become an instanced material (you can check this in the editor. then material in the meshrender will get "(instance)" added to its name) and therefore your changes shouldn't affect other objects using it.
    This is in contrast to using the sharedMaterial property, which will modify all objects using this material.
     
    yesakman likes this.
  5. Ntero

    Ntero

    Joined:
    Apr 29, 2010
    Posts:
    1,436
    If you want to use model batching to reduce draw calls, you cannot modify the materials colour (if it's a shared material). using the above method will remove the model batching ability as well.

    A good way to retain the ability to have all those models in one draw call and have different coloured models is to change the vertex colours (and use a shader that supports vertex colours)

    A quick sample of how to change the vertex Colours:

    Code (csharp):
    1.  
    2. Mesh mesh = (gameObject.GetComponent(typeof(MeshFilter))as MeshFilter).mesh;
    3.  
    4. Color[] colours = mesh.colors;
    5.  
    6. for(int i = 0; i < colours.Length; i++)
    7. {
    8.     colours[i] = newColour;//the new colour you want to set it to.
    9. }
    10.  
    Sorry about the funny syntax on the GetComponent, I"m used to the iPhones missing features and can't recall what is easiest on PC.

    But if you use the right Shader and modify the colours of the vertices you can get a colour swap while retaining the same material. It's how the SpriteManager does it so that it I believe.
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Code (csharp):
    1. var go = Instantiate(myPrefab);
    2. go.GetComponent(Renderer).material.color = Color.blue; // or whatever
    --Eric
     
  7. renderizer

    renderizer

    Joined:
    Apr 13, 2012
    Posts:
    1
    Hi,
    I don't undestend.
    I make new mono script with code find in this thread.
    Then put it on geometry or material?
    It function with touch interaction on mobile? (iOS)
     
  8. alok-kr-029

    alok-kr-029

    Joined:
    Jan 10, 2013
    Posts:
    22
    var a : gameobject;
    a.renderer.material.color = Color.blue;

    works perfectly
     
    Robomobius, Ruzu and karthickoxygen like this.
  9. paranoidray

    paranoidray

    Joined:
    Oct 31, 2013
    Posts:
    2
    The best way to do this is to copy the existing Material ( Ctrl-D ) and then change the color on that new Material.
    And then in the code or in PlayMaker you can assign the new Material, that works much better and leaves other instances alone.
     
  10. IvanM71

    IvanM71

    Joined:
    Oct 28, 2019
    Posts:
    7
    Code (CSharp):
    1. target.GetComponent<MeshRenderer>().material.color = Color.red;
    And depending on your code sometime you will nee to make a check if the MeshRenderer is not nul, like:

    Code (CSharp):
    1. if (target.GetComponent<MeshRenderer>() != null){
    2. target.GetComponent<MeshRenderer>().material.color = Color.red
    3. }
     
    lordadamson likes this.
  11. SamuelVPi

    SamuelVPi

    Joined:
    Oct 20, 2020
    Posts:
    3
    I am a beginner, so I may ask some dumb questions, what do you type in the variable: GameObject whateverGameObject = whatever;
     
  12. SamuelVPi

    SamuelVPi

    Joined:
    Oct 20, 2020
    Posts:
    3
    I am a beginner and I need to know what to type in the variable: GameObject whateverGameObject = whatever;
    in the whatever part.
     
  13. SamuelVPi

    SamuelVPi

    Joined:
    Oct 20, 2020
    Posts:
    3
    Oops I accidentally posted the reply two times since I did not see the first one I posted.
     
  14. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    360
    The answer is literally just above your question.
    But you'll have to take the answer contextually. The variable names, the reference to the object etc depend on your actual implementation.
     
  15. mstarr

    mstarr

    Joined:
    Jun 20, 2018
    Posts:
    135
    This doesn't work for me. It says it's an obsolete/out of date API. It also won't let me auto-update the API.
     
  16. AnimalMan

    AnimalMan

    Joined:
    Apr 1, 2018
    Posts:
    1,164
    Code (CSharp):
    1. YourMaterial.SetColor("_Color", Color.red);
    you will be in trouble if you necro they will tell you to create a new thread if you have questions.
     
  17. ViviAlabaster

    ViviAlabaster

    Joined:
    Sep 1, 2013
    Posts:
    7
    Here's a solution I've used for several years now that will allow you to change an object's material color without affecting other objects using the same material.

    The tl;dr is that you can do this by creating a materialPropertyBlock, calling its SetColor function to change the "_Color" property, then using Renderer.SetPropertyBlock. A script that does this can be found below:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. /// <summary>
    6. /// Allows the changing of an object's color by changing it's renderer's Color materialPropertyBlock
    7. /// </summary>
    8. [ExecuteInEditMode]
    9. public class ARX_Script_IndividualColor : MonoBehaviour {
    10.  
    11.     #region Variables
    12.  
    13.     /// <summary>
    14.     /// The name of the Color property in the target shader.
    15.     /// Unity's naming convention prepends these names with an underscore. eg "_Color"
    16.     /// </summary>
    17.     public string mstr_colorPropertyName = "_Color";
    18.  
    19.     /// <summary>
    20.     /// The current color of the material block.
    21.     /// This is the color shown during Edit Mode.
    22.     /// When Play mode starts, this color will be set to
    23.     /// the value of mo_setOnStartColor
    24.     /// </summary>
    25.     [Tooltip("This is the color shown during Edit Mode.When Play mode starts, this color will be set to the value of mo_setOnStartColor")]
    26.     public Color mo_color;
    27.  
    28.     /// <summary>
    29.     /// The first color the material block will be set to when Play Mode Activates.
    30.     /// </summary>
    31.     [Tooltip("The first color the material block will be set to when Play Mode Activates.")]
    32.     public Color mo_setOnStartColor;
    33.  
    34.     /// <summary>
    35.     /// Set to a random color?
    36.     /// </summary>
    37.     public bool mb_makeRandomColor = false;
    38.  
    39.     /// <summary>
    40.     /// Change the color to setOnStartColor when Play Mode starts?
    41.     /// </summary>
    42.     public bool mb_setColorOnStart = false;
    43.  
    44.     /// <summary>
    45.     /// The default Alpha value of the random colors
    46.     /// </summary>
    47.     public float mnf_defaultAlpha = 0.5F;
    48.  
    49.     /// <summary>
    50.     /// The renderer component attached to this object
    51.     /// </summary>
    52.     Renderer mo_renderer;
    53.  
    54.     /// <summary>
    55.     /// The renderer's property block pointing to the "_Color" property
    56.     /// </summary>
    57.     MaterialPropertyBlock mo_propertyBlock;
    58.     #endregion
    59.  
    60.     #region Get
    61.  
    62.     /// <summary>
    63.     /// Returns the renderer component.
    64.     /// </summary>
    65.     Renderer GetRenderer { get
    66.         {
    67.             if(mo_renderer == null)
    68.                 mo_renderer = GetComponent<Renderer>();
    69.             return mo_renderer;
    70.         } }
    71.  
    72.     /// <summary>
    73.     /// Returns the MaterialPropertyBlock component
    74.     /// </summary>
    75.     MaterialPropertyBlock GetPropertyBlock { get
    76.         {
    77.             if(mo_propertyBlock == null)
    78.                 mo_propertyBlock = new MaterialPropertyBlock();
    79.             return mo_propertyBlock;
    80.         } }
    81.  
    82.     /// <summary>
    83.     /// Returns a random float Value between 0 and 0.5
    84.     /// </summary>
    85.     float RandomValueFromZeroToPointFive
    86.     {
    87.         get
    88.         {
    89.             return UnityEngine.Random.Range(0, 0.5F);
    90.         }
    91.     }
    92.     #endregion
    93.    
    94.     #region Functions
    95.  
    96.     /// <summary>
    97.     /// Set's the mo_color variable to a random color.
    98.     /// The material's color will change on the next frame.
    99.     /// </summary>
    100.     public void SetToRandomColor()
    101.     {
    102.         mo_color = new Color(RandomValueFromZeroToPointFive, RandomValueFromZeroToPointFive, RandomValueFromZeroToPointFive, mnf_defaultAlpha);
    103.     }
    104.    
    105.     #endregion
    106.    
    107.     #region Unity Overrides
    108.  
    109.     // Use this for initialization
    110.     void Start () {
    111.         if (Application.isPlaying == false)
    112.             return;
    113.  
    114.         if (mb_setColorOnStart)
    115.         {
    116.             mo_color = mo_setOnStartColor;
    117.         }
    118.     }
    119.  
    120. // Update is called once per frame
    121.     void Update () {
    122.         if (mb_makeRandomColor)
    123.         {
    124.             SetToRandomColor();
    125.             mb_makeRandomColor = false;
    126.         }
    127.         // Get the current value of the material properties in the renderer.
    128.         GetRenderer.GetPropertyBlock(GetPropertyBlock);
    129.         // Assign our new value.
    130.         GetPropertyBlock.SetColor(mstr_colorPropertyName, mo_color);
    131.         // Apply the edited values to the renderer.
    132.         GetRenderer.SetPropertyBlock(GetPropertyBlock);
    133.     }
    134.  
    135.     #endregion
    136. }
    137.