2016-05-13 136 views
1

我正在寫一個函數,在一段時間內緩慢轉動90度。到目前爲止,一切工作正常,我只需要弄清楚如何使它圍繞轉換中心旋轉一點而不是旋轉。Unity3d隨着時間的推移圍繞一個特定的點旋轉

protected bool _isRotating = false; 
public IEnumerator RotateWithEasing(GameHelper.Axis axis, Vector3 isolatedAxisPoint, float inTime) 
{ 
    if(_isRotating) 
    { 
     yield break; 
    } 

    _isRotating = true; 

    var degrees = this.GetDegreesFromAxis(axis); 

    Quaternion fromAngle = transform.rotation; 
    Quaternion toAngle = Quaternion.Euler(transform.eulerAngles + degrees); 
    for (float t = 0f; t < 1f; t += Time.deltaTime/inTime) 
    { 
     transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t); 
     yield return null; 
    } 

    _isRotating = false; 
} 

任何人都可以幫助指出我在正確的方向,我如何修改它,使其圍繞指定的isolatedAxisPoint旋轉?

+0

在該點周圍繪製一個圓並沿着該圓移動它? – Master117

+0

這聽起來像是會起作用,我對統一很陌生我使用'Quaternion.Lerp'或'Quaternion.Slerp'作爲那個 –

+1

,你可能會很好地研究[旋轉](http:// docs。 unity3d.com/ScriptReference/Transform.RotateAround.html),結合'速度* deltatime',您可以添加緩解,甚至時間 –

回答

5

下面是一個實際的示例Unity Tween碰巧在文本編輯器中顯示的另一個窗口!

如果要旋轉的東西,實在是小巫見大巫只是使用的DeltaTime在一個IEnumerator一個循環,並調整爲:eulerAngles或只是調用旋轉。 (在Unity中從不使用四元數。)在這個例子中,我只是調用Rotate。

這是一個Unity的基本模式

以下是Unity中補間的基本圖案。你會在Unity中做這1000次!

  1. 計算結束時間
  2. 做一個while循環,直到達到該時間
  3. 每個幀,滑動(或其他)由適當的級分。

注意,當然,你

yield return null; 

內循環的,它的意思是「等到下一幀」。

(請注意,與任何吐溫,這是很好的做法,強制設定的最終值在年底,所以你知道它是完美的。在這個例子中,我簡單地設置爲:eulerAngles通知,在結束的時候,環路完成。)

private IEnumerator _roll(Vector3 delta) 
    { 
    rollBegins.Invoke(); 

    Vector3 begin = transform.eulerAngles; 

    float rollSecs = 2f; // speed of the roll 

    float startTime = Time.time; 
    float endTime = startTime+rollSecs; 

    while (Time.time < endTime) 
     { 
     Vector3 d = delta * (Time.deltaTime/rollSecs); 
     transform.Rotate(d, Space.World); 
     yield return null; 
     } 

    transform.eulerAngles = .. perfectly correct end values; 

    busy = false; 

    rollComplete.Invoke(); 
    } 

{注意,在實際的代碼示例中,「增量」理解爲僅在一個軸上;不用擔心,這只是一個使用協程的補間的例子。}

注 - 當然有「兩種方式」去循環內。你可以計算小數目你應該把它移動到那個框架。或者,您可以計算當時應該在的新位置。隨你便。許多程序員認爲後者更合乎邏輯,如果是這樣的話。還要注意的是,你可以在while循環中執行while循環,直到你到達目的地爲止! (非常小心浮動平等。)選擇是你的。非常非常經常使用線性插值甚至更​​好SmoothStep與這些充斥着的是

注意。它在Unity中無處不在。一旦你掌握了基本模式,就嘗試一下。

請注意,在我的示例中,代碼使用UnityEvent來標記動畫的開始和結束。這是非常普遍的。畢竟,通常情況下,一旦某個動作結束,你就必須繼續做其他事情。另一個很好的例子是,當某些動畫出現時,用戶被阻止轉向或遊戲中的任何情況。

優秀的介紹到UnityEvent https://stackoverflow.com/a/36249404/294884請投上一票:)


爲了記錄在案。

Tweeng in Unity。

的是先進的方式統一補間是tweeng:

Basic Tweeng code base appears in this question.

這需要一段時間才能得到的,該懸掛卻是令人難以置信的強大。令人驚訝的是,tweeng擴展只有幾行代碼。

+0

謝謝,這就是我正在尋找的東西,當我回家時我會測試這個,只是想知道是rollComplete一個內置的代表?還是某種類型的事件系統,可以防止它被稱爲多重時間直到它完成? –

+0

謝謝,關於設置我在角度之前注意到的末端歐拉角度的提示,我們稍微介紹一下,可能是因爲四捨五入的浮點十進制錯誤 –

+0

嗨,約翰尼,這是Unity中正確的模式。它就像是最基本的東西,有時候感覺就像你在Unity中編程一樣,嘿! 「rollComplete」是一個「unityEvent」,我已經包含了一個完整的解釋。這樣的協同補間就是使用UnityEvent的一個很好的例子。 – Fattie

0

使用類似,假設由90度在1秒旋轉:

int rotatedDegrees; 
int desiredRotation = 90; 
float startTime = null; 
float rotationDuration = 1f; 

public void rotate() 
{  
    if(startTime == null) 
    startTime = time.Now; 

    while((time.Now - starttime)/rotationDuration > (((float) rotatedDegrees)/desiredRotation)) 
    { 
    transform.RotateAround (isolatedAxisPoint, Vector3.up, 1); 
    rotatedDegrees++; 
    } 
} 

在開始時間+ 0它已經旋轉0度。

現在假設time.Now類似startTime + 0.1(+ 100ms)。然後time.Now - startTime爲0.1,旋轉直到(rotatedDegrees/desiredRotation)爲0.1,即9,或總旋轉的1/10。

+0

hm有趣,但time.Now如何與rotateDegrees/desiredRotation相關,不是時間,現在總是增加,或者不應該在協程中使變量不修改? –

+0

@ johnny5編輯,time.Now - startTime =自旋轉開始以來的時間。 – Master117

+0

謝謝,當我回家時,這看起來很穩定。如果它的工作,我會把它標記爲完整 –