Как мне сплющить местность под игровым объектом?


10

У меня есть скрипт, который создает объект местности и рисует его текстурами, но у меня проблема. Когда я пытаюсь разместить игровые объекты (например, простой водный объект, который обеспечивает единица), я использую Raycast, чтобы определить правильную высоту для размещения игрового объекта, но это просто гарантирует, что он правильно расположен в этой конкретной точке.

Как бы мне сгладить рельеф местности под игровым объектом, чтобы он не уходил в местность и не зависал в воздухе на холмах?


3
Найдите все вершины, которые образуют треугольники местности под игровым объектом. Сделайте координату Y всех этих вершин одинаковыми.
MichaelHouse

Ответы:


6

Как я сказал в своем комментарии, вы захотите найти все вершины, которые составляют треугольники под вашим игровым объектом, и установить для их значения y то же значение.

Я дополню свой комментарий более подробными шагами. Я не слишком знаком с Unity, поэтому я не знаю лучших инструментов, которые можно использовать для этой работы, но я верю, что смогу помочь вам начать правильный путь.

Метод грубой силы:

  1. Бросайте сетку лучей прямо от игрового объекта. Сетка должна быть достаточно плотной, чтобы не пропустить треугольники на поверхности местности.
  2. Для каждого луча, который попадает во что-то, вы можете получить треугольник в сетке ландшафта со следующим:

    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]];
  3. p0, p1 и p2 - все позиции трех вершин, которые составляют треугольник, который был поражен. Вы хотите настроить каждую из этих вершин, чтобы они имели одинаковое yзначение. Вы можете либо собрать все вершины, а затем установить для них все среднее yзначение или использовать начальное выбранное yзначение, которое вы нашли при размещении игрового объекта.

Оптимизации:

  • Вместо того, чтобы просто бросать сетку лучей, вы можете смести коллайдер с игрового объекта и собрать точки контакта столкновений между коллайдером игрового объекта и сеткой столкновения ландшафта. Затем для каждой из этих точек контакта выполните описанные выше шаги для получения вершин, которые вы хотите переместить.

  • Создайте свою местность таким образом, чтобы каждая вершина xи ее zзначения были выровнены по сетке и изменились только по ее yзначению. Теперь вы можете легко получить границы вашего игрового объекта и изменить все значения y вершин в этих границах.

Эта последняя оптимизация действительно является альтернативным методом, который, вероятно, будет простым в реализации и достаточно эффективным.


Из того, что я могу сказать, у объекта Terrain ( docs.unity3d.com/Documentation/ScriptReference/Terrain.html ) есть TerrainCollider ( docs.unity3d.com/Documentation/ScriptReference/… ), а не MeshCollider ( docs.unity3d.com/Documentation). / ScriptReference /… ), поэтому в нем отсутствует свойство sharedMesh, которое вы пытаетесь использовать на шаге 2. Я предположил, что мне понадобится какая-то логика для изменения карты высот, которую хранит свойство terrainData.
Рапида

Вы можете проверить здесь: forum.unity3d.com/threads/… Кроме того, кажется, что объект terrain имеет регулярную сетку, поэтому вторая оптимизация может быть вашим лучшим выбором.
MichaelHouse

1

Обычно требуется, чтобы земля под объектом была ровной, а земля вокруг нее - ровной.

Если земля сделана из сетки, а здание выровнено по оси, это намного проще.

В общем случае вы подразделяете треугольники, на которых расположено здание, и затем устанавливаете y всех вершин на треугольниках, на которых строится здание, на один и тот же y , а затем выполняете сглаживание смещения средней точки для всех вершин на определенном расстоянии, которые не сами под зданием.

Я использовал этот подход, чтобы поместить дороги в трехмерную местность.

Как правило, вы хотите установить минимальное расстояние между зданиями, чтобы иметь достаточно земли для выравнивания. Или вы можете предварительно запустить алгоритм перед размещением и посмотреть, не превышен ли какой-либо порог крутизны, и, таким образом, контролировать, где пользователь может размещать здания.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.