Генерация TeleportArea с помощью NavMesh

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Разрабатывая под VR на Unity, у меня возникла проблема с TeleportArea, а именно, по умолчанию его можно создавать только прямоугольную.

Прямоугольная TeleportArea
Прямоугольная TeleportArea

Но это достаточно неудобно, если на TeleportArea стоит статический объект и игрок может в нем застрять.

Эту проблему можно решить так, но решение будет выглядит немного неудовлетворительно(ну лично для меня).

Решение, но у Нас уже 4 TeleportArea
Решение, но у Нас уже 4 TeleportArea

Вроде бы, кажется, проблема решена, но

  1. Вместо одного TeleportArea, мы имеем их целых 4

  2. Данное решение сложно в реализации для большой, комнаты с большим количеством предметов

  3. Это не гадиться для Terrain

Некорректная работа с Terain
Некорректная работа с Terain

Готовое решение

готовое решение этой проблемы есть, но оно к сожалению для SteamVr 1.x https://github.com/Flafla2/Vive-Teleporter,

Поэтому я решил, решить эту задачку, т.к. не я один страдал с нею!

Решение этой проблемы

В Unity есть отличный генератор проходимости персонажа NavMesh, он генерирует карту местности для AI.

Запеченный NavMesh
Запеченный NavMesh

Почему бы не использовать его для генерации TeleportArea. Поэтому я сделал набросок скрипта для преобразования NavMesh в Mesh.

NavMeshTriangulation triangles = NavMesh.CalculateTriangulation();
Mesh mesh = new Mesh();
mesh.vertices = triangles.vertices;
mesh.triangles = triangles.indices;

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

public static void SaveMesh(Mesh mesh, string name, bool makeNewInstance, bool optimizeMesh)
    {
        Mesh meshToSave = (makeNewInstance) ? Instantiate(mesh) : mesh;

        if (optimizeMesh)
            MeshUtility.Optimize(meshToSave);

        AssetDatabase.CreateAsset(meshToSave, "Assets/GeneratedNavMeshes/" + name + ".asset");
        AssetDatabase.SaveAssets();
    }

Я оформил инструмент в виде EditorWindow

[CustomEditor(typeof(NaveMeshToMeshGenerator))]
public class NavMeshToMeshEditor : Editor
{
    public override void OnInspectorGUI()
    {
        NaveMeshToMeshGenerator now = (NaveMeshToMeshGenerator) target;
        GUILayout.Label("Created by LivelyPuer https://github.com/LivelyPuer");
        now.BakeNaveMesh = GUILayout.Toggle(now.BakeNaveMesh, "Bake NavMesh", EditorStyles.toggle);
        if (GUILayout.Button("GenerateMesh"))
        {
            string curScene = EditorSceneManager.GetActiveScene().name;
            if (now.BakeNaveMesh)
            {
                NavMeshBuilder.BuildNavMesh();
            }
            NavMeshTriangulation triangles = NavMesh.CalculateTriangulation();
            Mesh mesh = new Mesh();
            mesh.vertices = triangles.vertices;
            mesh.triangles = triangles.indices;
            SaveMesh(mesh, "Mesh" + curScene, true, false);
            MeshCollider now_Mesh = now.GetComponent<MeshCollider>();
            now_Mesh.sharedMesh = mesh;
            MeshFilter nowMeshFilter = now.GetComponent<MeshFilter>();
            nowMeshFilter.mesh = mesh;
            Debug.Log("TeleportArea was created");
        }
    }
    public static void SaveMesh(Mesh mesh, string name, bool makeNewInstance, bool optimizeMesh)
    {
        Mesh meshToSave = (makeNewInstance) ? Instantiate(mesh) : mesh;

        if (optimizeMesh)
            MeshUtility.Optimize(meshToSave);

        AssetDatabase.CreateAsset(meshToSave, "Assets/GeneratedNavMeshes/" + name + ".asset");
        AssetDatabase.SaveAssets();
    }
}

Как этим пользоваться

  1. Скачать последний релиз с github https://github.com/LivelyPuer/NavMeshToTeleportArea

  2. Импортировать его в Unity, предварительно установив пакет SteamVR 2.x

  3. Создаем комнату

Оформление комнаты
Оформление комнаты

4. Добавить на все статические объекты Collider и поставить галочку Static

Static
Static

5. Добавить префаб игрока SteamVR на сцену

6. Открыть в окне Window/NavMesh to Mesh

7. Выбрать настройки для TeleportArea

8. Нажать в открывшемся окне кнопку "Generate"

9. На сцене появится 2 объекта:

1. Teleporting(Система передвижения для SteamVR)

2. Наша сгенерированная TeleportArea

10. Все готово!

Наш готовый результат:

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

Готовый проект можно найти в github

Источник: https://habr.com/ru/post/588675/


Интересные статьи

Интересные статьи

Одной из задач администрирования облачной инфраструктуры является мониторинг её компонентов: важно знать о неправильной работе облака, вовремя выявлять и исправлять ошибк...
GraphQL это современный язык запросов для получения данных с сервера. Существует большое количество документации по построению API для целого вороха платформ, но к сожале...
Ваш новый разработчик только что закончил подписывать трудовой договор и с горящими глазами готов закрывать по 15 задач в день. На его пути стоит лишь одно препятствие — ...
Новая методика взлома преодолевает проблему «джиттера сети», которая может влиять на успешность атак по сторонним каналам Новая методика, разработанная исследователями Левенско...
В анализаторе PVS-Studio для языков С и C++ на Linux и macOS, начиная с версии 7.04, появилась тестовая возможность проверить список указанных файлов. С помощью нового режима можно настроить ан...