using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BF
{
public class DrawBezierLine : MonoBehaviour
{
public LineRenderer lineRender;
private Vector3 _startPoint = Vector3.zero;
private Vector3 _endPoint = Vector3.zero;
private Vector3 _controlPoint1 = Vector3.zero;
private Vector3 _controlPoint2 = Vector3.zero;
// 曲线上的路径点数量,值越大,取得的路径点越多,曲线越平滑
private int drawPointCount = 30;
private bool isDraw = false;
private bool useCubicBezier = true;
public void SetStartPoint(float x, float y, float z)
{
_startPoint = new Vector3(x, y, z);
}
public void SetEndPoint(float x, float y, float z)
{
_endPoint = new Vector3(x, y, z);
}
public void SetControlPoint1(float x, float y, float z)
{
_controlPoint1 = new Vector3(x, y, z);
}
public void SetControlPoint2(float x, float y, float z)
{
_controlPoint2 = new Vector3(x, y, z);
}
public void SetDrawPointCount(int count)
{
drawPointCount = count;
}
public void DrawLine()
{
isDraw = true;
}
public void ClearLine()
{
isDraw = false;
lineRender.positionCount = 0;
}
public Vector3[] GetPathList()
{
Vector3[] positions = new Vector3[lineRender.positionCount];
lineRender.GetPositions(positions);
return positions;
}
public void SetUseCubicBezier(bool use)
{
useCubicBezier = use;
}
void Update()
{
if (!isDraw)
{
return;
}
isDraw = false;
if (drawPointCount <= 0)
{
return;
}
lineRender.positionCount = drawPointCount;
lineRender.SetPosition(0, _startPoint);
for (int i = 1; i < drawPointCount; i++)
{
var t = (i + 1) / (float)drawPointCount;
if (useCubicBezier)
{
var pathPoint = GetPointInCubicBezierCurve(t, _startPoint, _controlPoint1, _controlPoint2, _endPoint);//使用贝塞尔曲线的公式取得t时的路径点
lineRender.SetPosition(i, pathPoint);
}
else
{
var pathPoint = GetBezierPoint(t, _startPoint, _controlPoint1, _endPoint);//使用贝塞尔曲线的公式取得t时的路径点
lineRender.SetPosition(i, pathPoint);
}
}
}
/// 0到1的值,0获取曲线的起点,1获得曲线的终点
/// 曲线的起始位置
/// 决定曲线形状的控制点
/// 曲线的终点
public static Vector3 GetBezierPoint(float t, Vector3 start, Vector3 controlPoint, Vector3 end)
{
return (1 - t) * (1 - t) * start + 2 * t * (1 - t) * controlPoint + t * t * end;
}
public Vector3 GetPointInCubicBezierCurve(float t, Vector3 startPoint, Vector3 controlPoint1, Vector3 controlPoint2, Vector3 endPoint)
{
var A = startPoint * (Mathf.Pow(-t, 3) + 3 * Mathf.Pow(t, 2) - 3 * t + 1);
var B = controlPoint1 * (3 * Mathf.Pow(t, 3) - 6 * Mathf.Pow(t, 2) + 3 * t);
var C = controlPoint2 * (-3 * Mathf.Pow(t, 3) + 3 * Mathf.Pow(t, 2));
var D = endPoint * (Mathf.Pow(t, 3));
return A + B + C + D;
}
}
}