2017-11-12 24 views
6

Tôi đã tạo ra một đường cong bezier bằng cách thêm đoạn mã sau vào một đối tượng trò chơi trống trong thanh tra. Điều này rút ra để hoàn thành đường cong cùng một lúc khi tôi chạy mã. Làm thế nào tôi có thể tạo hiệu ứng động trong một khoảng thời gian nhất định, nói 2 hoặc 3 giây?Làm thế nào để animate một đường cong bezier trong một thời hạn nhất định

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

} 

Trả lời

2

Sử dụng một coroutine:

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: gia tăng một khoảng thời gian cụ thể cho các cuộc gọi.

Lưu ý: Nếu duration/numPoints có khả năng là ít hơn Time.deltaTime, bạn có thể muốn sử dụng phương pháp này để thay thế, có thể rút ra nhiều điểm cho mỗi khung:

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

Từ hiểu biết của tôi về câu hỏi, chronos muốn tạo ảnh động đường cong bezier trong khoảng thời gian cụ thể. – Hilarious404

+0

@ Hilarious404 sau đó tham số WaitForSeconds phải là duration/numPoints – mayo

+0

Trừ khi kết thúc sẽ nhỏ hơn 'Time.deltaTime', trong trường hợp đó nhiều lần chạy qua vòng lặp trong một khung đơn sẽ là cần thiết. –

0

Đây là tăng cường Ed Marty Đáp. để làm cho coroutine xây dựng đường cong trong thời gian nhất định, bạn có thể làm như thế này

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

Tôi đã kết hợp các thay đổi của bạn vào câu trả lời –

+0

xin lỗi vì đã làm, tôi muốn thêm nhận xét thay vào đó, nhưng tôi không thể –

Các vấn đề liên quan