Search Unity

Getting thousands of new Materials...

Discussion in 'Scripting' started by LuisDeliz, Mar 29, 2015.

  1. LuisDeliz

    LuisDeliz

    Joined:
    Nov 27, 2012
    Posts:
    24
    Hey there.
    I have a grid based game where tiles fade in/out based on player distance. I've noticed on the Profiler that I'm making 5,000+ materials when at most there are 400 tiles on screen. Why?
    This is my fade code:

    Code (CSharp):
    1. public void Fade(Renderer r, Color to, string fadeColor, float speed)
    2.     {
    3.         r.material.color = Color.Lerp(r.material.color, to, speed * Time.deltaTime);
    4.         float c = r.material.color.a;
    5.         //fading in
    6.         if (c <= to.a)
    7.         {
    8.             if (Mathf.Abs(c/to.a) > 0.99f)
    9.             {
    10.                 changing = false;
    11.                 r.material = MaterialManager.instance.Get(fadeColor);
    12.             }          
    13.         }
    14.         //fading out
    15.         else
    16.         {
    17.             if (Mathf.Abs(to.a/c) > 0.99f)
    18.             {
    19.                 changing = false;
    20.                 r.material = MaterialManager.instance.GetClear(fadeColor);
    21.             }
    22.         }
    23.     }
    The MaterialManager returns a material from an array of pre-assigned materials. It does not create a new material.
     
  2. Anozireth

    Anozireth

    Joined:
    Feb 7, 2013
    Posts:
    71
  3. LuisDeliz

    LuisDeliz

    Joined:
    Nov 27, 2012
    Posts:
    24
    I read that, but that breaks the visuals of my tiles. It makes tiles that aren't near the edge also fade in/out because others share their materials. Thanks for responding though!
     
  4. Anozireth

    Anozireth

    Joined:
    Feb 7, 2013
    Posts:
    71
    You could try to create and cache the material for each tile when the tile is created. Then update the material itself in your Fade method, but don't assign it to the Renderer again. This would result in one material per tile of course, which may still be too many.

    The other option is to have a material manager that gets the material for a certain set of conditions (fade level, texture, etc). It looks like this is already what you're trying to do though, so it's hard to tell why that would fade other tiles in and out without more context.
     
  5. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    Whenever you access Renderer.material it will create a clone of the sharedMaterial if it hasn't already.
    Even something simple as:
    Code (csharp):
    1.          if (renderer.material != null) {
    2.             Debug.Log("Hello");
    3.         }
    Will create a new material. That is why your first line in the method will create a new material.
    The usual way to get around this, while keeping the same material, is to edit the vertex colors of the meshes, and use a shader that reads these.
     
    passerbycmc likes this.