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

How to change material color?

Discussion in 'Scripting' started by sam268, Dec 16, 2014.

  1. sam268

    sam268

    Joined:
    Apr 21, 2014
    Posts:
    149
    So, I have a script that, when isSelected = true, the object turns green. Works fine.

    if (isSelected) {blahblahblah change color blahblahblah}

    So that is how i did it. However, I want the object to return to its normal material (not tinted green) when isSelected = false. In theory the game should do that automatically, as the above line of code is in the update function. However, even after I deselect the object, the color is still green. Weird. Help?
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I would assume you changed the actual material in your project, rather than an instance of the material on an object.

    --Eric
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,514
    What Eric5h5 means is that if you have a reference to a material (dragged into a public variable in your script) and you change that, then you will change the actual on-disk asset.

    Before using such a variable in your script, you should (in your Start() function), make a copy of it, which you would then change in your game.

    Code (csharp):
    1.  
    2. public Material TheMaterial;
    3.  
    4. void Start()
    5. {
    6.     // replace the material reference with an instance
    7.     TheMaterial = new Material( TheMaterial);
    8. }
    9.  
    10. // and from now on you can use it however you like, it's just a copy...
    11.  
    This is not without its caveats: if you have many scripts doing this, then each one will have its own drawcall, and that will impact performance. You would then need to do it only once and have all such objects share that new material instance.
     
  4. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    Code (CSharp):
    1. //You have to change it back, as well
    2. renderer.material.color = (isSelected) ? selectedColor : defaultColor;
    3.  
     
  5. sam268

    sam268

    Joined:
    Apr 21, 2014
    Posts:
    149
    No no this is what i mean

    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. var tile1 : GameObject;
    5. var tile2 : GameObject;
    6. var tile3 : GameObject;
    7. var tile4 : GameObject;
    8. var tile5 : GameObject;
    9. var tile6 : GameObject;
    10. var isSelected : int;
    11. var c : Color;
    12.  
    13. //   0 = false     1 = true
    14. function Start () {
    15. PlayerPrefs.SetInt("isSelected", 0);
    16. }
    17.  
    18. function Update () {
    19. if (isSelected == 1) {
    20. gameObject.renderer.material.color = Color.green;
    21. tile1.renderer.material.color = Color.yellow;
    22. tile2.renderer.material.color = Color.yellow;
    23. tile3.renderer.material.color = Color.yellow;
    24. tile4.renderer.material.color = Color.yellow;
    25. tile5.renderer.material.color = Color.yellow;
    26. tile6.renderer.material.color = Color.yellow;
    27. }
    28. }
    29.  
    30. function OnMouseDown () {
    31. if (PlayerPrefs.GetInt("isSelected") == 0) {
    32. isSelected = 1;
    33. PlayerPrefs.SetInt("isSelected", 1);
    34. }
    35. }
    36.  
    37. function OnGUI () {
    38. if (isSelected == 1) {
    39.    if (GUI.Button(Rect(Screen.width/1.2 - (Screen.width/10)/2, Screen.height/3 - (Screen.height/10)/2, Screen.width/15, Screen.height/15), "Deselect")) {
    40.    isSelected = 0;
    41.    PlayerPrefs.SetInt("isSelected", 0);
    42.    }
    43. }
    44. }

    But my issue is that when I press the deselect button the tiles are still tinted green and yellow.
     
  6. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    then your update function should look like this:
    Code (JavaScript):
    1. function Update () {
    2.     if (isSelected == 1) {
    3.         gameObject.renderer.material.color = Color.green;
    4.         tile1.renderer.material.color = Color.yellow;
    5.         tile2.renderer.material.color = Color.yellow;
    6.         tile3.renderer.material.color = Color.yellow;
    7.         tile4.renderer.material.color = Color.yellow;
    8.         tile5.renderer.material.color = Color.yellow;
    9.         tile6.renderer.material.color = Color.yellow;
    10.     } else {
    11.         gameObject.renderer.material.color = defaultColor;
    12.         tile1.renderer.material.color = defaultColor;
    13.         tile2.renderer.material.color = defaultColor;
    14.         tile3.renderer.material.color = defaultColor;
    15.         tile4.renderer.material.color = defaultColor;
    16.         tile5.renderer.material.color = defaultColor;
    17.         tile6.renderer.material.color = defaultColor;
    18.     }  
    19. }
    But those game objects should really be in a list or an array so you can loop through them, rather than setting each one individually
     
  7. sam268

    sam268

    Joined:
    Apr 21, 2014
    Posts:
    149
    Ohhh ok, thank you. But is defaultColor a variable? Because if so that won't work

    But wont this make my game lag like hell? because I have hundreds of tiles with this script on them, and it is constantly processing the materials color if I use an else statement, am I correct?


    And how does an array work? I have heard alot about them but they seem quite complicated.
     
  8. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    Arrays are a very important and very basic tenant of computer programming.

    I suggest you start here: http://www.w3schools.com/js/js_arrays.asp

    As for your question, the renderer has to process the material every frame regardless of what changes you make to it. The amount of time it takes the carry out an assignment operation (in this case, telling it what color to be) is going to be negligible.

    EDIT: That being said, Eric (below) is right. You should put the content of your Update function inside of your OnMouseDown function, to eliminate redundancy.
     
    Last edited: Dec 17, 2014
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You really shouldn't use Update unless you need things to change every single frame, though. The code for changing the material should only run when the mouse is clicked, not every frame.

    --Eric
     
  10. sam268

    sam268

    Joined:
    Apr 21, 2014
    Posts:
    149
    Ok, thanks for the tips, but how do I change the color back to what it was originally?
     
  11. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    that would be what the "defaultColor" variable is for.
     
  12. sam268

    sam268

    Joined:
    Apr 21, 2014
    Posts:
    149
    Yes, but the defaultColor can not actually be a default color. I tried setting a Color variable, but the closest thing I could get to a "default" color is black, grey, clear, and white. Black makes my tiles black, grey makes them grey (ew), clear makes them black, and white makes them look like ultra high gamma lol. So what is a "default" color? Because I can not seem to find it on the color spectrum
     
  13. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    defaultColor is supposed to be a variable. You would set it like so:


    Code (JavaScript):
    1. var defaultColor : Color;
    2.  
    3. function Awake() {
    4.     defaultColor = gameObject.renderer.material.color;
    5. }
     
  14. sam268

    sam268

    Joined:
    Apr 21, 2014
    Posts:
    149
    Oh wait nevermind. White is the default color on the color spectrum... lol... well thanks for the help guys, case closed :)