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

我想在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(); 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()永远停止。我怎样才能创建这样的代码链? 淡入或淡出时,我的意思是改变光强度。

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

在Unity中执行此操作的正确方法是使用Mathf.LerpTime.deltaTime 。 这种类型的操作就是Mathf.Lerp所做的,它是从你的minLuminositymaxLuminosity 。 您可以在我的其他问题中阅读更多相关信息,以便在此处使用其alpha组件淡出/使用GameObject。

我从该答案中获取了fadeInAndOut函数并移植它以使用Light组件。 这是一个简单的淡入淡出function:

 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函数来做到这fadeInAndOut 。 注意WaitForSeconds是如何在while循环之外声明的while这样它每次都不会创建新的Object。

 //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); } } 

用法

 public Light lightToFade; public float eachFadeTime = 2f; public float fadeWaitTime = 5f; void Start() { StartCoroutine(fadeInAndOutRepeat(lightToFade, eachFadeTime, fadeWaitTime)); } 

您的代码中的问题是您只应用了一次亮度变化,因此永远不会达到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(); } } } 

所以我通过使用以下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; } }