- 需求:我要一条波浪形的路线
- 前言
- 生成二阶曲线
- 生成三阶曲线
- 整理生成正弦函数
最近接到需求想要验证一下在波浪形路线下的效果怎么样,由于是在前人的工程下继续开发,已经定下行走路线的基调是按路劲点行进。我创建一条路线总不可能一个个点摆吧,之前是按mesh点获取路劲,但是这个需要一直返工测试,验证起来还是比较费劲的。
生成二阶曲线
计算方法
///生成三阶曲线///二阶贝塞尔 /// /// /// /// public void CreatTwoBezierCurve(Vector3 startPoint, Vector3 endPoint, Vector3 middlePoint) { allPoints.Clear(); for (int i = 0; i < nultiple; i++) { float tempPercent = (float) i / (float) nultiple; float dis1 = Vector3.Distance(startPoint, middlePoint); Vector3 point1 = startPoint + Vector3.Normalize(middlePoint - startPoint) * dis1 * tempPercent; float dis2 = Vector3.Distance(middlePoint, endPoint); Vector3 point2 = middlePoint + Vector3.Normalize(endPoint - middlePoint) * dis2 * tempPercent; float dis3 = Vector3.Distance(point1, point2); Vector3 linePoint = point1 + Vector3.Normalize(point2 - point1) * dis3 * tempPercent; allPoints.Add(linePoint); } allPoints.Add(endPoint); }
计算方法
///整理生成正弦函数/// 三阶贝塞尔 /// /// /// /// public void CreatThreeBezierCurve(Vector3 startPoint, Vector3 endPoint, Vector3 middlePoint1, Vector3 middlePoint2) { allPoints.Clear(); for (int i = 0; i < nultiple; i++) { float tempPercent = (float) i / (float) nultiple; float dis1 = Vector3.Distance(startPoint, middlePoint1); Vector3 pointL1 = startPoint + Vector3.Normalize(middlePoint1 - startPoint) * dis1 * tempPercent; float dis2 = Vector3.Distance(middlePoint1, middlePoint2); Vector3 pointL2 = middlePoint1 + Vector3.Normalize(middlePoint2 - middlePoint1) * dis2 * tempPercent; float dis3 = Vector3.Distance(pointL1, pointL2); Vector3 pointLeft = pointL1 + Vector3.Normalize(pointL2 - pointL1) * dis3 * tempPercent; float dis4 = Vector3.Distance(middlePoint2, endPoint); Vector3 pointR1 = middlePoint2 + Vector3.Normalize(endPoint - middlePoint2) * dis4 * tempPercent; float dis5 = Vector3.Distance(pointL2, pointR1); Vector3 pointRight = pointL2 + Vector3.Normalize(pointR1 - pointL2) * dis5 * tempPercent; float disLeftAndRight = Vector3.Distance(pointLeft, pointRight); Vector3 linePoint = pointLeft + Vector3.Normalize(pointRight - pointLeft) * disLeftAndRight * tempPercent; allPoints.Add(linePoint); } allPoints.Add(endPoint); }
完成代码
using System.Collections.Generic;
using UnityEngine;
namespace BowenkLib
{
public class BownekBezierTest : MonoBehaviour
{
///
/// 曲线圆滑度
///
[Range(5, 50)]public int nultiple = 5;
///
/// 波长 但是这里直接换成一个正弦的长度
///
[Range(2, 30)] public float WaveLength = 6;
///
/// 波峰高度控制
///
[Range(1, 50)] public int Height = 1;
///
/// 周期控制
///
[Range(1, 20)] public int Cyclic = 1;
public List allPoints = new List();
public Transform Start;
public Transform End;
public Transform Contrl1;
public Transform Contrl2;
private void OnDrawGizmos()
{
CreatPath();
}
///
/// 创建正弦路劲
///
private void CreatPath()
{
if(Start == null) return;
allPoints.Clear();
var nextPoint = Start.position;
for (var i = 0; i < Cyclic; i++)
{
nextPoint = OnePointDraw(nextPoint, WaveLength, Height);
}
}
///
/// 生成正弦波浪 x轴方向
///
/// 起点
/// 波长
private Vector3 OnePointDraw(Vector3 startPoint, float waveLength, float height)
{
var endPoint = startPoint + new Vector3(waveLength, 0, 0);
var mPoint1 = startPoint + new Vector3(waveLength / 3, height, 0);
var mPoint2 = startPoint + new Vector3((waveLength / 3) * 2, -height, 0);
var path = GetBezierCurve(startPoint, endPoint, mPoint1, mPoint2, nultiple);
for (var i = 1; i < path.Count; i++)
{
Debug.DrawLine(path[i-1], path[i], Color.yellow);
}
allPoints.AddRange(path);
return endPoint;
}
///
/// 画出二阶曲线
///
private void TwoDraw()
{
CreatTwoBezierCurve(Start.position, End.position, Contrl1.position);
for (int i = 1; i < allPoints.Count; i++)
{
Debug.DrawLine(allPoints[i - 1], allPoints[i], Color.blue);
}
}
///
/// 画出三阶曲线
///
private void ThreeDraw()
{
if (Start == null || End == null || Contrl1 == null || Contrl2 == null)
return;
CreatThreeBezierCurve(Start.position, End.position, Contrl1.position, Contrl2.position);
for (int i = 1; i < allPoints.Count; i++)
{
Debug.DrawLine(allPoints[i - 1], allPoints[i], Color.blue);
}
}
///
///二阶贝塞尔
///
public void CreatTwoBezierCurve(Vector3 startPoint, Vector3 endPoint, Vector3 middlePoint)
{
allPoints.Clear();
for (int i = 0; i < nultiple; i++)
{
float tempPercent = (float) i / (float) nultiple;
float dis1 = Vector3.Distance(startPoint, middlePoint);
Vector3 point1 = startPoint + Vector3.Normalize(middlePoint - startPoint) * dis1 * tempPercent;
float dis2 = Vector3.Distance(middlePoint, endPoint);
Vector3 point2 = middlePoint + Vector3.Normalize(endPoint - middlePoint) * dis2 * tempPercent;
float dis3 = Vector3.Distance(point1, point2);
Vector3 linePoint = point1 + Vector3.Normalize(point2 - point1) * dis3 * tempPercent;
allPoints.Add(linePoint);
}
allPoints.Add(endPoint);
}
///
/// 三阶贝塞尔
///
public void CreatThreeBezierCurve(Vector3 startPoint, Vector3 endPoint, Vector3 middlePoint1,
Vector3 middlePoint2)
{
allPoints.Clear();
for (int i = 0; i < nultiple; i++)
{
float tempPercent = (float) i / (float) nultiple;
float dis1 = Vector3.Distance(startPoint, middlePoint1);
Vector3 pointL1 = startPoint + Vector3.Normalize(middlePoint1 - startPoint) * dis1 * tempPercent;
float dis2 = Vector3.Distance(middlePoint1, middlePoint2);
Vector3 pointL2 = middlePoint1 + Vector3.Normalize(middlePoint2 - middlePoint1) * dis2 * tempPercent;
float dis3 = Vector3.Distance(pointL1, pointL2);
Vector3 pointLeft = pointL1 + Vector3.Normalize(pointL2 - pointL1) * dis3 * tempPercent;
float dis4 = Vector3.Distance(middlePoint2, endPoint);
Vector3 pointR1 = middlePoint2 + Vector3.Normalize(endPoint - middlePoint2) * dis4 * tempPercent;
float dis5 = Vector3.Distance(pointL2, pointR1);
Vector3 pointRight = pointL2 + Vector3.Normalize(pointR1 - pointL2) * dis5 * tempPercent;
float disLeftAndRight = Vector3.Distance(pointLeft, pointRight);
Vector3 linePoint =
pointLeft + Vector3.Normalize(pointRight - pointLeft) * disLeftAndRight * tempPercent;
allPoints.Add(linePoint);
}
allPoints.Add(endPoint);
}
///
/// 获取两点 之间的正弦点
///
/// 起点
/// 终点
/// 波峰1
/// 波峰2
/// 点数(控制圆滑度)
public List GetBezierCurve(Vector3 startPoint, Vector3 endPoint, Vector3 mPoint1, Vector3 mPoint2, int smooth)
{
List temp = new List();
for (int i = 0; i < smooth; i++)
{
float tempPercent = (float) i / (float) smooth;
float dis1 = Vector3.Distance(startPoint, mPoint1);
Vector3 pointL1 = startPoint + Vector3.Normalize(mPoint1 - startPoint) * dis1 * tempPercent;
float dis2 = Vector3.Distance(mPoint1, mPoint2);
Vector3 pointL2 = mPoint1 + Vector3.Normalize(mPoint2 - mPoint1) * dis2 * tempPercent;
float dis3 = Vector3.Distance(pointL1, pointL2);
Vector3 pointLeft = pointL1 + Vector3.Normalize(pointL2 - pointL1) * dis3 * tempPercent;
float dis4 = Vector3.Distance(mPoint2, endPoint);
Vector3 pointR1 = mPoint2 + Vector3.Normalize(endPoint - mPoint2) * dis4 * tempPercent;
float dis5 = Vector3.Distance(pointL2, pointR1);
Vector3 pointRight = pointL2 + Vector3.Normalize(pointR1 - pointL2) * dis5 * tempPercent;
float disLeftAndRight = Vector3.Distance(pointLeft, pointRight);
Vector3 linePoint =
pointLeft + Vector3.Normalize(pointRight - pointLeft) * disLeftAndRight * tempPercent;
temp.Add(linePoint);
}
temp.Add(endPoint);
return temp;
}
}
}
这时候就可以直接在 Inspector面板直接控制你想要的波浪线了



