首页 > 解决方案 > 如何停止协程但让 alpha 颜色在停止前先完成褪色?

问题描述

我有两个问题:

现在,当协程停止时,它会在中间停止褪色,我希望褪色首先完成然后停止。

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

public class FadeInOutSaveGameText : MonoBehaviour
{
    public Animator animator;
    public Canvas canvas;
    public float fadingSpeed;

    private bool stopFading = false;

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(OverAllTime(5f));
    }

    IEnumerator CanvasAlphaChangeOverTime(Canvas canvas, float duration)
    {
        var alphaColor = canvas.GetComponent<CanvasGroup>().alpha;

        while (true)
        {
            alphaColor = (Mathf.Sin(Time.time * duration) + 1.0f) / 2.0f;
            canvas.GetComponent<CanvasGroup>().alpha = alphaColor;

            if (stopFading == true)
            {
                break;
            }

            yield return null;
        }
    }

    IEnumerator OverAllTime(float time)
    {
        StartCoroutine(CanvasAlphaChangeOverTime(canvas, fadingSpeed));

        yield return new WaitForSeconds(time);

        stopFading = true;
        StopCoroutine("CanvasAlphaChangeOverTime");
    }
}

标签: c#unity3d

解决方案


如果你想停止你的协程,你必须将 StartCoroutine(...) 的返回值存储在一个成员变量中,并通过它的引用显式地停止它:

private Coroutine coroutine;
[...]
private void StartRoutine 
{
    if(coroutine == null)
        coroutine = StartCoroutine(...);
}

private void StopRoutine 
{
    if(coroutine != null)
    {
        StopCoroutine(coroutine);
        coroutine = null;
    }
}

但是在您的情况下,您不想停止协程,因为您希望它继续直到达到它的转折点(然后自行完成)。

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

public class FadeInOutSaveGameText : MonoBehaviour
{
    private const float THRESHOLD = 0.01F;

    [...]

    IEnumerator CanvasAlphaChangeOverTime(Canvas canvas, float duration)
    {
        var alphaColor = canvas.GetComponent<CanvasGroup>().alpha;

        while (true)
        {
            alphaColor = (Mathf.Sin(Time.time * duration) + 1.0f) / 2.0f;
            canvas.GetComponent<CanvasGroup>().alpha = alphaColor;

            // only break, if current alpha value is close to 0
            if (stopFading && Mathf.Abs(alphaColor) <= THRESHOLD)
            {
                break;
            }

            yield return null;
        }
    }

    IEnumerator OverAllTime(float time)
    {
        StartCoroutine(CanvasAlphaChangeOverTime(canvas, fadingSpeed));

        yield return new WaitForSeconds(time);

        stopFading = true;
        // do not stop routine, since it should run on until reaching 0
        //StopCoroutine("CanvasAlphaChangeOverTime");
    }
}

推荐阅读