[System.Serializable]
//贝塞尔曲线类
public class Bezier : System.Object
{
public Vector3 Point0;
public Vector3 Point1;
public Vector3 Point2;
public Vector3 Point3;
private Vector3 comparisonPoint0 = Vector3.zero;
private Vector3 comparisonPoint1 = Vector3.zero;
private Vector3 comparisonPoint2 = Vector3.zero;
private Vector3 comparisonPoint3 = Vector3.zero;
private float Ax;
private float Ay;
private float Az;
private float Bx;
private float By;
private float Bz;
private float Cx;
private float Cy;
private float Cz;
//得到四个点的坐标,起始点,中间两个点和末尾的点
public void SetPoint( Vector3 point0, Vector3 point1, Vector3 point2, Vector3 point3 )
{
this.Point0 = point0;
this.Point1 = point1;
this.Point2 = point2;
this.Point3 = point3;
}
// 0.0 <= t <= 1.0
//确定对应点的坐标
public Vector3 GetOnPathPoint( float t )
{
this.CheckPointChange();
float t2 = t * t;
float t3 = t * t * t;
float x = this.Ax * t3 + this.Bx * t2 + this.Cx * t + Point0.x;
float y = this.Ay * t3 + this.By * t2 + this.Cy * t + Point0.y;
float z = this.Az * t3 + this.Bz * t2 + this.Cz * t + Point0.z;
return new Vector3( x, y, z );
}
//对系数赋值
private void SetCoefficient()
{
this.Cx = 3f * ( this.Point1.x - this.Point0.x );
this.Bx = 3f * ( this.Point2.x - this.Point1.x ) - this.Cx;
this.Ax = this.Point3.x - this.Point0.x - this.Cx - this.Bx;
this.Cy = 3f * ( this.Point1.y - this.Point0.y );
this.By = 3f * ( this.Point2.y - this.Point1.y ) - this.Cy;
this.Ay = this.Point3.y - this.Point0.y - this.Cy - this.By;
this.Cz = 3f * ( this.Point1.z - this.Point0.z );
this.Bz = 3f * ( this.Point2.z - this.Point1.z ) - this.Cz;
this.Az = this.Point3.z - this.Point0.z - this.Cz - this.Bz;
}
// Check if p0, p1, p2 or p3 have changed
private void CheckPointChange()
{
if( this.Point0 != this.comparisonPoint0 || this.Point1 != this.comparisonPoint1 || this.Point2 != this.comparisonPoint2 || this.Point3 != this.comparisonPoint3 )
{
this.SetCoefficient();
this.comparisonPoint0 = this.Point0;
this.comparisonPoint1 = this.Point1;
this.comparisonPoint2 = this.Point2;
this.comparisonPoint3 = this.Point3;
}
}
}
//调用的类
using UnityEngine;
public class MyBezier : MonoBehaviour
{
public Transform Head;
public Transform End;
private Vector3 point0;
public Vector3 point1;
public Vector3 point2;
private Vector3 point3;
//贝塞尔曲线算法类
private Bezier bezier;
//曲线的对象
// public GameObject BezierLine;
//曲线对象的曲线组件
public LineRenderer BezierLineRenderer;
void Awake(){
//为了让曲线更加美观,设置曲线由100个点来组成
BezierLineRenderer.SetVertexCount(100);
bezier = new Bezier( );
}
void Start()
{
drawLine();
}
void Update()
{
//当起始点或者末尾点的坐标改变时重新绘制线
if (point0 !=Head.position||point3 !=End.position) {
setPoint();
drawLine();
}
}
//对中间的点赋值
private void setPoint(){
point1 =Vector3.Lerp(point1,(Head.position + End.position) * 0.5f,0.1f);
point2 = point1;
}
//绘制线
private void drawLine(){
point0 =Head.position;
point3 =End.position;
bezier.SetPoint(point0,point1,point2,point3);
//循环100遍来绘制贝塞尔曲线每个线段
for(int i =0; i < 100; i++)
{
//参数的取值范围 0 - 1 返回曲线每一点的位置
//为了精确这里使用i * 0.01 得到当前点的坐标
Vector3 v = bezier.GetOnPathPoint( (float)(i *0.01) );
//把每条线段绘制出来 完成贝塞尔曲线的绘制
BezierLineRenderer.SetPosition(i,v);
}
}
}