Is there a plugin or simple way to get pathfinding to work on a sphere? Im making a simple planetary game and i’ve managed to get the player to move on the planet surface fine and now want to get enemies to chase the player but as navmesh doesnt work on spheres im not sure how to achieve this.
Hi! Just made spherical surface navigation via unity`s NavMesh:
It was tricky, so for now I have no power to record a tutorial, but be sure, Ill do :) In short - I baked my planet 6 times, rotating different sides up. Then I manually added baked navmesh pieces, setting its rotation. And then connected it with off mesh links (sure, it must be more accurate for production).
Man, Im really not sure, when Ill be able to make a good tutorial, so let me describe the process in text.
Create a sphere with geometry, mark in navmesh static, as usual.
Setup navmesh baking settings, max slope must be pretty large, but 60 deg was too much in my case - 54 worked well for me. Also, if you have high walls, it`s better to set small agent height for baking.
Bake navmesh. It will bake a shape, which looks like a square, projected on sphere. Now you have a “NavMesh” file generated in folder, named as your scene. Rename it. I choosed naming convention, when baking rotation described in file name. Starting from zero, so the file name is navmesh_0_0_0.
Rotate your sphere to 90 by X, and repeat. Rename to navmesh_90_0_0.
Repeat totally 6 times, you`ll have additionaly next files: navmesh_180_0_0, navmesh_270_0_0, navmesh_0_0_90, navmesh_0_0_270.
Create a script, which will load these navmesh “chunks”:
Here is my one:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
[Serializable]
public struct NavMeshChunk
{
public Vector3 EulerRotation;
//---- DRAG HERE YOUR BAKED NAVMESH CHUNK
public NavMeshData Data;
public bool Enabled;
}
public class NavMeshSphere : MonoBehaviour
{
//----- HERE ARE YOUR BAKED NAVMESH CHUNKS
[SerializeField]
private List<NavMeshChunk> _navMeshChunks;
[SerializeField]
private List<NavMeshDataInstance> _instances = new List<NavMeshDataInstance>();
[SerializeField]
private Transform _pivot;
public void OnEnable()
{
RemoveAllNavMeshLoadedData();
LoadNavmeshData();
}
public void RemoveAllNavMeshLoadedData()
{
NavMesh.RemoveAllNavMeshData();
}
public void LoadNavmeshData()
{
foreach(var chunk in _navMeshChunks)
{
if (chunk.Enabled)
{
_instances.Add(
NavMesh.AddNavMeshData(
chunk.Data,
_pivot.transform.position,
Quaternion.Euler(chunk.EulerRotation)));
}
}
}
public void OnDisable()
{
foreach(var instance in _instances)
{
instance.Remove();
}
}
}
Drag your baked navmesh chunks into array in inspector. Setup euler rotation for each of them. Note: if you rotated sphere during baking by 90 deg X, and file called navmesh_90_0_0, you need to set euler rotation to 270, 0, 0. And wice versa.
Do not forget to reset sphere rotation.
You can use method LoadNavmeshData() from custom editor, to see loaded meshes in editor.
Thats it! Be ready, probably it wont work exactly as you want from first try, but it possible to fix. Also, especially for my case, it was the best solution to have 6 walkable meshes, for each chunks, without walls. So the baking actually just filled whole available surface with navmesh. I enabled one of that meshes for each baking, while main geometry was disabled.
Good luck, and please, share your results, if you`ll get it work, and if you able to share - very interesting to see
Fantastic tutorial. Works well!
I just have to try to fill the final holes manually.
To add an obstacle I assume I have to do it all over again by placing the obstacle in the face I want, right?
Thanks again a really good idea. I had thought of something similar but my script was not working properly
New Answer: From Unity. Using the Experimental Navigation AI, (currently at 1.0.0.4 I believe) you can now have multiple directions of navmeshes joined together.