随着时间的推移增加和减少光强度

时间:2017-09-26 07:14:46

标签: c# unity3d

我想在Unity中创建一些萤火虫。我想增加光强度然后等待几秒钟,然后在Unity中减少它。当它们产生时,我希望它们增加光照强度,等待几秒钟然后淡出。如何以干净的方式创建这个“过程”?

private Light pointLight; // The light component of the firefly

private float minLuminosity = 0; // min intensity
private float maxLuminosity = 1; // max intensity

private float luminositySteps = 0.005f; // factor when increasing / decreasing

private float shineDuration = 3; // wait 3 seconds when faded in

private void Start()
{
    pointLight = GetComponent<Light>();
    pointLight.intensity = Random.Range(minLuminosity, maxLuminosity); // start with a random intensity
    StartCoroutine(ChangeIntensity()); // start the process
}

private IEnumerator ChangeIntensity()
{
    pointLight.intensity += luminositySteps; // increase the firefly intensity / fade in
    yield return new WaitWhile(() => pointLight.intensity >= maxLuminosity); // wait for the maximum intensity

    yield return new WaitForSeconds(shineDuration); // wait 3 seconds

    pointLight.intensity -= luminositySteps;
    yield return new WaitWhile(() => pointLight.intensity <= maxLuminosity); // wait for the minimum intensity

    StartCoroutine(ChangeIntensity()); // do it again
}

很明显,协程在第一个WaitWhile()永远停止了?如何创建这样的代码链?淡入或淡出时,我的意思是改变光强度。

3 个答案:

答案 0 :(得分:4)

即使已经解决了这个问题,当前的解决方案只是递减变量,并且每帧都会创建新对象(WaitForSeconds)。

在Unity中执行此操作的正确方法是使用Mathf.LerpTime.deltaTime。这种类型的操作是从Mathf.LerpminLuminosity的{​​{1}}。您可以在我的其他问题中阅读更多相关信息,以便使用其alpha分量here淡出/使用GameObject。

我从answer获取maxLuminosity函数并移植它以使用fadeInAndOut组件。这是一个简单的淡入淡出功能:

Light

现在,要创建所需的精确效果,即增加光照强度,然后等待几秒钟然后减小它,创建另一个调用上述函数的协同程序函数并等待它完成。你可以通过产生IEnumerator fadeInAndOut(Light lightToFade, bool fadeIn, float duration) { float minLuminosity = 0; // min intensity float maxLuminosity = 1; // max intensity float counter = 0f; //Set Values depending on if fadeIn or fadeOut float a, b; if (fadeIn) { a = minLuminosity; b = maxLuminosity; } else { a = maxLuminosity; b = minLuminosity; } float currentIntensity = lightToFade.intensity; while (counter < duration) { counter += Time.deltaTime; lightToFade.intensity = Mathf.Lerp(a, b, counter / duration); yield return null; } } 函数来做到这一点。注意如何在fadeInAndOut循环之外声明WaitForSeconds,以便每次都不会创建新的Object。

while

<强> USAGE

//Fade in and out forever
IEnumerator fadeInAndOutRepeat(Light lightToFade, float duration, float waitTime)
{
    WaitForSeconds waitForXSec = new WaitForSeconds(waitTime);

    while (true)
    {
        //Fade out
        yield return fadeInAndOut(lightToFade, false, duration);

        //Wait
        yield return waitForXSec;

        //Fade-in 
        yield return fadeInAndOut(lightToFade, true, duration);
    }
}

答案 1 :(得分:1)

代码中的问题是您只应用了一次光度变化,因此永远不会达到WaitWhile条件。我会将WaitWhile更改为简单的while循环,然后使用WaitForEndOfFrame

private IEnumerator ChangeIntensity()
{
    while(true)
    {
        while(pointLight.intensity <= maxLuminosity)
        {
            pointLight.intensity += luminositySteps; // increase the firefly intensity / fade in
            yield return new WaitForEndOfFrame();
        }

        yield return new WaitForSeconds(shineDuration); // wait 3 seconds

        while(pointLight.intensity > minLuminosity)
        {
            pointLight.intensity -= luminositySteps;
            yield return new WaitForEndOfFrame();
        }
    }
}

答案 2 :(得分:0)

所以我通过使用以下while循环来获得它

private IEnumerator ChangeIntensity()
{
    while (true)
    {
        pointLight.intensity += isIncreasing ? luminositySteps : -luminositySteps;

        if (pointLight.intensity <= minLuminosity)
            isIncreasing = true;

        if (pointLight.intensity >= maxLuminosity)
        {
            isIncreasing = false;
            yield return new WaitForSeconds(shineDuration);
        }

        yield return null;
    }
}