Unity coroutine not running to the end

2019-09-14 18:33发布

问题:

I am having a weird problem with a coroutine.

Basically when I mouse over a sprite it fades in and out as long as the mouse pointer is over it, this works fine, but when the mouse exits the sprite I want the sprite to fade out until its alpha value reaches 0.

To do so and because unlike the OnMouseOver function which is called every frame while the mouse is over the collider, I use a coroutine called in my OnMouseExit function.

The code below is what I use, but as soon as the mouse exits the sprite, the sprite's alpha is set to 0 straight away, without fading out, I have no idea why, hence my post.

You will notice in the OnMouseExit function the last line is commented out, I have tried to call the coroutine using both methods, it gets called both times but the fade out does not happen in either call.

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

public class Fader : MonoBehaviour {

    public float min_fade_speed;
    public float max_fade_speed;

    private SpriteRenderer sprite;
    private float fade_speed;

    // Use this for initialization
    void Start () {
        fade_speed = Random.Range (min_fade_speed, max_fade_speed);
        sprite = GetComponent<SpriteRenderer> ();
        reset_color ();
    }

    void reset_color() {
        //Initially transparent
        sprite.color = new Color(1, 1, 1, 0.0f);
    }

    // Update is called once per frame -- currently unused
    void Update () {
    }

    void FadeInAndOut() {
        sprite.color = new Color (1, 1, 1, Mathf.SmoothStep (0.0f, 1.0f, Mathf.PingPong(Time.time/fade_speed, 1f)));
    }

    IEnumerator FadeOut(float alpha_start) {
        Debug.Log ("Alpha is: " + alpha_start);
        while (sprite.color.a > 0.0f) {
            sprite.color = new Color (1, 1, 1, Mathf.SmoothStep (alpha_start, 0.0f, Time.time / fade_speed));
            yield return null;
        }
    }

    void onMouseEnter() {
        reset_color ();
    }

    void OnMouseOver() {
        FadeInAndOut ();
    }

    void OnMouseExit() {
        float alpha = sprite.color.a;
        Debug.Log ("Alpha is: " + alpha);
        StartCoroutine ("FadeOut", alpha);
        // StartCoroutine(FadeOut(alpha));
    }
}

Regards

Crouz

回答1:

You need a counter variable in the Coroutine function that counts from 0 to fade_speed. You increment this variable in the while loop with Time.deltaTime. When that variable is >= fade_speed, exit the while loop. To get the new colorin the whole loop, you can do new Color(1, 1, 1, Mathf.Lerp(startingAlpha, 0, counter / fade_speed));.

Your new FadeOut function:

IEnumerator FadeOut(float alpha_start)
{
    //This will start decreasing from where it is
    float startingAlpha = sprite.color.a;

    float counter = 0;

    while (counter < fade_speed)
    {
        counter = counter + Time.deltaTime;
        sprite.color = new Color(1, 1, 1, Mathf.Lerp(startingAlpha, 0, counter / fade_speed));
        yield return null;
    }
}