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

Разрабатывая под 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();
            now_Mesh.sharedMesh = mesh;
            MeshFilter nowMeshFilter = now.GetComponent();
            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();
    }
}

image-loader.svg

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

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

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

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

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

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

StaticStatic

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

image-loader.svg

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

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

image-loader.svg

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

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

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

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

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

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

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

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

© Habrahabr.ru