2017-09-26 70 views
1

我想在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()如何創建這樣的代碼鏈永遠停止?淡入淡出時,我的意思是改變光線強度。

+0

你所說的 「淡出」 是什麼意思?你是說光的強度? – Programmer

+0

是的,我只是想改變光線強度 – peterHasemann

+0

出去做別的事情。回來看到一些答案,但他們需要改進,所以我加了我的。 – Programmer

回答

4

儘管這已經得到解決,目前的解決方案有以下幾種只是遞減變量並且還創建每個幀的新對象(WaitForSeconds)。

Unity中這樣做的正確方法是使用Mathf.LerpTime.deltaTime。這種類型的操作是從minLuminositymaxLuminosityMathf.Lerp。你可以在我的另一個問題中閱讀更多關於使用它的alpha分量here淡出/在GameObject中的內容。

我從answer中取得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函數來做到這一點。請注意,在while循環之外聲明WaitForSeconds是如何聲明的,以便它不會每次都創建新對象。

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

對不起,這並沒有工作,協程只是在那裏停止 – peterHasemann

+0

@peterHasemann我不明白這怎麼可能。你是否把正確的操作比操作員低劣和優越? – Isuka

+0

isuka,大概是第二個,而應該是「while(pointLight.intensity> minLuminosity)」,而不是「while(pointLight.intensity> maxLuminosity)」。 – rs232

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