2014-05-16 19 views
0

我目前正在制定每日時間系統,並且在那個系統中,我希望能夠控制SUNRISE在哪個小時開始,DAY開始,SUNSET開始和NIGHT開始。目前在系統中這是可能的,並且當「時鐘」碰到下一個開始時刻時,我啓動一個協同程序開始旋轉太陽和月亮。沒有協程的旋轉對象?

我的協同程序是這樣的:

IEnumerator RotateSun(Vector3 fDegrees, float SecondsDuringTimeSet) 
{ 
    Quaternion quaFromPosition = _lSunLight.transform.rotation; 
    Quaternion quaToPostion = Quaternion.Euler(fDegrees); 

    for (float t = 0.0f; t < 1; t += Time.deltaTime/SecondsDuringTimeSet) 
    { 
     _lSunLight.transform.rotation = Quaternion.Lerp(quaFromPosition, quaToPostion, t); 
     yield return null; 
    } 
} 

正如你看到的我值傳遞到每個I運行時間。這是這樣做的:

if (_fCurrGameHour == _fTimeStartSunrise && _bMoveSunAndMoonOnlyOnce == true) 
    { 
     // Which TIMESET should it be: 
     _en_CurrTimeSet = TimeSet.SUNRISE; 

     // How long should the SUN move and how many which degree should it reach before that time ends 
     vec3MoveSun = new Vector3(10.0f, 0, 0); 
     StartCoroutine(RotateSun(vec3MoveSun, _fConvertSunriseToGTSeconds)); 

     // How long should the MOON move and how many which degree should it reach before that time ends 
     vec3MoveMoon = new Vector3(180.0f, 0, 0); 
     StartCoroutine(RotateMoon(vec3MoveMoon, _fConvertSunriseToGTSeconds)); 

     // Tell bool that we don't need to move the sun and moon more then once 
     _bMoveSunAndMoonOnlyOnce = false; 
    } 

而且正如我寫的這個系統現在的作品。但它是一種靜態系統。所以目前我需要確保遊戲的開始時間是日出時間。否則,我的協同程序將會中斷,因爲它不會在一天的開始時間之前旋轉到正確的位置。而且我可以明確地不開始接近日落的比賽,然後太陽以完全錯誤的方式旋轉,因爲它接近於旋轉錯誤的方式(我假設)。

所以我的第一個問題是:我能以某種方式使系統更具動態性嗎?我希望能夠設定在哪個時間SUNRISE,DAY,SUNSET和NIGHT應該在不同季節開始,例如我可以在我的一天有不同的長度。我希望能夠在遊戲中改變這些小時,然後如果SUNSET將在稍後設置,則太陽將開始稍微慢一點旋轉,因爲它需要更長的時間才能達到SUNSET的位置。

到我的第二個問題:難道也有可能重寫我的協程,所以我可以在我想任何時間開始遊戲,太陽仍然會開始在正確度旋轉?

太陽將總是設置在相同的旋轉(170度),並上升以相同的旋轉(350度)。我只想控制它在到達這些旋轉之前所花費的時間。也許我可以以某種方式將它移動到我的更新階段,而不是使用Coroutine進行更新?我不知道如何在我的系統中改變這個,所以如果有人有任何想法。請幫忙。

+0

有沒有人現在呢? –

+0

我試過一些沒有成功的想法。有沒有人做過這個? –

回答

1

您可以通過使用State設計模式,您可以通過協程之遙。

public int SunRise = 8; 
public int SunSet = 15; 
public Quaternion RiseRotation; 
public Quaternion SetRotation; 
public int StartHour = 8; 

float time; // our time on a 24 hr system 
bool wasSun; // what was our previous state? 

void Start() 
{ 
    GoToHour(StartHour); 
    ToggleState(IsSun()); 
} 

void Update() 
{ 
    bool isSun = IsSun(); 

    if (isSun != wasSun) 
     ToggleState(isSun); 

    time = (time + Time.deltaTime) % 24; // wrap at 24 hrs back to 0 

    if (isSun) 
     UpdateSun(); 
    else 
     UpdateMoon(); 
} 

bool IsSun() 
{ 
    return time >= SunRise && time < SunSet 
} 

void UpdateSun() 
{ 
    float t = (time - SunRise)/(SunSet - SunRise); 
    UpdateRotation(_lSunLight.transform, RiseRotation, SetRotation, t); 
} 

void UpdateMoon() 
{ 
    float t; 

    if (time >= SunRise) 
     t = time - SunRise; 
    else 
     t = time + (24 - SunSet); 

    t = t/((24 - SunSet) + SunRise)); 
    UpdateRotation(_lMoonLight.transform, RiseRotation, SetRotation, t); 
} 

void GoToHour(int hour) 
{ 
    t = hour/24; 
} 

void ToggleState(bool isSun) 
{ 
    if (isSun) 
    { 
     // Custom logic here, turn on sun, turn off moon? 
    } 
    else 
    { 
     // Custom logic here, turn on moon, turn off sun? 
    } 

    wasSun = isSun; 
} 

static void SetRotation(Transform target, Quaternion start, Quaternion end, float t) 
{ 
    target.rotation = Quaternion.Lerp(start, end, t); 
} 

完全未經測試的代碼,但這是如何使用類更新太陽或月亮的基本思路。這是一個二進制實現,所以無論是太陽顯示還是月亮。如果你想重疊,你當然可以定製它很容易。你會想要不同的時間月亮升起和月亮設置,然後如果/月亮和太陽更新,則不需要。

代碼也基本相當,使很多的假設(日出無重疊24小時標記)。所有這些都可以被清理。您也可以創建變量來存儲每幀完成的計算(關於日出/設置的持續時間)。如果你想這樣做,只需在GoToHour方法中設置它。

SetRotation不是非常必要的,但它可以保持代碼的清潔。如果您以後決定要使用Quaternion.Sleep,則只需在一個位置進行更改。

我暴露在四元的檢查,你可以使用,而只是一個浮動爲度,或歐拉Vecter3。如果你這樣做,你可以在開始做一個轉換。

我希望這回答了所有的問題,如果沒有,隨意澄清什麼都不回答。

+0

謝謝,設法讓它工作。 :) –