Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

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

Discussion in 'Scripting' started by kakubeiUK, Sep 5, 2023.

  1. kakubeiUK

    kakubeiUK

    Joined:
    Jul 11, 2014
    Posts:
    4
    Hello, I've got this code:

    Code (CSharp):
    1.  private void Update() {
    2.         if (Input.GetKeyDown("f")) {
    3.             StartCoroutine(Fade());
    4.         }
    5.  
    6.         if (performFade) {
    7.             StartCoroutine(Fade());
    8.         }
    9.     }
    10.    
    11.     IEnumerator Fade() {
    12.         Color c = _spriteRenderer.material.color;
    13.         for (float alpha = 1f; alpha >= -0.2; alpha -= 0.1f) {
    14.             c.a = alpha;
    15.             _spriteRenderer.material.color = c;
    16.             yield return new WaitForSeconds(.1f);
    17.         }
    18.  
    19.         performFade = false;    
    20.     }
    21.  
    22. private void OnTriggerEnter2D(Collider2D other) {
    23.     if (other.CompareTag("Player")) {
    24.         performFade = true;
    25.     }
    26. }
    27.  
    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 :)

    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
     
  2. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,058
    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
     
  3. kakubeiUK

    kakubeiUK

    Joined:
    Jul 11, 2014
    Posts:
    4
    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?
     
  4. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,058
    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,
    https://gist.github.com/unitycoder/dd464da0f0ffe5041e46#file-colorfader-cs-L13

    and to have more control of the fade, if use AnimationCurve, instead of linear decrements.
    https://gist.github.com/unitycoder/eb3833e1bda8ac2c04fca2a3eb343cb0#file-cameralerp-cs-L21 *this is for position, but could be used on that fade script above.

    https://docs.unity3d.com/ScriptReference/AnimationCurve.html
     
  5. kakubeiUK

    kakubeiUK

    Joined:
    Jul 11, 2014
    Posts:
    4
    Ah cheers mate! I'm new to Coroutines, we don't have anything similar in Swift :)

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