Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Changing colors of a material for separate prefab instances

Discussion in 'Unity 5 Pre-order Beta' started by 0x0000, Nov 22, 2014.

  1. 0x0000

    0x0000

    Joined:
    Apr 21, 2014
    Posts:
    5
    I have a collection of characters that are all copies of the same prefab. This prefab has a world canvas object that has several elements (such as name, health, level, etc...). Each of the elements uses a material built specifically for that element (such as health_material or name_material) that also uses the standard shader (so I can add glow and other effects). I want health to always be visible to the player, but the name and level to only be visible when the player selects one of these characters.

    I just want to change the alpha value of one of these instances "name/level info" to fade it in when the character is selected, and let it fade out when the character is deselected. As it currently stands, since I am using the standard shader, the color field on the Text and RawImage component is completely ignored (is that intentional?) so my only option right now is to go into the material and change the color of the material itself using the "_Color" property. Of course, this changes the color for all other objects using that material, which is undesirable. My next thought was to create a new material for every element instance (not very efficient, but I am running out of ideas here) and use the same method of modifying the "_Color" property for that copy of the original material. Now, the copy of the material, after I assign it to the RawImage/Text material variable, is drawing black and ignoring all changes I make to it. The strangest part is that if I open up the element in the inspector, double click on the material field for the RawImage/Text component (this material is the copy of the original material) and just touch anything (like opening the color picker for the Albedo color) the material will fix itself and render correctly from then onwards. At first I thought I just needed to mark the material as dirty in my script to cause the same effect, but that is not the case.

    TL;DR: How do I copy a material at runtime/change that copies color?

    Am I doing something glaringly wrong here? Should I not be using the standard shader for UI elements? Is there some known bug that is getting in my way?
     
  2. one_one

    one_one

    Joined:
    May 20, 2013
    Posts:
    621
    Have you looked into the difference between sharedMaterial and material?
     
  3. 0x0000

    0x0000

    Joined:
    Apr 21, 2014
    Posts:
    5
    Yes, I am familiar with that pattern. The Raw Image and Text components, heck even the Canvas Renderer, do not implement that pattern in the same was as any other Renderer as far as I know, I think that the material of UI objects is just always shared.

    Thanks for the thought though.
     
  4. one_one

    one_one

    Joined:
    May 20, 2013
    Posts:
    621
    Ah, too bad. I don't think unity has implemented a clone method for materials, so you apparently would have to write your own and then adjust the color of the copy you created.
     
  5. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,657
    Not really. What's happening is that the UI system feeds the colour field of Text/RawImage components into the vertices of the mesh it generates; it expects the shader to then read that colour and use it. The standard shader doesn't do this, which is why you're not seeing the colour field have any effect on the output.

    The simplest fix is probably to write your own surface shader which uses the PBR lighting function (like the Standard shader) but also uses vertex colour to tint the surface properties (like the UI shaders). Support for this was added in beta 12; check the beta 12 release notes for some hints on how to do it, along with the documentation for surface shaders.