沿地形表面的贝塞尔曲线

Bezier along Terrain Surface

最好的方法是什么,如果我为 Unity Terrain 绘制贝塞尔曲线(设置起点和终点),并且我希望曲线跟随地面的起伏。

现在我部分是这样实现的,(需要从groundedPoints连接新的Points,作为新的Beziers)

int SegmentCount = Mathf.Floor(BezierLength / SegmentLength);
//Rounded to the next lower integer
var groundedPoints = new List<Vector3>();

for(int i =0; i<SegmentCount;i++){
  Vector3 p = GetPoint(BezierPoints,i / SegmentCount);
    p = p.RayCastDown();
    //RayCasting Down to get the Point on the Terrain
  if(i == 0 || i < SegmentCount -1){
    groundedPoints.Add(p);
  }else{
    if(p.y != groundedPoints[groundedPoints.Count-1].y){
      groundedPoints.Add(p);
      }
   }
}

它现在有点不准确,但它不一定是真正准确的解决方案。

也许有人可以给我提示?谢谢

首先我会推荐使用 Centripetal Catmull–Rom spline 因为它更严格地遵循点,并且需要更少的点来生成(也只在 p1 和 p2 之间绘制),但我不知道你想要实现什么所以:

我会将你的贝塞尔曲线转换成二维贝塞尔曲线,并且只在二维 space 中使用它,然后当你绘制(视觉渲染)时,你通过使用 https://docs.unity3d.com/ScriptReference/Terrain.SampleHeight.html 给它一个 Y 值

我用我的样条线做这个,它最终给出了一个非常准确的样条线(道路生成)

请注意!: 隐式 Vector2 和 Vector3 转换不符合您的需要,您需要添加一个扩展方法来将 Vector3 转换为 Vector2 :) (Vector(x,y,z) 将是 Vector(x,y) 但您需要 Vector(x,z))

编辑 1:

代码示例如何通过 Terrain.SampleHeight(); 通过 Vector2 坐标读取地形实际高度,如果 Vector2 不在地形上方它会给你返回 null 或壁橱地形高度,我不确定是哪一个 atm(现在无法测试):)

public static float GetPoint_On_Terrain(Vector2 point){
    float terrainHeightAtPoint = Terrain.activeTerrain.SampleHeight(new Vector3(point.x, 0, point.y));
    return new Vector3(point.x, terrainHeightAtPoint,point.y);
}