如题,有三个点的曲线(开始点,中间点,结束点)
5个点:(开始点,结束点,三个中间点)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BezierCurve : MonoBehaviour
{
public Transform _startTra;//起始点
public Transform _centerTra;//中间点(随意即可)
public Transform _endTra;//终结点
//编辑器画线
void OnDrawGizmos()
{
List
m_pathPointList.AddRange(GetPathPoints(_startTra.position, _endTra.position, _centerTra.position, 20));
Gizmos.color = Color.yellow;
for (int i = 0; i < m_pathPointList.Count - 1; i++)
{
Gizmos.DrawLine(m_pathPointList[i], m_pathPointList[i + 1]);
}
}
//一个额外点的贝萨尔曲线(即抛物线)
public static Vector3[] GetPathPoints(Vector3 startPos, Vector3 endPos, Vector3 centerPos, int needPointNumber = 20)
{
//为了节省性能
//将其转化成;一个float,可以进行差值运算,否则结果为0
float number = (float)needPointNumber;
//定义一个数组,用来存放路径点,他的长度是从0 - needPointNumber的长度,及从0-1
Vector3[] targetPosArr = new Vector3[needPointNumber + 1];
//只有在等于needPointNumber时Lerp()中最后一项的值才为1,所有比needPointNumber数多1
for (int i = 0; i <= needPointNumber; i++)
{
//第一层
Vector3 one1 = Vector3.Lerp(startPos, centerPos, i / number);
Vector3 one2 = Vector3.Lerp(centerPos, endPos, i / number);
//目标层
Vector3 targetPos = Vector3.Lerp(one1, one2, i / number);
//将目标层放入我们的路径点中
targetPosArr[i] = targetPos;
}
//在for循环结束之后得到所有的路径点
return targetPosArr;
}
///
/// 将目标物体从开始点移动到目标点通过平滑的曲线
///
/// 你要移动的目标物体
/// 目标物体的开始点
/// 目标物体的结束点
/// 三个中间点
/// 你最终得到的路径点的中间数,默认是20,数量越大曲线越平滑,越小越线性
///
public static Vector3[] GetPathPoints(Transform start, Transform end, Transform[] threeCenterPosArr, int needPointNumber = 20)
{
//为了节省性能
//将其转化成;一个float,可以进行差值运算,否则结果为0
float number = (float)needPointNumber;
//定义一个数组,用来存放路径点,他的长度是从0 - needPointNumber的长度,及从0-1
Vector3[] targetPosArr = new Vector3[needPointNumber + 1];
//只有在等于needPointNumber时Lerp()中最后一项的值才为1,所有比needPointNumber数多1
for (int i = 0; i <= needPointNumber; i++)
{
//第一层
Vector3 one1 = Vector3.Lerp(start.position, threeCenterPosArr[0].position, i / number);
Vector3 one2 = Vector3.Lerp(threeCenterPosArr[0].position, threeCenterPosArr[1].position, i / number);
Vector3 one3 = Vector3.Lerp(threeCenterPosArr[1].position, threeCenterPosArr[2].position, i / number);
Vector3 one4 = Vector3.Lerp(threeCenterPosArr[2].position, end.position, i / number);
//第二层
Vector3 two1 = Vector3.Lerp(one1, one2, i / number);
Vector3 two2 = Vector3.Lerp(one2, one3, i / number);
Vector3 two3 = Vector3.Lerp(one3, one4, i / number);
//第三层
Vector3 three1 = Vector3.Lerp(two1, two2, i / number);
Vector3 three2 = Vector3.Lerp(two2, two3, i / number);
//目标层
Vector3 targetPos = Vector3.Lerp(three1, three2, i / number);
//将目标层放入我们的路径点中
targetPosArr[i] = targetPos;
}
//在for循环结束之后得到所有的路径点
return targetPosArr;
}
//额外的重载方法,就不仔细介绍了
public static Vector3[] GetPathPoints(Vector3 startPos, Vector3 endPos, Vector3[] threeCenterPosArr, int needPointNumber = 20)
{
float number = (float)needPointNumber;
Vector3[] targetPosArr = new Vector3[needPointNumber + 1];
for (int i = 0; i <= number; i++)
{
//第一层
Vector3 one1 = Vector3.Lerp(startPos, threeCenterPosArr[0], i / number);
Vector3 one2 = Vector3.Lerp(threeCenterPosArr[0], threeCenterPosArr[1], i / number);
Vector3 one3 = Vector3.Lerp(threeCenterPosArr[1], threeCenterPosArr[2], i / number);
Vector3 one4 = Vector3.Lerp(threeCenterPosArr[2], endPos, i / number);
//第二层
Vector3 two1 = Vector3.Lerp(one1, one2, i / number);
Vector3 two2 = Vector3.Lerp(one2, one3, i / number);
Vector3 two3 = Vector3.Lerp(one3, one4, i / number);
//第三层
Vector3 three1 = Vector3.Lerp(two1, two2, i / number);
Vector3 three2 = Vector3.Lerp(two2, two3, i / number);
//目标层
Vector3 targetPos = Vector3.Lerp(three1, three2, i / number);
//将目标层放入我们的路径点中
targetPosArr[i] = targetPos;
}
return targetPosArr;
}
}