2017-11-12 1 views
6

Ich habe eine Bezier-Kurve erstellt, indem ich das folgende Skript zu einem leeren Spielobjekt im Inspektor hinzugefügt habe. Dies zeichnet die Kurve sofort auf, wenn ich den Code ausführe. Wie kann ich es über einen bestimmten Zeitraum animieren, sagen wir 2 oder 3 Sekunden?Wie animiere ich eine Bezier-Kurve über eine bestimmte Dauer?

public class BCurve : MonoBehaviour { 

LineRenderer lineRenderer; 
public Vector3 point0, point1, point2; 
int numPoints = 50; 
Vector3[] positions = new Vector3[50]; 

// Use this for initialization 
void Start() { 
    lineRenderer = gameObject.AddComponent<LineRenderer>(); 
    lineRenderer.material = new Material (Shader.Find ("Sprites/Default")); 
    lineRenderer.startColor = lineRenderer.endColor = Color.white; 
    lineRenderer.startWidth = lineRenderer.endWidth = 0.1f; 
    lineRenderer.positionCount = numPoints; 

    DrawQuadraticCurve(); 

} 

void DrawQuadraticCurve() { 
    for (int i = 1; i < numPoints + 1; i++) { 
     float t = i/(float)numPoints; 
     positions [i - 1] = CalculateLinearBeziearPoint (t, point0, point1, point2); 

    } 
    lineRenderer.SetPositions(positions); 
} 

Vector3 CalculateLinearBeziearPoint (float t, Vector3 p0, Vector3 p1, Vector3 p2) { 

    float u = 1 - t; 
    float tt = t * t; 
    float uu = u * u; 
    Vector3 p = uu * p0 + 2 * u * t * p1 + tt * p2; 

    return p; 
} 

} 

Antwort

2

eine Koroutine Verwendung:

public class BCurve : MonoBehaviour { 

    LineRenderer lineRenderer; 
    public Vector3 point0, point1, point2; 
    int numPoints = 50; 
    Vector3[] positions = new Vector3[50]; 

    // Use this for initialization 
    void Start() { 
     lineRenderer = gameObject.AddComponent<LineRenderer>(); 
     lineRenderer.material = new Material (Shader.Find ("Sprites/Default")); 
     lineRenderer.startColor = lineRenderer.endColor = Color.white; 
     lineRenderer.startWidth = lineRenderer.endWidth = 0.1f; 

     StartCoroutine(DrawQuadraticCurve (3)); 

    } 

    IEnumerator DrawQuadraticCurve (float duration) { 
     //Calculate wait duration for each loop so it match 3 seconds 
     float waitDur = duration/numPoints; 

     for (int i = 1; i < numPoints + 1; i++) { 
      float t = i/(float)numPoints; 
      lineRenderer.positionCount = i; 
      lineRenderer.setPosition(i - 1, CalculateLinearBeziearPoint (t, point0, point1, point2)); 
      yield return new WaitForSeconds(waitDur); 
     } 
    } 

    Vector3 CalculateLinearBeziearPoint (float t, Vector3 p0, Vector3 p1, Vector3 p2) { 

     float u = 1 - t; 
     float tt = t * t; 
     float uu = u * u; 
     Vector3 p = uu * p0 + 2 * u * t * p1 + tt * p2; 

     return p; 
    } 

} 

EDIT: Added eine bestimmte Dauer auf den Anruf.

Hinweis: Wenn duration/numPoints wahrscheinlich auf weniger als Time.deltaTime, können Sie stattdessen diese Methode verwenden möchten, die mehrere Punkte pro Bild zeichnen kann:

IEnumerator DrawQuadraticCurve (float duration) { 
     float progressPerSecond = 1/duration; 
     float startTime = Time.time; 
     float progress = 0; 
     while (progress < 1) { 
      progress = Mathf.clamp01((Time.time - startTime) * progressPerSecond); 
      int prevPointCount = lineRenderer.positionCount; 
      int curPointCount = progress * numPoints; 
      lineRenderer.positionCount = curPointCount; 
      for (int i = prevPointCount; i < curPointCount; ++i) { 
       float t = i/(float)numPoints; 
       lineRenderer.setPosition(i, CalculateLinearBeziearPoint (t, point0, point1, point2)); 
      } 
      yield return null; 
     } 
    } 
+0

Von meinem Verständnis der Frage will Chronos die Bezier-Kurve über bestimmte Dauer zu animieren. – Hilarious404

+0

@ Hilarious404 dann WaitForSeconds Parameter sollte Dauer sein/numPoints – mayo

+0

Wenn nicht weniger als "Time.deltaTime" endet, in welchem ​​Fall mehrere durchläuft die Schleife in einem einzigen Rahmen wäre notwendig. –

0

Dies ist Erweiterung von Ed Marty Antworten. um die Coroutine die Kurve in gegebener Dauer zu erstellen, können Sie es so machen

waitDur = duration/numOfPoints;

public class BCurve : MonoBehaviour { 

    LineRenderer lineRenderer; 
    public Vector3 point0, point1, point2; 
    int numPoints = 50; 
    Vector3[] positions = new Vector3[50]; 

    // Use this for initialization 
    void Start() { 
     lineRenderer = gameObject.AddComponent<LineRenderer>(); 
     lineRenderer.material = new Material (Shader.Find ("Sprites/Default")); 
     lineRenderer.startColor = lineRenderer.endColor = Color.white; 
     lineRenderer.startWidth = lineRenderer.endWidth = 0.1f; 

     StartCoroutine(DrawQuadraticCurve (3)); 
    } 

    IEnumerator DrawQuadraticCurve (float duration) { 
     //Calculate wait duration for each loop so it match 3 seconds 
     float waitDur = duration/numPoints; 

     for (int i = 1; i < numPoints + 1; i++) { 
      float t = i/(float)numPoints; 
      lineRenderer.positionCount = i; 
      lineRenderer.setPosition(i - 1, CalculateLinearBeziearPoint (t, point0, point1, point2)); 
      yield return new WaitForSeconds(waitDur); 
     } 
    } 

    Vector3 CalculateLinearBeziearPoint (float t, Vector3 p0, Vector3 p1, Vector3 p2) { 

     float u = 1 - t; 
     float tt = t * t; 
     float uu = u * u; 
     Vector3 p = uu * p0 + 2 * u * t * p1 + tt * p2; 

     return p; 
    } 

} 
+0

Ich habe Ihre Änderungen in meine Antwort aufgenommen –

+0

Entschuldigung dafür, ich möchte stattdessen einen Kommentar hinzufügen, aber ich kann nicht –

Verwandte Themen