逻辑直线运动的曲线表现模拟2--基于控制点(基函数)的随机曲线
需求
设计师希望可以完全自定义地描述某些投射物的弹道曲线。该曲线需要支持跟踪和确定目标点。
实现
B样条
本曲线使用的基本理论是B样条,B样条是受多个控制点约束而绘制出的样条曲线。它相对于类似原理的贝赛尔曲线具有更好的局部性性质,用户调整其中部分控制点时曲线整体不会受到影响。
△ 表现上可以近似地理解为抛射物被控制点吸引地向正方向移动。
本实现中生成的B样条是一组曲线上的有序顶点。
B样条的数学推导相对复杂,本文档不会包含相关内容。但是可以参考下方链接:
https://www.qiujiawei.com/b-spline-1/
运动过程
每一帧都更新目标位置targetPos
、逻辑直线运动总时间directFullTime
、抛射物当前运动时间curLifeTime
,计算过程中速度和加速度都参与计算。
1 | private void UpdateDirectInfo() { |
每一帧上,直线上运动进度百分比为
directRate = curLifeTime / directFullTime
,因为曲线运动和直线运动抵达终点的时刻应相同,所以曲线上的运动进度百分比也应该等于directRate
。若抵达最后顶点,说明抛射物已抵达终点,直接设置抛射物位置;若尚未抵达,则使用当前时间比例计算当帧的曲线位置。
if (directRate >= 1) { // 直接定位到最终位置 RefreshTransform(this.targetPos); } else { Vector3 pos = bSpline.CreateBSpline(directRate); RefreshTransform(pos); }
曲线控制点的运行时定位方式
(咕)
跟踪情形
当抛射物目标点动态变化时,原有曲线将无法准确命中目标。因此在每一帧Tick时,需要更新曲线的最后一个顶点和曲线全长,以保证终点无误。
这会产生的问题是,抛射物运动轨迹的最后一部分将会是一条斜率可能发生突变的线段,但在绝大多数帧相关的情形中难以察觉。
为什么不实时生成新的曲线,然后重新对抛射物做当帧定位?
生成曲线的计算量不低,高频率的曲线生成会产生性能问题。基于确定曲线的运动模拟不是一个增量过程,当目标点发生较大变化时,曲线也会剧烈变化,定位平滑效果较差的问题无法避免,这在复杂曲线上的表现更明显。
22.12.24更新
新做法,重新调整了样条生成方式,支持了直接计算b样条在某个直线比例上的曲线坐标Bspline.CreateCurvePointByDirectRate(float rate)
,以此去除了动态目标情况的无效计算消耗。
B样条优秀的局部采样性质使得曲线顶点的计算与控制点数量无关,相比于贝塞尔曲线,在大量曲线同时进行计算的情形下效率优化明显。