Home > Net >  How to make a 50% fade in and a 100% fade out?
How to make a 50% fade in and a 100% fade out?

Time:07-19

How to make a sprite start to fade in and 1 second later when the opacity is 50% then its turning instantly to 100% and then 0.2 seconds later its within 0.5 seconds the opacity going to 100% to 0% and its repeat itself every 1 second?

I think this is a really hard question but I hope somebody will help my fix my problem.

-Thanks!

CodePudding user response:

I'm not sure if it's the best solution but I have some idea how to realize it. So we have Time.deltaTime valuable. It's the interval in seconds from the last frame to the current onetime to draw (Unity Documentation). So we can use it to count seconds. The other way to count secounds are Coroutines but it's more complicated in my opinion so I will use the first method.

So we have some Sprite we need to change.

public Sprite ourSprite;

Also (as DiplomacyNotWar proposed) we would use a simple state machine. We will use integer to store current state. And we need some timer to use it when we wait 0.2 seconds and when we wait 1 second before repeat:

public int state = 0;
public float timer = 0;

In Start() I find the SpriteRenderer component and set opacity to zero (to test work of the script).

void Start()
{
    ourSprite = this.GetComponent<SpriteRenderer>();
    ourSprite.color = new Color(ourSprite.color.r, ourSprite.color.g, ourSprite.color.b, 0);
}

And in Update() we realize out state machine. We use switch to control states. So we write simple code for each state and have this switch as a result:

void Update()
{
    switch (state) {
        case 0:
            ourSprite.color = new Color(ourSprite.color.r, ourSprite.color.g, ourSprite.color.b, ourSprite.color.a   Time.deltaTime * 0.5f);
            if (ourSprite.color.a >= 0.5f) {
                state = 1;
            }
            break;
        case 1:
            ourSprite.color = new Color(ourSprite.color.r, ourSprite.color.g, ourSprite.color.b, 1f);
            state = 2;
            break;
        case 2:
            timer  = Time.deltaTime;
            if (timer >= 0.2f) {
                timer = 0; //reseting timer
                state = 3;
            }
            break;
        case 3:
            ourSprite.color = new Color(ourSprite.color.r, ourSprite.color.g, ourSprite.color.b, ourSprite.color.a - Time.deltaTime * 2f);
            if (ourSprite.color.a <= 0) {
                state = 4;
            }
            break;
        case 4:
            timer  = Time.deltaTime;
            if (timer >= 1f) {
                timer = 0;
                state = 0;
            }
            break;
    }
}

The full code is here. I tested it on Unity 2021.3.5f1 and everything works fine. Don't forget to place this script on sprite object on your Scene and everything seems to work.

using UnityEngine;
using UnityEngine.UI;

public class spriteChange : MonoBehaviour
{
    private SpriteRenderer ourSprite;
    private int state = 0;
    private float timer = 0;

    // Start is called before the first frame update
    void Start()
    {
        ourSprite = this.GetComponent<SpriteRenderer>();
        ourSprite.color = new Color(ourSprite.color.r, ourSprite.color.g, ourSprite.color.b, 0); //setting sprite opacity to 0 in the beggining of scene
    }

    // Update is called once per frame
    void Update()
    {
        switch (state) {
            case 0:
                ourSprite.color = new Color(ourSprite.color.r, ourSprite.color.g, ourSprite.color.b, ourSprite.color.a   Time.deltaTime * 0.5f);
                if (ourSprite.color.a >= 0.5f) {
                    state = 1;
                }
                break;
            case 1:
                ourSprite.color = new Color(ourSprite.color.r, ourSprite.color.g, ourSprite.color.b, 1f);
                state = 2;
                break;
            case 2:
                timer  = Time.deltaTime;
                if (timer >= 0.2f) {
                    timer = 0; //reseting timer
                    state = 3;
                }
                break;
            case 3:
                ourSprite.color = new Color(ourSprite.color.r, ourSprite.color.g, ourSprite.color.b, ourSprite.color.a - Time.deltaTime * 2f);
                if (ourSprite.color.a <= 0) {
                    state = 4;
                }
                break;
            case 4:
                timer  = Time.deltaTime;
                if (timer >= 1f) {
                    timer = 0;
                    state = 0;
                }
                break;
        }
    }
}

CodePudding user response:

In most cases, coroutines will be fine for a such task.

(I wrote this code here, not in the IDE, so it can possibly contain some typos. But I think it will be enough to understand the principle and modify it according to your needs.)

// call this method when you need to begin the sequence
public void StartBlinking()
{
    StartCoroutine(CoBlinking());
}

IEnumerator CoBlinking()
{
    while(true) // to make this sequence repeat until we break it manually
    {
        // assume we have `_sprite` variable assigned
        yield return StartCoroutine(CoChangeAlpha(_sprite, 0f, 0.5f, 1f)); 
        
        SetSpriteAlpha(_sprite, 1f);
        
        yield return new WaitForSeconds(0.2f);
        
        yield return StartCoroutine(CoChangeAlpha(_sprite, 1f, 0f, 0.5f));

        // add other delays or changes if you need
    }
}

IEnumerator CoChageAlpha(Sprite sprite, float startAlpha, float endAlpha, float duration)
{
    float elapsed = 0f;
    while(elapsed < duration)
    {
        elapsed  = Time.deltaTime;
        float curAlpha = Mathf.Lerp(startAlpha, endAlpha, elapsed / 
duration);
        SetSpriteAlpha(sprite, curAlpha);
        yield return null;    
    }
}

void SetSpriteAlpha(Sprite sprite, float newAlpha)
{
    Color newColor = sprite.color;
    newColor.a = newAlpha; 
    sprite.color = newColor;   
}
  • Related