Itération 122442
Itération 122442

Reputation: 2962

Unity Mesh Renderer won't be completely transparent

I'm creating a script that allows objects to be faded considering an interval of time.

The script works very well, however when an object is faded, it is still very visible in the inspector AND in the build.

Could someone explain me why and how to make an object completely invisible? (I know I can "enable" the object, but isn't it using more resources than fading? I don't know :( )

Here is the code if I've made any mistake (code inspired from a topic in unity's forum)

// Update is called once per frame
void Update () 
{
    MyTime = Time.deltaTime;
    AccumulatedTime += MyTime;
    if (this.name == "Cube (1)")
    {
        Debug.Log(AccumulatedTime);
    }
    if (SwitchVisibility == 1)
    {

        if (AccumulatedTime >= Interval && AccumulatedTime<= 2*Interval || AccumulatedTime >= 3*Interval && AccumulatedTime<= 4*Interval)
        {
            StartCoroutine(FadeTo(0.0f, 1.0f));
            SwitchVisibility = 0;
        }
    }
    if (SwitchVisibility == 0)
    {
        if (AccumulatedTime >= 0 && AccumulatedTime <= Interval || AccumulatedTime >= 2*Interval && AccumulatedTime <= 3*Interval)
        {
            StartCoroutine(FadeTo(1.0f, 1.0f));
            SwitchVisibility = 1;
        }
    }
    if (AccumulatedTime >= Interval * 4.5f)
    {
        AccumulatedTime = 0;
    }
}

IEnumerator FadeTo(float aValue, float aTime)
{
    float alpha = MyRenderer.material.color.a;
    for (float t = 0.0f; t < 1.0f; t += Time.deltaTime / aTime)
    {
        OriginalColor.a = Mathf.Lerp(alpha, aValue, t);
        Color newColor = OriginalColor;
        MyRenderer.material.color = newColor;  
        yield return null;
    }
}

Here is what objects look like:

enter image description here

Upvotes: 0

Views: 5049

Answers (1)

Programmer
Programmer

Reputation: 125255

Assuming your code is fine, the problem very likely is from your Material settings. This changed in Unity 5. To change the alpha of a Mesh Renderer, you must also change the Material's Rendering Mode from Opaque(default) to Fade.

Transparent Mode is also fine but will will not be completely transparent and will result to the problem in your question.

You can change the mode from script.

Property Name: _Mode

With Debug.Log(MyRenderer.material.GetFloat("_Mode"));, I got the follwing values:

0 = Opaque
1 = Cutout
2 = Fade
3 = Transparent

We can change the Rendering Mode to Fade with MyRenderer.material.SetFloat("_Mode",2);

There is a known problem when setting the Render Mode from script. You must also update all other properties as well to make the change take effect. Here is a complete way to change your Render Mode to Fade from script:

MyRenderer.material.SetFloat("_Mode", 2);
MyRenderer.material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
MyRenderer.material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
MyRenderer.material.SetInt("_ZWrite", 0);
MyRenderer.material.DisableKeyword("_ALPHATEST_ON");
MyRenderer.material.EnableKeyword("_ALPHABLEND_ON");
MyRenderer.material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
MyRenderer.material.renderQueue = 3000;

Finally, if the this is working for you then your script is not good. You can use the script below to fade in and fade out a Mesh Renderer.

public MeshRenderer MyRenderer;
bool fading = false;

void Fade(bool fadeIn, float duration)
{
    if (fading)
    {
        return;
    }
    fading = true;

    changeModeToFade();
    StartCoroutine(FadeTo(fadeIn, duration));
}

void changeModeToFade()
{
    MyRenderer.material.SetFloat("_Mode", 2);
    MyRenderer.material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
    MyRenderer.material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
    MyRenderer.material.SetInt("_ZWrite", 0);
    MyRenderer.material.DisableKeyword("_ALPHATEST_ON");
    MyRenderer.material.EnableKeyword("_ALPHABLEND_ON");
    MyRenderer.material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
    MyRenderer.material.renderQueue = 3000;
}

IEnumerator FadeTo(bool fadeIn, float duration)
{
    //MyRenderer.material.
    float counter = 0f;

    //Set Values depending on if fadeIn or fadeOut
    float a, b;
    if (fadeIn)
    {
        a = 0;
        b = 1;
    }
    else
    {
        a = 1;
        b = 0;
    }


    //Enable MyRenderer component
    if (!MyRenderer.enabled)
        MyRenderer.enabled = true;

    //Get original Mesh Color
    Color meshColor = MyRenderer.material.color;


    //Do the actual fading
    while (counter < duration)
    {
        counter += Time.deltaTime;
        float alpha = Mathf.Lerp(a, b, counter / duration);
        Debug.Log(alpha);


        MyRenderer.material.color = new Color(meshColor.r, meshColor.g, meshColor.b, alpha);
        yield return null;
    }

    if (!fadeIn)
    {
        //Disable Mesh Renderer
        MyRenderer.enabled = false;
    }
    fading = false; //So that we can call this function next time
}

void Start()
{
    //Fade(true, 3f); //Fade In
    Fade(false, 3f);//Fade Out
}

Upvotes: 4

Related Questions