Unity Mesh Renderer won't be completely transparent

孤街浪徒 提交于 2019-12-01 12:29:35

问题


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:


回答1:


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
}


来源:https://stackoverflow.com/questions/39366888/unity-mesh-renderer-wont-be-completely-transparent

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!