2025-11-03 10:59:33 +08:00

113 lines
3.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}
/// <param name="t">0到1的值0获取曲线的起点1获得曲线的终点</param>
/// <param name="start">曲线的起始位置</param>
/// <param name="center">决定曲线形状的控制点</param>
/// <param name="end">曲线的终点</param>
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;
}
}
}