Search Unity

Runtime Loading / Saving Navmesh Data??? Lol?

Discussion in 'Navigation' started by Leoo, Apr 25, 2017.

  1. Leoo

    Leoo

    Joined:
    May 13, 2013
    Posts:
    96
    Am not sure if anyone realized or already asked this question on the forums.

    So , new dynamic navmesh generation, BUT no saving / loading navmesh data?

    Lol?
     
    TobyWu likes this.
  2. dannuic

    dannuic

    Joined:
    Mar 30, 2017
    Posts:
    4
    You can grab the navmesh vertices/triangles through NavMesh.CalculateTriangulation() and output any format you'd like. Theoretically, you can load by importing the file, converting to a mesh, and then building it but I'm having no luck doing that.
     
  3. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    Having actually the same problem.

    I would definitely need a load/save function as I have a tile base system (up to 10k tiles) with an ingame edtior. which takes 15-20 seconds to generate on a quite fast machine. Users will not wait for so long to load a level.

    Any help would be greatly appreciated!
     
  4. BTables

    BTables

    Joined:
    Jan 18, 2014
    Posts:
    61
    +1 really need a solution to this
     
  5. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    There is no way to inject this data back into the navmesh, so this is not going to work. I created a mesh out of this triangulation data, but I would need to bake it again, which doesn't help at all.

    We need some more functions exposed to make this work or a save/load function for the navmesh. If this is not going to be solved soon, I will kick the Unity navigation completely and try a different solution.

    @Jakob_Unity it would be great if you could give a comment, if this is on the roadmap in the near future. Cheers.
     
    Last edited: Jun 12, 2017
  6. Jakob_Unity

    Jakob_Unity

    Joined:
    Dec 25, 2011
    Posts:
    269
    I will look into this - but currently busy working on much requested async query API.
     
  7. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    Thanks! :)
     
  8. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    Any news yet?
     
  9. Jakob_Unity

    Jakob_Unity

    Joined:
    Dec 25, 2011
    Posts:
    269
    no - only thoughts so far. We might add a special serialize/deserialize API for navmesh - e.g. between NavMeshData and byte array.
     
    DwinTeimlon and JBR-games like this.
  10. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    Thanks for the update. Adding a serialize/deserialize API to the navmesh would be perfect!
     
  11. Sebsc

    Sebsc

    Joined:
    Oct 18, 2016
    Posts:
    22
    That would indeed fix the issue - be sure to also include the build source cache and other useful stuff needed so that we can run the lightning fast UpdateNavMeshData on it just as if it was backed in the same session.

    In my scenario on a 2048x2048 terrain it takes upwards of a minute to generate the initial mesh. Later UpdateNavMeshDataAsync calls are instant so kudos on that!

    Now I just need a way to save the navmesh once generated and just update it as new stuff (buildings) etc are created.
     
  12. jnorris-sca

    jnorris-sca

    Joined:
    Oct 6, 2017
    Posts:
    8
    Any progress on this?
     
  13. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Ya this is kind of a major oversight in the api. You can create instances of navmeshdata and store/load those, but you can't obtain an instance of it from the navmesh. Providing serialization kind of misses the major point which is we can't even get at the object itself right now if it was created via the normal build process.
     
  14. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    So you can get partway there now.

    First create your navmesh using the builder, not the editor flow. Otherwise updating takes a long time since the editor uses different settings.

    Then create a component (ScriptableObject will not work) with a NavMeshData field in your scene and then use AssetDatabase.CreateAsset to save the navmeshdata That links the field to the asset and now it persists in the scene. Now you load it via NavMesh.AddNavMeshData.

    That at least lets you start with a base navmesh already there that you can also update.
     
    RomanSpai, DwinTeimlon and JBR-games like this.
  15. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Actually you don't need to save it as an asset. I was trying to use that to make ScriptableObject work which didn't, but I just went back and tried it with the component route and not creating an asset, and it persists fine.
     
  16. jnorris-sca

    jnorris-sca

    Joined:
    Oct 6, 2017
    Posts:
    8
    DebugLogError likes this.
  17. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    Everything works fine in the editor using AssetDatabase, but this doesn't work in builds of course.

    Any update on the serialization possibilities?
     
    DebugLogError likes this.
  18. joshenes

    joshenes

    Joined:
    Apr 18, 2014
    Posts:
    48
    This is a big hole in the pipeline for those who don't use scenes to manage content.

    Maybe I am oversimplifying this in my head, but surely Unity is already serializing the navmesh for a scene into the NavMesh.asset file, and then de-serializing it when the scene is loaded. How far removed could we possibly be from saving a runtime generated navmesh into a .asset file and then loading it on demand?

    It feels like the navmesh system was 90% implemented and abandoned a few steps before the finish line. We switched over to runtime navmesh generation in Unity 5.6 with the promise of runtime navmesh jump generation "coming soon". Now it's a year later and here we are still manually placing jumps.
     
    joshcamas and malkere like this.
  19. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,277
    100%. The Navmesh system has felt incomplete ever since it's initial release, and it's very frustrating. But we get graphics updates cause that's what looks good on the advertisements
     
  20. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    Can you please give an update on this? It takes multiple minutes for me to generate a navmesh using the runtime generation. I have a large open world game with lots of dynamically placed trees and so on. Forcing users to wait that long each startup is not an acceptable solution for me.
     
  21. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    If it takes multiple minutes, you aren't using it right. Generate it with the scene, then just do an async update when stuff changes. It takes around 350ms on my system to update a 1k terrain.
     
  22. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    Mine was with a 2k terrain with over 20 thousand additional colliders in the scene from trees/etc. Also as I mentioned above, everything is procedurally placed at runtime on the first play through so that it's different each time. So the only thing that could be saved in the scene is the terrain.
     
    tatsuuuuuuu likes this.
  23. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Well my advice is rethink your design or switch to a grid based system. Because if you insist on generating large navmeshes on play, you are going to take a hit in framerate or availability, one of the two. Doesn't matter what Unity does you will still have that choice going with your approach.

    But honestly I can't even think of a good reason why generate at play, I'm curious what's the reason for that?
     
  24. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    I don't think you understand what this feature request is for. It's to be able to save a runtime generated navmesh to a file, and be able to reload it. That would mean very little overhead compared to generating a navmesh from scratch. So no, I don't agree with that it won't work no matter what Unity does.

    I've already switched to another asset, the A* pathfinding project. It generates the entire navmesh in one minute instead of multiple, and supports runtime loading/saving of the navmesh so that one minute goes to almost zero for every launch of the game except the first. However, there's things I prefer over Unity's system instead of this one, so I'd like to switch back. This feature is what's holding me back.

    I've explained that I have to generate it at runtime because trees and other objects are placed at runtime. They do not have static positions. It's a dynamic spawning system so the world feels a bit different for each play through. Updating the nav mesh 20k+ times has more overhead than generating it from scratch.
     
    tatsuuuuuuu likes this.
  25. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    I generate entirely during runtime. The most important settings are tileSize and voxelSize, I use 100 and 0.15. I can bake what I use around the player, a 400x400 space, in 3.29s fully asynchronously in 100x100 chunks. If you do the whole thing at once there is a snag when it tries to input all the calculated data to the main thread. I then update 100x100 chunks around the player as necessary using less than 1s each again 99% off the main thread. My agents will not turn themselves on until they can successfully find a navmesh after the player comes within 200m of them, and are turned off when more than 200m and the navmesh is removed at around 300m.

    I use carving to put down trees and other objects which only cost nanoseconds. I also have dynamic building and refresh the 100x100 chunks as necessary whenever a player places a new building. It all works quite well, and A* was much less performant in my case.

    If you terrain is static just the trees and things are generated I would highly recommend looking into carving. But there are definitely ways to get it working runtime just fine. The biggest problem I have right now is that there are zero links in my world. When an agent reaches an edge they have to recognize that and be forced onto the next navmesh, as I've posted about here in the forums.

    If there was a way to save the data I might still not even use it because I'd be loading 512x512 per terrain chunks and they had a visible hiccup when finalizing. I think waiting until the navmesh has been completed to spawn monsters and making them check to make sure they can find a navmesh is a better approach for games that do not have the option of pre-baking. I have players beyond 86km in an open procedural world. There is no way that would ever work with pre-baking, and is almost entirely undocumented despite many months gone by now, but it does more or less work.

    If I were trying to get the voxelsize lower or worrying about multiple agent sizes it might be a different story but right now 3-5s is plenty to regenerate on the fly.
     
    Last edited: Mar 21, 2018
    Rootbeard likes this.
  26. gomizako

    gomizako

    Joined:
    Apr 2, 2015
    Posts:
    11
    Any updates? I'm currently using AssetDatabase to save NavMesh data and then loading it in, similar to @emrys90 and others here. I'm working on a simulation which loads arbitrary locations using GPS locations (using MapBox) and the "levels" can be gigantic. It's a simulation so I don't mind the generation taking a long time -- most locations take > 30 minutes. The largest took > 6 hours, and this is after already having tuned tileSize and voxelSize. I don't mind since I can just save the data and load it after the first time. However I would like to get away from using the editor so I can make builds and give to users and allow them to create their own data.
     
  27. AFrisby

    AFrisby

    Joined:
    Apr 14, 2010
    Posts:
    223
    *bump*
     
  28. Ziron999

    Ziron999

    Joined:
    Jan 22, 2014
    Posts:
    282
    rofl this is still an issue
     
  29. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,277
    Yep, current solution is to avoid Unity's built in Navmesh entirely and shell out $100 for a comparable addon that has the feature :^^)
     
  30. Ziron999

    Ziron999

    Joined:
    Jan 22, 2014
    Posts:
    282
    i have an infinite world i can't find anything that works, i'm sure this doesn't either. don't plan on spending $100 just to find out....
     
  31. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,277
    For infinite worlds, doesn't that mean you would generate the navmesh during runtime? Even unity supports that... Or do you need finer control?
     
  32. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    Code (CSharp):
    1.                     //prep the nav mesh data
    2.                     navMeshData = NavMeshBuilder.BuildNavMeshData(
    3.                         navMeshBuildSettings,
    4.                         GetBuildSources(nullMask),
    5.                         new Bounds(boundsCenter, boundsSize),
    6.                         tilePosition,
    7.                         Quaternion.identity);
    8.  
    9.                     //generate the actual nav mesh
    10.                     building = true;
    11.                     StartCoroutine(UpdateNavmeshDataAsync());
    12.                     while (building) {
    13.                         yield return null;
    14.                     }
    Code (CSharp):
    1.     IEnumerator UpdateNavmeshDataAsync() {
    2.         AsyncOperation op = NavMeshBuilder.UpdateNavMeshDataAsync(
    3.             navMeshData,
    4.             navMeshBuildSettings,
    5.             GetBuildSources(buildMask),
    6.             new Bounds(boundsCenter, boundsSize));
    7.         yield return op;
    8.  
    9.         building = false;
    10.     }
    should just yield return op; the first time huh... wrote that 9 months ago, been using it without problems since. Haven't really seen any upgrades to the system Unity side unfortunately =/
     
    Last edited: Feb 12, 2019
  33. Ziron999

    Ziron999

    Joined:
    Jan 22, 2014
    Posts:
    282
    i have tried the async but it's a major downside i figured out how to use a* in a way that will make this possible. this issue is fixed for me now :)
     
  34. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    I never was able to get A* to work off the main thread. It's been a long time though. It also caused monsters to get stuck on ramp corners as it would "mush" the edges as walkable and they'd fall off =[ It was definitely a powerful tool set though... wish I had the time to look deeper into it.
     
  35. Ziron999

    Ziron999

    Joined:
    Jan 22, 2014
    Posts:
    282
    I have fixed any possibility of stuck/falling through the world stuff long ago luckily. It has worked perfectly with 50 enemies and everything going super speed fast as a breakthrough test.
     
  36. Ziron999

    Ziron999

    Joined:
    Jan 22, 2014
    Posts:
    282
    The enemies have a steeper slope requirement just to see how they behave when stuck, everything worked.
     
  37. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    I mean everything is up to your settings no matter the system. I need monsters to be able to go multiple levels and tight doorways and things, runtime carving, etc., I had things turned up pretty high. It's never the pathfinding itself, but the generation of the surfaces. I'm running almost zero percent on the main thread with async navmesh generation. But A* is actively developed... unlike navmesh seems to be... it's probably a lot better than when I used it. I think jobs can raycast off the main thread now, which was not possible a couple years ago, which is how the whole recast system works... might be worth the time to look back into =D not being able to link multiple navmeshes in runtime is a serious pain... none of my players complain though so... ya... back to other things XD
     
  38. plindsey

    plindsey

    Joined:
    May 31, 2014
    Posts:
    1
    Any update on this? This would really open up the engine a lot.
     
  39. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    This thread is 2.5 years and going. I asked around in some other threads a month or two ago, all I got from them was more or less that, the system already has everything it needs and no one is going to improve the runtime stuff. That wasn't actual Unity staff responses though, so who knows. It's a very incomplete system as is and most people end up going to something else for runtime support.
    If you're building static levels for mobile it's the bee's knees I guess :rolleyes:
     
    joshcamas likes this.
  40. Ne0mega

    Ne0mega

    Joined:
    Feb 18, 2018
    Posts:
    755
    well dammit, so proud of myself for getting a runtime generated terrain and NavMesh, but it looks like I cannot save the terrain or navmesh bake results.

    That leaves me with four options:
    1) rebuild the terrain from seed/serialized data and rebuild navmesh on every scene load
    2) hope Unity decides saving runtime generated assets is worth investing dev time into in the next couple of years
    3) hope computers get fast enough it will not matter by my release date.
     
    joshcamas likes this.
  41. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,277
    4. https://arongranberg.com/astar/ I use this. It's really good, and lets you access / modify / create the actual navmesh data, and also allows for a lot more complex stuff, like physics based agents and such.
     
    Ne0mega likes this.
  42. Ne0mega

    Ne0mega

    Joined:
    Feb 18, 2018
    Posts:
    755
    ah, so it does. that was going to be my number 4, but I was not sure if it could.
    I suppose at this juncture I coukd switch to Astar project, since as I have been making my game, the issue of runtime terrain generation has constantly deflated my hopes for easier asset integration, since everything seems so geared towards editor created scenes.
     
  43. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    I'm still running Unity navmesh, recreating every load... but I own Astar, and dream of finding the time to implement it... Unity has pretty much said they think the navmesh system is fine and doesn't need work and then gone silent for the past couple years. I do generate navmesh off thread very fast, like 0.8s, the settings you use can make a big, often unituitive difference, but there are plenty of other problems that still make it a very flawed system unless you're building tiny levels for mobile.
     
  44. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Maybe this will help light a fire on this issue.

    In 2019.3 when they added terrain holes it introduced some bugs that caused navmesh rebuild times to increase dramatically. It was the last straw for us so I just wrote our own system using recast (what Unity uses also) and a set of C# wrappers over it.

    What most don't know because Unity conflates things is that the navmesh and tile building are completely separate things. You build tiles, that process impacts the navmesh not at all. Then you add/remove those tiles to the navmesh, which takes almost no time at all.

    The only synchronization with the main thread that has to happen is query handles. Because those are inherently tied to the navmesh and you can't have queries in progress while adding/removing tiles. But as I said adding/removing tiles is really really fast. Updating a small handful at runtime is sub 10ms (I'm being very conservative there).

    You just can't reconcile how it actually works internally with how Unity's implementation works. They screwed it up and on top of that they keep making it worse with every new feature (terrain holes *cough*).
     
    malkere likes this.
  45. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    Without a way to add onto a navmesh or at least connect neighbors or something it's really just a terribly incomplete system that doesn't work with anything that isn't static in the first place. In my open world procedural case anyway. I just don't have updating to Astar planned for another couple months, so my mobs jitter and dance every time they get to the edge of a navmesh until the AI notices and gives them a shove =/ super hacky, embarrassing bandaid for a system that doesn't support me using it the way I want/need to. Not to mention grass performance, the base terrain shader, restructuring the entire tree set with every change =o= so many unfinished systems in the terrain department, again: unless you're building small static levels, then it's the bee's knees!
     
  46. Ne0mega

    Ne0mega

    Joined:
    Feb 18, 2018
    Posts:
    755
    run-time nav mesh creation is good in Unity. You can easily connect neighbors, same with infinite terrain generation.

    There are samples of this in the Navmeshcomponents pack (not a part of default Unity, but still an official Unity project, must be downloaded separately).

    It's only saving to avoid re-baking every time that is problematic.
     
    Last edited: Dec 22, 2019
  47. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    @Ne0mega You can only connect straight lines and points, unless I've grossly overlooked something for years. Terrains are not flat and I also have buildings and obstacles and, you know, stuff. I probably could write a ridiculous script to add thousands of links to compensate for each terrain face and object, doesn't sound like a "performant" solution though. I generate infinite terrain and have to overlap the navmeshes and "push" agent onto the next over whenever they reach an edge. We need a "neighbor" system like terrains have, where navmesh edges can recognize one another.
     
  48. Ne0mega

    Ne0mega

    Joined:
    Feb 18, 2018
    Posts:
    755
    Scene 4 is "sliding Window, infinite terrain".

    In example scene two "Drop Plank" it shows how you can use meshes to change the nav mesh. In the example, you instantiate an object, that example has a prefab (a plank) with couple of components whose job is to meld its navmesh with the existing navmesh.

    I can generate terrain with a generated navmesh now. Just add prefabs of any objects you wish, and they will meld their navmesh with the overall navmesh.

    For never ending terrain or huge terrains, there are things called NavMeshModifierVolumes which are valumes/change spaces you can create to change the navmesh, so you don't have to rebuild the entire navmesh every time.

    You should definitely start a new project, download it, and look at some of the example scenes. There are a ton of great examples of some very cool stuff you can do with run-time navmesh generation.

    And you have grossly overlooked something, because this is a Unity supported-ish high level API for Unity. Its kind of lost between the asset store, and official unity add-ons.
    It's last official version was built for 2018.3, but it works very well for me (2019.2). I can not emphasize enough how happy I was when I actually downloaded it and tried the example scenes (this was just a few days ago... ..it is REALLY awesome) (there are seven different run time navmeshmodification scene examples.)
     
    Last edited: Dec 22, 2019
    doarp likes this.
  49. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356

    You don't need modifier volumes to change small parts of the navmesh. In fact all of the github components are just high level functionality built over existing core api's that have been there for quite a while.

    Another thing is performance varies a lot depending on what your inputs look like, and 2019.3 has some special performance degradation of it's own.

    You shouldn't have to rebuild anything at all unless something actually changes. Like you should be able to build your tiles by scene (or whatever scope you want), and then just have a single runtime navmesh where you load/unload tiles on the fly. And be able to do that in a granular way also. The underlying system fully supports that, it's a key feature actually.

    And of course persist those changes, which is what this thread was sort of originally about. In a persistent world with changes over time that's sort of a deal breaker actually. Accumulated dynamic changes to the environment can eventually lead to players having to rebuild significant parts of the navmesh every time they enter part of the world.

    The limitations don't stop there either.

    Here is an example of what we do using recast directly. First of all tile changes persist and we version them against dynamic item id's. So clients only ever rebuild for a change once. We also split what the server and client do. The clients build tiles, the server runs the crowd simulation (multithreaded which you can't do in Unity either). The server has a simple protocol where clients update it with what version they are at, it dynamically pulls tile changes from them and loads those into it's navmesh for use by the crowd. The crowd is not deterministic, that's why you need an authoritative crowd on the server.

    Just so many things you can't actually do well or right with Unity's navmesh system.
     
  50. Ne0mega

    Ne0mega

    Joined:
    Feb 18, 2018
    Posts:
    755
    You can spawn NavMeshModifierVolumes wherever the small changes are needed. The dynamic changes are done anywhere a change is made. No accumulation required.

    or you center a NavMeshModifierVolume around your character. And then it is only constantly updating however much area around the character you feel is necessary. This is shown in the example #5, "sliding window terrain". Whatever happens outside that window is irrelevant, since the agent's navMesh will only be built when the player arrives.


    For now, I am working on a system to serialize the mesh geometry (binary), and then serialize carving objects/navmesh obstacles, (will use asset store serializer for this part probably) and then build the navMesh during runtime, since I have not found a way to serialize the navmesh itself.... yet.
     
    Last edited: Dec 22, 2019