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