Разрабатывая под VR на Unity, у меня возникла проблема с TeleportArea, а именно, по умолчанию его можно создавать только прямоугольную.
![Прямоугольная TeleportArea Прямоугольная TeleportArea](https://habrastorage.org/getpro/habr/upload_files/ff7/517/c71/ff7517c71876615393b7eb18ccd2e824.png)
Но это достаточно неудобно, если на TeleportArea стоит статический объект и игрок может в нем застрять.
Эту проблему можно решить так, но решение будет выглядит немного неудовлетворительно(ну лично для меня).
![Решение, но у Нас уже 4 TeleportArea Решение, но у Нас уже 4 TeleportArea](https://habrastorage.org/getpro/habr/upload_files/8aa/812/997/8aa812997616a9a5491875d89b54e321.png)
Вроде бы, кажется, проблема решена, но
Вместо одного TeleportArea, мы имеем их целых 4
Данное решение сложно в реализации для большой, комнаты с большим количеством предметов
Это не гадиться для Terrain
![Некорректная работа с Terain Некорректная работа с Terain](https://habrastorage.org/getpro/habr/upload_files/df9/f0e/8c3/df9f0e8c360b908a681538f2b662f3c3.png)
Готовое решение
готовое решение этой проблемы есть, но оно к сожалению для SteamVr 1.x https://github.com/Flafla2/Vive-Teleporter,
Поэтому я решил, решить эту задачку, т.к. не я один страдал с нею!
Решение этой проблемы
В Unity есть отличный генератор проходимости персонажа NavMesh, он генерирует карту местности для AI.
![Запеченный NavMesh Запеченный NavMesh](https://habrastorage.org/getpro/habr/upload_files/7dd/7c3/fc9/7dd7c3fc974f45f2a31ecce14fcc9d52.png)
Почему бы не использовать его для генерации 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();
}
}
![](https://habrastorage.org/getpro/habr/upload_files/d25/a74/50a/d25a7450accf112f971b208a4e9c8cd1.png)
Как этим пользоваться
Скачать последний релиз с github https://github.com/LivelyPuer/NavMeshToTeleportArea
Импортировать его в Unity, предварительно установив пакет SteamVR 2.x
Создаем комнату
![Оформление комнаты Оформление комнаты](https://habrastorage.org/getpro/habr/upload_files/c01/600/917/c016009175d4ac5847c36e52b5bdd183.png)
4. Добавить на все статические объекты Collider и поставить галочку Static
![Static Static](https://habrastorage.org/getpro/habr/upload_files/e7d/afd/4c2/e7dafd4c2710f706a9b452da2dd07ea7.png)
5. Добавить префаб игрока SteamVR на сцену
![](https://habrastorage.org/getpro/habr/upload_files/8d0/ff0/01f/8d0ff001fc64b02ad02a0bdf83271ddb.png)
6. Открыть в окне Window/NavMesh to Mesh
7. Выбрать настройки для TeleportArea
![](https://habrastorage.org/getpro/habr/upload_files/ff0/135/a62/ff0135a62edb7a9412d59df5aa7b4326.png)
8. Нажать в открывшемся окне кнопку "Generate"
9. На сцене появится 2 объекта:
1. Teleporting(Система передвижения для SteamVR)
2. Наша сгенерированная TeleportArea
10. Все готово!
Наш готовый результат:
Спасибо, что прочитали статью, все предложения для будущего улучшения системы приветствуются в комментариях.