Fading in/out GameObject

断了今生、忘了曾经 提交于 2019-12-27 11:51:59

问题


I'm fairly new to coding, I'm still trying to develop that logic of thinking to help me create the solutions I'm wanting for games. Currently, I'm in Unity trying to create a 2D GameObject that's a wall hiding a secret door. I want that GameObject to fade out (about 90%) when the player GameObject triggers it, revealing the space behind and the hidden door.

So far, I've managed to figure out how to render the "secret wall" GO inactive on the trigger, so it disappears, but this doesn't produce the visual that I'm going for. As I said, I'm still working on developing that coder's way of thinking, so while I've done a lot of research to solve this problem, many of the results I don't readily understand.

Here's my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SecretDoor1 : MonoBehaviour {

    void OnTriggerEnter2D (Collider2D SecretDoorTrig) {
         if (SecretDoorTrig.gameObject.tag == "Player") {
             GetComponent<SpriteRenderer> ().enabled = false;
         }
         else {
             GetComponent<SpriteRenderer> ().enabled = true;
         }
    }

    void OnTriggerExit2D (Collider2D SecretDoorTrig) {

         if (SecretDoorTrig.gameObject.tag == "Player") {

             GetComponent<SpriteRenderer> ().enabled = true;
         }
         else {
             GetComponent<SpriteRenderer> ().enabled = false;
         }
    }
}

回答1:


Fading a Sprite is almost the-same as moving GameObject over time except that you modify its alpha instead of it's position.

The three most important stuff about fading an Object are Time.deltaTime, Mathf.Lerp/Color.Lerp and coroutine. You need to understand how these work together.

Start coroutine, use Time.deltaTime to increment a variable. That variable is used to use to determine how much that function has ran. In a for/while loop, use that variable that is incremented every-frame and the duration you want the fade to happen to generate the alpha with the help of the Mathf.Lerp function. Create new color with that alpha and and assign it to the Sprite.

This is done every frame until that variable that is incremented with Time.deltaTime reaches the duration you want to the fade to happen within.

Here is a simple SpriteRenderer fade function:

public SpriteRenderer spriteToFade;

IEnumerator fadeOut(SpriteRenderer MyRenderer, float duration)
{
    float counter = 0;
    //Get current color
    Color spriteColor = MyRenderer.material.color;

    while (counter < duration)
    {
        counter += Time.deltaTime;
        //Fade from 1 to 0
        float alpha = Mathf.Lerp(1, 0, counter / duration);
        Debug.Log(alpha);

        //Change alpha only
        MyRenderer.color = new Color(spriteColor.r, spriteColor.g, spriteColor.b, alpha);
        //Wait for a frame
        yield return null;
    }
}

If you want it to fade in, change Mathf.Lerp(1, 0, counter / duration); to Mathf.Lerp(0, 1, counter / duration); which will make the alpha go from 0 to 1 over-time instead of 1 to 0.


From the example above, writing a fade-out and fade-in functions only requires a way to tell the function to change the alpha from 1 to 0 or from 0 to 1. You can make the function use a boolean or enum variable to determine which type of fade to perform. Of-course, you can separate the fade-in/fade-out functions but it's good to have it in one function.

Here is the extended version of that function that supports fade-in and fade-out. It also supports almost all GameObjects like MeshRenderer(3D), SpriteRenderer(2D), Image, RawImage....You can extend it to support more components that's missing.

IEnumerator fadeInAndOut(GameObject objectToFade, bool fadeIn, float duration)
{
    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;
    }

    int mode = 0;
    Color currentColor = Color.clear;

    SpriteRenderer tempSPRenderer = objectToFade.GetComponent<SpriteRenderer>();
    Image tempImage = objectToFade.GetComponent<Image>();
    RawImage tempRawImage = objectToFade.GetComponent<RawImage>();
    MeshRenderer tempRenderer = objectToFade.GetComponent<MeshRenderer>();
    Text tempText = objectToFade.GetComponent<Text>();

    //Check if this is a Sprite
    if (tempSPRenderer != null)
    {
        currentColor = tempSPRenderer.color;
        mode = 0;
    }
    //Check if Image
    else if (tempImage != null)
    {
        currentColor = tempImage.color;
        mode = 1;
    }
    //Check if RawImage
    else if (tempRawImage != null)
    {
        currentColor = tempRawImage.color;
        mode = 2;
    }
    //Check if Text 
    else if (tempText != null)
    {
        currentColor = tempText.color;
        mode = 3;
    }

    //Check if 3D Object
    else if (tempRenderer != null)
    {
        currentColor = tempRenderer.material.color;
        mode = 4;

        //ENABLE FADE Mode on the material if not done already
        tempRenderer.material.SetFloat("_Mode", 2);
        tempRenderer.material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
        tempRenderer.material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
        tempRenderer.material.SetInt("_ZWrite", 0);
        tempRenderer.material.DisableKeyword("_ALPHATEST_ON");
        tempRenderer.material.EnableKeyword("_ALPHABLEND_ON");
        tempRenderer.material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
        tempRenderer.material.renderQueue = 3000;
    }
    else
    {
        yield break;
    }

    while (counter < duration)
    {
        counter += Time.deltaTime;
        float alpha = Mathf.Lerp(a, b, counter / duration);

        switch (mode)
        {
            case 0:
                tempSPRenderer.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
                break;
            case 1:
                tempImage.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
                break;
            case 2:
                tempRawImage.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
                break;
            case 3:
                tempText.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
                break;
            case 4:
                tempRenderer.material.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
                break;
        }
        yield return null;
    }
}

Usage:

GameObject to fade:

public GameObject SpriteRend;

Fade-out in 3 seconds

StartCoroutine(fadeInAndOut(SpriteRend, false, 3f));

Fade-in in 3 seconds

StartCoroutine(fadeInAndOut(SpriteRend, true, 3f));



回答2:


The way I have accomplished this has been change the alpha on the sprite color.

Color(R,G,B,A). A is the alpha.

  • SpriteRenderer.color = new Color(1f,1f,1f,1f) is opaque.
  • SpriteRenderer.color = new Color(1f,1f,1f,.5f) is about 50% transparent.
  • SpriteRenderer.color = new Color(1f,1f,1f,0f) is about 100% transparent, sprite cannot be seen.


来源:https://stackoverflow.com/questions/44933517/fading-in-out-gameobject

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