又到了开学的时候了~ 开学第一课 使用贝塞尔曲线绘制路径并移动 吼吼
这部分是摘录
Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierre Bézier第一个研究了这种绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。
以下公式中:B(t)为t时间下 点的坐标;
P0为起点,Pn为终点,Pi为控制点
一阶贝塞尔曲线(线段):
意义:由 P0 至 P1 的连续点, 描述的一条线段
二阶贝塞尔曲线(抛物线):
原理:由 P0 至 P1 的连续点 Q0,描述一条线段。
由 P1 至 P2 的连续点 Q1,描述一条线段。 由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。经验:P1-P0为曲线在P0处的切线。
三阶贝塞尔曲线:
通用公式:
高阶贝塞尔曲线:
4阶曲线:
5阶曲线:
下面是试用贝塞尔曲线来设置路径 然后使自身按照曲线移动,代码来源 A Pathfinding Project 插件Demo ,写的不错 先收藏了,比较重要的是Plot函数用来计算曲线
using UnityEngine;using System.Collections;using Pathfinding;public class BezierMover : MonoBehaviour { public Transform[] points; public float tangentLengths = 5; public float speed = 1; float time = 0; void Update ( ) { Move ( true ); } Vector3 Plot (float t) { Vector3 inTang, outTang; int c = points.Length; int pt = Mathf.FloorToInt(t); inTang = ( (points[(pt+1)%c].position - points[(pt+0)%c].position).normalized - (points[(pt-1+c)%c].position - points[(pt+0)%c].position).normalized ).normalized; outTang = ( (points[(pt+2)%c].position - points[(pt+1)%c].position).normalized - (points[(pt-0+c)%c].position - points[(pt+1)%c].position).normalized ).normalized; Debug.DrawLine ( points[pt%c].position, points[pt%c].position + inTang*tangentLengths, Color.red); Debug.DrawLine ( points[(pt+1)%c].position - outTang*tangentLengths, points[(pt+1)%c].position, Color.green); return AstarMath.CubicBezier ( points[pt%c].position, points[pt%c].position + inTang*tangentLengths, points[(pt+1)%c].position - outTang*tangentLengths, points[(pt+1)%c].position, t - pt); } // Update is called once per frame void Move ( bool progress ) { /*if ( time > pt+1 ) { Move ( false ); return; }*/ float mn = time; float mx = time+1; while ( mx - mn > 0.0001f ) { float mid = (mn+mx)/2; Vector3 p = Plot ( mid ); if ( (p-transform.position).sqrMagnitude > (speed*Time.deltaTime)*(speed*Time.deltaTime) ) { mx = mid; } else { mn = mid; } } time = (mn+mx)/2; /*Vector3 p1 = AstarMath.CubicBezier ( points[pt%c].position, points[pt%c].position + inTang*tangentLengths, points[(pt+1)%c].position - outTang*tangentLengths, points[(pt+1)%c].position, time - pt); Vector3 p2 = AstarMath.CubicBezier ( points[pt%c].position, points[pt%c].position + inTang*tangentLengths, points[(pt+1)%c].position - outTang*tangentLengths, points[(pt+1)%c].position, time - pt + 0.001f);*/ Vector3 p1 = Plot(time); Vector3 p2 = Plot(time+0.001f); transform.position = p1; transform.rotation = Quaternion.LookRotation ( p2 - p1 ); } public void OnDrawGizmos () { if ( points.Length >= 3 ) { for ( int i = 0; i < points.Length; i++ ) if ( points[i] == null ) return; for ( int pt = 0; pt < points.Length; pt++ ) { int c = points.Length; Vector3 inTang = ( (points[(pt+1)%c].position - points[pt+0].position).normalized - (points[(pt-1+c)%c].position - points[pt+0].position).normalized ).normalized; Vector3 outTang = ( (points[(pt+2)%c].position - points[(pt+1)%c].position).normalized - (points[(pt-0+c)%c].position - points[(pt+1)%c].position).normalized ).normalized; Vector3 pp = points[pt].position; for ( int i=1;i<=100;i++) { Vector3 p = AstarMath.CubicBezier ( points[pt].position, points[pt].position + inTang*tangentLengths, points[(pt+1)%c].position - outTang*tangentLengths, points[(pt+1)%c].position, i / 100.0f ); Gizmos.DrawLine ( pp, p ); pp = p; } } } }}