Search Unity

Navmesh / pathfinding on a sphere

Discussion in 'Scripting' started by will_brett, Mar 19, 2015.

  1. will_brett

    will_brett

    Joined:
    Feb 16, 2013
    Posts:
    208
    Hey everyone,

    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.

    Any ideas?

    THnaks
     
    daniel_lochner likes this.
  2. proandrius

    proandrius

    Unity Technologies

    Joined:
    Dec 4, 2012
    Posts:
    544
  3. Bryarey

    Bryarey

    Joined:
    Aug 24, 2014
    Posts:
    25
    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, I`ll do :) In short - I baked my planet 6 times, rotating different sides up. Then I manually added baked navmesh pieces, setting it`s rotation. And then connected it with off mesh links (sure, it must be more accurate for production).
     
  4. Monkey_M

    Monkey_M

    Joined:
    Mar 10, 2020
    Posts:
    36
    I am very interested in this I was looking for a solution online right now
     
    Bryarey likes this.
  5. Bryarey

    Bryarey

    Joined:
    Aug 24, 2014
    Posts:
    25
    Man, I`m really not sure, when I`ll be able to make a good tutorial, so let me describe the process in text.

    1. Create a sphere with geometry, mark in navmesh static, as usual.
    2. 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.
    3. 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.
    4. Rotate your sphere to 90 by X, and repeat. Rename to navmesh_90_0_0.
    5. 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.
    6. Create a script, which will load these navmesh "chunks":
    Here is my one:
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.AI;
    6.  
    7. [Serializable]
    8. public struct NavMeshChunk
    9. {
    10.     public Vector3 EulerRotation;
    11.  
    12.     //---- DRAG HERE YOUR BAKED NAVMESH CHUNK
    13.     public NavMeshData Data;          
    14.     public bool Enabled;
    15. }
    16.  
    17.  
    18. public class NavMeshSphere : MonoBehaviour
    19. {
    20.     //----- HERE ARE YOUR BAKED NAVMESH CHUNKS
    21.     [SerializeField]
    22.     private List<NavMeshChunk> _navMeshChunks;
    23.  
    24.     [SerializeField]
    25.     private List<NavMeshDataInstance> _instances = new List<NavMeshDataInstance>();
    26.  
    27.     [SerializeField]
    28.     private Transform _pivot;
    29.  
    30.     public void OnEnable()
    31.     {
    32.         RemoveAllNavMeshLoadedData();
    33.  
    34.         LoadNavmeshData();
    35.     }
    36.  
    37.     public void RemoveAllNavMeshLoadedData()
    38.     {
    39.         NavMesh.RemoveAllNavMeshData();
    40.     }
    41.  
    42.     public void LoadNavmeshData()
    43.     {
    44.         foreach(var chunk in _navMeshChunks)
    45.         {
    46.             if (chunk.Enabled)
    47.             {
    48.                 _instances.Add(
    49.                     NavMesh.AddNavMeshData(
    50.                         chunk.Data,
    51.                         _pivot.transform.position,
    52.                         Quaternion.Euler(chunk.EulerRotation)));
    53.             }
    54.         }
    55.     }
    56.  
    57.     public void OnDisable()
    58.     {
    59.         foreach(var instance in _instances)
    60.         {
    61.             instance.Remove();
    62.         }
    63.     }
    64. }
    7. 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.
    8. Do not forget to reset sphere rotation.
    9. You can use method LoadNavmeshData() from custom editor, to see loaded meshes in editor.
    10. Setup off-mesh links, as described in unity official docs.

    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 :)
     
    forloopcowboy likes this.
  6. Monkey_M

    Monkey_M

    Joined:
    Mar 10, 2020
    Posts:
    36
    Grazie mille!
    I will test even if I'm not an expert.

    If I get something good I will share it here. The challenge begins
     
  7. Bryarey

    Bryarey

    Joined:
    Aug 24, 2014
    Posts:
    25
    Good luck! Here is more detailed description
     
    Monkey_M likes this.
  8. Monkey_M

    Monkey_M

    Joined:
    Mar 10, 2020
    Posts:
    36
    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
     
  9. Fewnz

    Fewnz

    Joined:
    Aug 20, 2020
    Posts:
    1
    Super cool guys thanks !
     
  10. rameshblue

    rameshblue

    Joined:
    Dec 17, 2019
    Posts:
    1
    whats the pivot in that script
     
  11. Bryarey

    Bryarey

    Joined:
    Aug 24, 2014
    Posts:
    25
    Sorry for late answer, didn't saw this previously. _pivot is the origin of the sphere, and the point to rotate sphere around.
     
  12. DanVioletSagmiller

    DanVioletSagmiller

    Joined:
    Aug 26, 2010
    Posts:
    204
    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.