Fading opacity flickers when used with `OnTriggerEnter2D` but works fine with key press

Hello, I’ve got this code:

 private void Update() {
        if (Input.GetKeyDown("f")) {
            StartCoroutine(Fade());
        }

        if (performFade) {
            StartCoroutine(Fade());
        }
    }
   
    IEnumerator Fade() {
        Color c = _spriteRenderer.material.color;
        for (float alpha = 1f; alpha >= -0.2; alpha -= 0.1f) {
            c.a = alpha;
            _spriteRenderer.material.color = c;
            yield return new WaitForSeconds(.1f);
        }

        performFade = false;    
    }

private void OnTriggerEnter2D(Collider2D other) {
    if (other.CompareTag("Player")) {
        performFade = true;
    }
}

This works fine when uses by pressing the f key.
But when invoked from within OnTriggerEnter2D I get flickering on the fading.

The Coroutine example is taken directly from the Unity manual so I think it’s pretty solid :slight_smile:

I’ve seen multiple posts on how to achieve this effect on trigger but none of them work properly (including the one by the chap who says never to use Coroutines for this but doesn’t explain why not). Sorry, I can’t find the links now.

My understanding is that because this is a Coroutine, it would execute the fading one frame at a time. And, as I say, it works fine when triggered by the keyboard press but not with OnTriggerEnter2D. Any ideas why that might be?

Does OnTriggerEnter do some other sort of magic that I’m unaware of?

Any help would be greatly appreciated.

Thanks

line 6-7 will execute every frame,
so multiple coroutines will be running at the same time.

note also, OnTriggerEnter2D might get called again (if player moves out and back in),
before previous coroutine has finished (that would cause flicker too).

yield return null; // this would wait 1 frame

But the same is true for the key press, right?

If I use yield return null; the fading happens immediately. How can I add a delay in that case so that it happens a bit slower?

What do you recommend?

getkeydown is done only once, try clicking F key really fast, it should start multiple coroutines then also.

“performFade” is true all the time, after entered trigger,
so first aid would be to set it false after line 6…

usually i set fade duration like this,

and to have more control of the fade, if use AnimationCurve, instead of linear decrements.
Camera Position Lerp With AnimationCurve · GitHub *this is for position, but could be used on that fade script above.

Ah cheers mate! I’m new to Coroutines, we don’t have anything similar in Swift :slight_smile:

Thanks for this, I was finally able to get it to work after about 2 days fighting with it!