Як вирівняти місцевість під ігровим об’єктом?


10

У мене є сценарій, який робить об’єкт місцевості та фарбує його текстурами, але у мене виникає проблема. Коли я намагаюся розмістити ігрові об’єкти (наприклад, простий водний об’єкт, який забезпечує єдність), я використовую Raycast для визначення правильної висоти для розміщення ігрового об’єкта, але це просто гарантує його правильне розміщення в цій конкретній точці.

Як би я подумав про вирівнювання місцевості під ігровим об’єктом, щоб він не виходив на місцевість і не висів у повітрі у випадку пагорбів?


3
Знайдіть усі вершини, які утворюють місцеві трикутники під ігровим об’єктом. Зробіть координату у всіх цих вершин однаковою.
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.
Rapida

Ви можете перевірити тут: forum.unity3d.com/threads/… Крім того, здається, що місцевий об’єкт має звичайну сітку, тому друга оптимізація може стати вашою найкращою ставкою.
MichaelHouse

1

Зазвичай він хоче, щоб земля під об'єктом була рівною, а земля безпосередньо навколо неї була згладжена.

Якщо земля зроблена з сітки, а будівля вирівняна по осі, це набагато простіше.

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

Я використовував цей підхід для розміщення доріг на 3D-місцевості.

Зазвичай ви хочете забезпечити мінімальний поділ між будівлями, щоб мати достатньо землі для згладжування. Або ви можете запускати алгоритм попередньо перед розміщенням і бачити, чи не перевищений якийсь поріг крутості, і таким чином слід виконувати функції, де користувач може розміщувати будівлі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.