地形オブジェクトを作成してテクスチャでペイントするスクリプトを入手しましたが、問題があります。ゲームオブジェクト(Unityが提供する単純な水オブジェクトなど)を配置しようとするときは、レイキャストを使用してゲームオブジェクトを配置するための正しい高さを決定しますが、これにより、オブジェクトが特定のポイントに正しく配置されるようになります。
ゲームオブジェクトの下の地形を平坦化して、地形に進入したり、丘の場合は薄い空気にぶら下がったりしないようにするにはどうすればよいですか?
地形オブジェクトを作成してテクスチャでペイントするスクリプトを入手しましたが、問題があります。ゲームオブジェクト(Unityが提供する単純な水オブジェクトなど)を配置しようとするときは、レイキャストを使用してゲームオブジェクトを配置するための正しい高さを決定しますが、これにより、オブジェクトが特定のポイントに正しく配置されるようになります。
ゲームオブジェクトの下の地形を平坦化して、地形に進入したり、丘の場合は薄い空気にぶら下がったりしないようにするにはどうすればよいですか?
回答:
コメントで述べたように、ゲームオブジェクトの下の三角形を構成するすべての頂点を見つけて、それらのy値を同じ値に設定する必要があります。
コメントをさらに詳細な手順で展開します。私はUnityに慣れていないので、この仕事に使用するのに最適なツールはわかりませんが、正しい道に進むことができると信じています。
ブルートフォース法:
何かに当たる光線ごとに、次のように地形メッシュの三角形を取得できます。
RaycastHit hit;
if (!Physics.Raycast(camera.ScreenPointToRay(Input.mousePosition), out hit))
return;
MeshCollider meshCollider = hit.collider as MeshCollider;
if (meshCollider == null || meshCollider.sharedMesh == null)
return;
Mesh mesh = meshCollider.sharedMesh;
Vector3[] vertices = mesh.vertices;
int[] triangles = mesh.triangles;
Vector3 p0 = vertices[triangles[hit.triangleIndex * 3 + 0]];
Vector3 p1 = vertices[triangles[hit.triangleIndex * 3 + 1]];
Vector3 p2 = vertices[triangles[hit.triangleIndex * 3 + 2]];
p0、p1、p2はすべて、ヒットした三角形を構成する3つの頂点の位置です。これらの各頂点の位置を同じy
値に調整します。すべての頂点を収集してから、それらすべてを平均y
値に設定するかy
、ゲームオブジェクトを配置するときに見つけた最初の選択値を使用できます。
最適化:
光線のグリッドをキャストするだけでなく、ゲームオブジェクトからコライダーを下にスイープして、ゲームオブジェクトのコライダーと地形衝突メッシュ間の衝突の接触点を収集できます。次に、これらの各接触点について、移動する頂点を取得するための上記の手順を実行します。
各頂点x
とz
値がグリッドに揃えられ、y
値のみが変化するように地形を作成します。これで、ゲームオブジェクトの境界を簡単に取得し、それらの境界内の頂点のすべてのy値を変更できます。
この最後の最適化は、実際には代替の方法であり、実装が簡単で、かなり効果的です。
通常、オブジェクトの下の地面を平らにし、そのすぐ近くの地面を滑らかにします。
土地がグリッドから作られ、建物が軸合わせされている場合、これははるかに簡単です。
一般的なケースでは、建物が置かれている三角形を細分割し、建物が置かれている三角形のすべての頂点のyを同じyに設定し、特定の距離内にあるすべての頂点に対して中点変位スムージングを行います。建物の下にはありません。
このアプローチを使用して、道路を3D地形に配置しました。
通常、スムーズにするのに十分な土地を確保するために、建物間の分離を最小限に抑える必要があります。または、配置の前に暫定的にアルゴリズムを実行して、急勾配のしきい値を超えているかどうかを確認し、ユーザーが建物を配置できる場所をポリシングします。