Change material color draw calls

Hi there.

I am in the process of making certain game objects transparent if they are between the player and the camera. When they leave this area they return to the normal opacity (1.0f).
I am aware that a new copy of the material is created when changing the color alpha, but I don’t know how to proceed to set the original material back in order to get the object batched.

Here is the code I am using:

private static Material defaultMaterial;

    // Use this for initialization
    void Start()
    {
        if (defaultMaterial != null)
        {
            defaultMaterial = (Material)Material.Instantiate(this.renderer.material);
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (timeToFade > 0)
        {
            timeToFade -= Time.deltaTime;

            if (shouldFadeIn)
            {
                Color c = this.renderer.material.color;
                c.a = minimumFade + ((fadeDuration - timeToFade) * (1.0f - minimumFade) / fadeDuration);
                this.renderer.material.color = c;

                if (timeToFade <= 0)
                {
                    this.renderer.material = defaultMaterial;
                    Debug.Log("Faded IN");
                }

                
            }
            else
            {
                Color c = this.renderer.material.color;
                c.a = minimumFade + (timeToFade * (1.0f - minimumFade) / fadeDuration);
                this.renderer.material.color = c;

                if (timeToFade <= 0)
                {
                    Debug.Log("Faded OUT");
                }
            }
        }
    }

The approach in this code doesn’t work. Any ideas on how to do it?

You should use this for the default material:

defaultMaterial = renderer.sharedMaterial;

You should also have a Material variable for the material instance (don’t use a static variable, because then it will be the same for all objects):

instanceMaterial = (Material)Instantiate(renderer.sharedMaterial);

When you want to change the material, do this:

renderer.material = instanceMaterial;
instanceMaterial.color = whatever;

Then to switch back:

renderer.material = defaultMaterial;

–Eric

Hey, thanks. It worked like a charm.

In case anyone else is interested, here is the final code, hope it helps:

public class EnviromentFade : MonoBehaviour
{
    public float fadeDuration = 0.5f;
    public float minimumFade = 0.2f;

    private float timeToFade = 0f;
    bool shouldFadeIn = false;
    bool hadInstancedMaterial = false;

    private Material defaultMaterial;

    void Start()
    {
        defaultMaterial = this.renderer.sharedMaterial;
    }

    void Update()
    {
        if (timeToFade > 0)
        {
            timeToFade -= Time.deltaTime;

            if (shouldFadeIn)
            {
                Color c = this.renderer.material.color;
                c.a = minimumFade + ((fadeDuration - timeToFade) * (1.0f - minimumFade) / fadeDuration);
                this.renderer.material.color = c;

                if (timeToFade <= 0)
                {
                    this.renderer.material = defaultMaterial;
                    hadInstancedMaterial = false;
                }
            }
            else
            {
                if (!hadInstancedMaterial)
                {
                    hadInstancedMaterial = true;
                    this.renderer.material = (Material)Material.Instantiate(this.renderer.sharedMaterial);
                }

                Color c = this.renderer.material.color;
                c.a = minimumFade + (timeToFade * (1.0f - minimumFade) / fadeDuration);
                this.renderer.material.color = c;
            }
        }
    }

    public void FadeIn()
    {
        timeToFade = fadeDuration;
        shouldFadeIn = true;
    }

    public void FadeOut()
    {
        timeToFade = fadeDuration;
        shouldFadeIn = false;
    }
}