我通过将以下脚本添加到检查器中的空游戏对象来创建贝塞尔曲线。当我运行代码时,这将立即绘制完成曲线。如何在给定的时间段内为其设置动画,例如2或3秒?
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;
}
}
答案 0 :(得分:4)
使用协程:
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;
}
}
编辑:为通话添加了特定的持续时间。
注意:如果duration / numPoints
可能小于Time.deltaTime
,您可能需要使用此方法,每帧可以绘制多个点:
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;
}
}
答案 1 :(得分:0)
这是Ed Marty Answers的增强版。 为了使协同程序在给定的持续时间内构建曲线,你可以这样做
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;
}
}