如何将游戏抛射体3D曲线沿XY轴起点到终点方向旋转适配至XY平面
实现方案
核心思路
你原来的曲线逻辑本质是「沿传播方向移动的同时,在垂直于传播方向的轴做余弦波动」,原来的传播方向是世界Z轴,波动也在Z轴方向。现在要实现需求只需要做两步坐标空间转换:
- 预计算XY平面内起点到终点的传播方向单位向量,以及该方向在XY平面内的垂直单位向量
- 完全保留原有参数计算逻辑,把原Z轴的波动值映射到上述垂直向量方向叠加到线段基础坐标上,最终Z轴固定为0即可保证曲线完全落在XY平面
具体实现步骤
1. 预计算方向向量
// 取线段起止点 Vector2 start = new Vector2(LinePoints[0].x, LinePoints[0].y); Vector2 end = new Vector2(LinePoints[LinePoints.Length - 1].x, LinePoints[LinePoints.Length - 1].y); Vector2 dir = end - start; // 兼容起止点重合的极端情况 if (dir.magnitude < 0.001f) { dir = new Vector2(1, 0); } dir.Normalize(); // 计算XY平面内垂直于传播方向的单位向量(如需反向波动把x/y取反即可) Vector2 perpDir = new Vector2(-dir.y, dir.x);
2. 新坐标计算逻辑(完全保留原函数参数逻辑)
// 完全复用原逻辑计算波动值 float waveOffset = t == 1 ? 0.35f : math.cos(scaleFactor * (t * 0.1f)) * (t * 0.5f); // 取线段上的基础点 Vector2 basePoint = new Vector2(LinePoints[t-1].x, LinePoints[t-1].y); // 处理原xOffset/yOffset(如果原偏移是世界坐标下的偏移,做投影转换保证逻辑完全一致) Vector2 originalOffset = new Vector2(xOffset, yOffset); float parallelOffset = Vector2.Dot(originalOffset, dir); // 沿传播方向的偏移 float perpOffset = Vector2.Dot(originalOffset, perpDir) + waveOffset; // 垂直方向总偏移 = 原垂直偏移 + 波动偏移 // 合成最终XY坐标 float finalX = basePoint.x + dir.x * parallelOffset + perpDir.x * perpOffset; float finalY = basePoint.y + dir.y * parallelOffset + perpDir.y * perpOffset; // 固定Z为0保证曲线完全落在XY平面 float finalZ = 0f;
可选简化
如果你的xOffset和yOffset本身就是垂直于原Z轴的偏移,不需要保留世界坐标方向,直接合并到垂直偏移即可:
float totalPerpOffset = xOffset + yOffset + waveOffset; float finalX = basePoint.x + perpDir.x * totalPerpOffset; float finalY = basePoint.y + perpDir.y * totalPerpOffset; float finalZ = 0f;
内容的提问来源于stack exchange,提问作者michael-martinez
相关产品推荐
相关产品推荐

