Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Dynamically Translating/Rotating a NavMesh Surface/NavMesh Agent

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

  1. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    158
    Hi,

    I am working on a space game, which requires AI characters to be able to walk on a spacecraft that is moving and rotating. Since Unity's navmeshes could not previously do this, I implemented my own solution, which works ok. However, it's quite crude, and so I decided to upgrade to Unity 5.6 and try out the new Navmesh upgrades.

    I have added the NavMeshComponents from the Github page (https://github.com/Unity-Technologies/NavMeshComponents), and I have added a "NavMeshSurface" component to my spaceship object, which allows me to translate and rotate the spaceship object in real-time, and have the navmesh translate and rotate with it. So far, this all works great, I can see the navmesh moving and rotating as the spaceship moves.

    The problem, however, is that the NavMesh Agent component on my AI character prevents the character from moving when the spaceship moves. The AI character is a child of the spaceship, so, with my system, I was able to just move the spaceship (By just modifying the transform and rotation values, I am not using a rigidbody), and all of the child objects (The player, AI, etc) would also move.

    However the Unity NavMesh Agent prevents this, the AI ends up staying in place, while the ship moves.

    Am I doing something wrong, or is this functionality not available with the Unity system? I would like to switch back to Unity's navmesh if possible, since it is better than my system, but I need to be able to dynamically rotate and translate the parent object, and have the AI move with it.

    Thanks for any advice!
     
  2. christougher

    christougher

    Joined:
    Mar 6, 2015
    Posts:
    418
    I think I remember seeing that it's not supported, basically saying that any movement is basically teleporting it and triggering recalcs galore... And I think that the navmesh agent's destination is not actually updating with the rotation/translation of the mesh... so it could be that there simply is no path to that point in space. perhaps when you set a destination you should set as destination an empty gameobject that is a child of the space station as well so that it stays on the navmesh??? I dunno, I'm just thinking out loud. I think it could be terrible performance-wise if the agent could even keep up with the changing transforms...

    Disclaimer: I'm far from an expert!!!!
     
  3. christougher

    christougher

    Joined:
    Mar 6, 2015
    Posts:
    418
    :D ok... but it gets a little bit hacky...



    So in the example scene #3 from the github (https://github.com/Unity-Technologies/NavMeshComponents) I added the oscillator script to the TiltedPlane and saw that pathfinding pretty much stopped as you described above... however When I added a LocalNavMeshBuilder to the TiltedPlane object it worked! But it only worked if I left the originally baked navmesh on there (actually an oversight on my part). If I had it as a navmeshsourcetag with the LocalNavmeshBuilder moving it crashed unity... it did eventually work but VERY jittery... the baked version was quite stable but would only work if the LocalNavmeshBuilder targeted the area.

    I used Behavior Designer to slowly rotate the plane as well and then I have the yellow dude wandering with the red dude seeking after the yellow, also courtesy of Behavior designer.... which is what you see in the video.

    Soooo. try this... bake on your nav mesh, add the LocalNavmeshBuilder with your spaceship as the target, WITHOUT adding a NavMeshSourceTag... and report back. Good Luck!!!!!
     
  4. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    158
    Thank you very much, I'll definitely try out those ideas and see how far I get!
     
  5. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    158
    I tried this out, and it didn't seem to work.

    What I did was:

    Added a LocalNavMeshBuilder to the parent object (SpaceShip), set the "tracked" value to the spaceship, and change the size of the nav mesh builder. I also baked the navmesh surface.

    The AI is still not moving with the navmesh.

    The only other thing that I can think of is that the actual colliders are children of the SpaceShip gameobject, but this doesn't make a difference for the navmesh, I can still see it and rotate/move it properly.
     
  6. christougher

    christougher

    Joined:
    Mar 6, 2015
    Posts:
    418
    Do you have behaviour designer? I've got a scene I can share that has agents using nav mesh links to nav mesh surfaces on children objects as well. One issue I did notice is that agents will constantly try to reach their destination in global space, not necessarily the original local point on the nav mesh. In other words the destination doesn't update with the nav mesh movements, so my thought is that when a destination is set it actually needs to be an empty gameobject or node that is childed to your space ship...

    Also, gone is the need for the local nav mesh builder??? Not sure what changed for me but they are working fine now without it...
     
  7. christougher

    christougher

    Joined:
    Mar 6, 2015
    Posts:
    418
    Also make sure you've got the latest scripts from the github
     
  8. christougher

    christougher

    Joined:
    Mar 6, 2015
    Posts:
    418
    New video in action of the moving/rotating 'spaceship' with mostly stable pathing. There is the floor with two 90 degree walls each with it's own navMeshSurface connected by two wide NavmeshLinks. The yellow is alternating between seeking the pink orbs and the red is following the yellow.

     
  9. Jakob_Unity

    Jakob_Unity

    Unity Technologies

    Joined:
    Dec 25, 2011
    Posts:
    269
    From the github projects FAQ:

    Q: Can I do moving NavMesh platforms?
    A: No - new API is required for consistently moving platforms carrying agents.
     
  10. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    158
    Hi,

    Thank you for your replies.

    I haven't tried to set the destination using an empty game object, I think that is a good idea, I'll try that today.

    I have the latest version of everything, I just downloaded the scripts a few days ago.

    Jakob, I saw that on the github, but I figured I'd try it anyway, and it seems to work fine in the example scenes, which christougher posted, even if it's not officially supported.

    Is there a new API, or any updates coming that would add this feature officially? I would be prepared to wait for that, if it was forthcoming.

    Thanks all!
     
  11. Marcos-Elias

    Marcos-Elias

    Joined:
    Nov 1, 2014
    Posts:
    93
    Still no progress about this? :(
    I want to use NavMesh but I need floating origin... And it does not work here... Floating origin is a must for large world projects, we need to move everything (in my case when player are far than 999 units from the 0,0,0).
     
  12. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    158
    Yes, this is exactly what I am doing as well. It seems that there is still no built-in support for this, I have been evaluating other solutions (Both my own solution, and various options from the asset store) but it doesn't look like anything fully supports this feature.
     
  13. Marcos-Elias

    Marcos-Elias

    Joined:
    Nov 1, 2014
    Posts:
    93
    This is bad... It's really hard making large real world-sized projects with Unity due to these limitations with its native features. Something amazing that could not be used... I'm trying to use them for pedestrians on a city, to put lots of them walking in random directions... In static scenes it works like a charm.

    I hope that it will get fixed in a future release, this is a must for many projects.

    If you find a good 3rd party dynamic navmesh that works with Floating Origin please let me know, I'm afraid of buying some on the Asset Store because I don't know if they rely on global coordinates too (this research will take some weeks).
     
  14. christougher

    christougher

    Joined:
    Mar 6, 2015
    Posts:
    418
  15. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    158
    christougher, you won't believe this, but that was actually me that wrote that thread! Look at the logo, it's the same!

    Marcos, you're right, it would be awesome if Unity added translation/rotation ability to the standard navmesh, but from what I read, this would require huge changes to the actual API that the navmesh uses, and I suppose not enough people would use the new features for it to be justified.

    I don't know if unity 2018.1 has any navmesh improvements, I haven't tried the beta yet.

    The A* pathfinding project, as chris said, seems like it *might* fit the bill, I also tried out NavAI, which seems to work:
    https://assetstore.unity.com/packages/tools/ai/navai-103960

    However it doesn't seem to be maintained anymore, which is a big disappointment, because it showed promise.
     
    Marcos-Elias likes this.
  16. GameDevCouple_I

    GameDevCouple_I

    Joined:
    Oct 5, 2013
    Posts:
    2,134
    Did you manage to get this working, either using the A* pathfinding project or not? Wondering if it is worth me buying it or writing own A* for this. Need to know if it is fit for purpose (150+ moving units on platform)
     
    Marcos-Elias likes this.
  17. GameDevCouple_I

    GameDevCouple_I

    Joined:
    Oct 5, 2013
    Posts:
    2,134
    @Jakob_Unity Would one way to implement this ourselves be to have navmesh baked at origin, and then convert from local to world space position of the rendered components? This would allow say a moving pirate ship with pathfinding on it, while underneath what is actually happening is graph is not moving.

    Asking because not being able to do pathfinding on moving surfaces is a very very big issue for me and I need some, any way, around it! So happy to try anything no matter how hacky
     
  18. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    158
    Daemonhahn, I haven't purchased the A* pathfinding project yet, so I don't know if it would work. However the developer of the A* pathfinding project did say that your suggestion is basically what his project does for moving/rotating platforms: IE, translate everything to the origin and back. So that seems like it could work, but it strikes me as a suboptimal solution.
     
  19. christougher

    christougher

    Joined:
    Mar 6, 2015
    Posts:
    418
    Here is a quick video of the included local space demo (scene 13 from A* PP)...



    and here is the same scene modded with 196 agents with the local avoidance added even. Multithreading enabled for both the A* and RVO avoidance running about 45-60fps



    at a couple of points when the boat rotates as it turns the agents seem to get pushed to one side of the boat but that only happens with the avoidance enabled and that could probably be addressed as well... Either way this seems to have the functionality you're after...

    also Jakob_Unity hasn't been sighted in months... :(
     
    Last edited: May 10, 2018
  20. GameDevCouple_I

    GameDevCouple_I

    Joined:
    Oct 5, 2013
    Posts:
    2,134
    This must be possible using in built navmesh!

    I will try this weekend. I am thinking just using the navmesh for queries and doing my own avoidance and movement. Will post back with findings
     
  21. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    158
    christougher, those videos do seem to indicate that this functionality is possible with A* PP, that's good to know!

    Although, it would be interesting to see if this can be done with unity's built in nav mesh too, I look forward to seeing what Daemonhahn comes up with!
     
  22. GameDevCouple_I

    GameDevCouple_I

    Joined:
    Oct 5, 2013
    Posts:
    2,134
    I mean what I have works currently, but it is not very optimised. Ill rewrite it over the weekend and stick it on a github so you can test it next week. Right now I can handle around 100-200 agents moving with physics on platform, but with optimisations could easily be 10x that as nothing is threaded/jobified etc right now

    @PhoenixAdvanced another very easy idea I just had would be to use a ParentConstraint to dynamically link the objects to the moving mesh they are on. So you would do navigation on a static mesh, and then use that to move the agents that are actually on moving mesh (with each one having a parent constraint). This would mean it gets offset by the amount of movement the ground moves (space ship)
     
  23. GameDevCouple_I

    GameDevCouple_I

    Joined:
    Oct 5, 2013
    Posts:
    2,134
  24. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    158
    A parent constraint, that is a very good idea! I had never even heard of that feature, I will certainly do some reading on it.

    How would that work exactly?
     
  25. Niels40

    Niels40

    Joined:
    Nov 6, 2017
    Posts:
    20

    I dont really want to necro this thread but i have been looking for this so long. May i ask how you fixed the issue? Its quite a while ago so idk if you are still working on it but i would love to find out more.

    Did you end up using the parentconstraint @GameDevCouple_I ? Or did you use your own custom agent in the end?
     
    Last edited: Oct 19, 2018
  26. GameDevCouple_I

    GameDevCouple_I

    Joined:
    Oct 5, 2013
    Posts:
    2,134
    Ended up making a custom solution. Basically did this from my earlier post:

    "Would one way to implement this ourselves be to have navmesh baked at origin, and then convert from local to world space position of the rendered components? This would allow say a moving pirate ship with pathfinding on it, while underneath what is actually happening is graph is not moving."

    Its basically same as what the A* pathfinding project does underneath to do this sort of thing
     
  27. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    158
    I was using a custom soluton too, with A*, but I am now experimenting with another solution. What I am doing it keeping the Spaceship (in my case) static, and rotating and moving the world. So when the ship turns left, every object in the world, including the starbox, etc, turns to the right.
    This actually works much better than I thought it would, it feels seamless, and it allows me to use unity's built in navigation. It should also allow me to use things like baked lighting, since the ship is now a static object.
    I can also have the "ship" moving at very high speeds without causing any "jitter" or any bugs with the player or AI movement, since the ship is always static, and only the world moves.

    When the player leaves the ship, in a shuttle, etc, I just go back to regular movement.

    This might not work for all solutions, but it seems to work ok for my purposes.
     
  28. Niels40

    Niels40

    Joined:
    Nov 6, 2017
    Posts:
    20
    Hmm yea i think that is the best option. Downside is there is not alot to found about such a solution. I am using a pirate ship myself aswell and was hoping you could share your custom code so i can see how it is done. Is this possible or would you prefer to keep it private?

    Thx for your help btw @GameDevCouple_I . really appreciate it since i have been stumbling on this issue for quite some time now
     
  29. GameDevCouple_I

    GameDevCouple_I

    Joined:
    Oct 5, 2013
    Posts:
    2,134
    I cant send that exact code as its under NDA but I can look at writing you up an example at the weekend, PM me to remind me!
     
    Cereal_Killa and Niels40 like this.
  30. Niels40

    Niels40

    Joined:
    Nov 6, 2017
    Posts:
    20
    oh wow that would be so nice!!!!! you dont know how amazing this is! Thx alot, srsly.

    Will send the pm aswell
     
  31. Niels40

    Niels40

    Joined:
    Nov 6, 2017
    Posts:
    20
    I tried to send the pm but it seems like you have personal messages disabled. this intended?
     
    Last edited: Oct 19, 2018
  32. GameDevCouple_I

    GameDevCouple_I

    Joined:
    Oct 5, 2013
    Posts:
    2,134
    No it is not! ill sort that out now!
     
  33. GameDevCouple_I

    GameDevCouple_I

    Joined:
    Oct 5, 2013
    Posts:
    2,134
    You should be able to now :)
     
  34. GameDevCouple_I

    GameDevCouple_I

    Joined:
    Oct 5, 2013
    Posts:
    2,134
    I’ve decided due to the interest that I will write a job system optimised version of this for everyone this weekend and put it on GitHub, I’ll update here with a link when done :)

    EDIT: I didn’t get round to this yet as the new visual effect graph came out and I spent all weekend playing around with that :( sorry!
     
    Last edited: Oct 29, 2018
    zIyaGtVm and christougher like this.
  35. Niels40

    Niels40

    Joined:
    Nov 6, 2017
    Posts:
    20
    No worries! Your help is greatly appreciated so take your time :).
     
  36. Niels40

    Niels40

    Joined:
    Nov 6, 2017
    Posts:
    20
    @gamedevcoup i completely forgot to ask you last weekend (And you probably forgot it yourself aswell).

    Have you had any time this weekend to take a look at AI navmesh surface?
     
  37. GameDevCouple_I

    GameDevCouple_I

    Joined:
    Oct 5, 2013
    Posts:
    2,134
    Unfortunately I have not, we have a deadline in 2 weeks which is making it hard to get any free time!

    That said, this is the basics of what you want:

    Code (CSharp):
    1. public GameObject target;
    2. public Vector3 startPosTarget;
    3. public Vector3 startPosObj;
    4. public Vector3 difference;
    5. void Start()
    6. {
    7.      startPosTarget = target.transform.position;
    8.      startPosObj = this.transform.position;
    9. }
    10. void LateUpdate () {
    11.      difference = target.transform.position - startPosTarget;
    12.      this.transform.position = startPosObj + difference;
    13. }
    The idea being you are essentially recreating the parent-child like behaviour that you get in transform component, except you want an offset.

    So you want to position your "real" world at somwhere like 100,100,100. And your navmesh and agents at 0,0,0. Then you start it up and the models will offset based on the linked agent.

    Except what I was going to do was actually perform world to local space transformation and back using https://docs.unity3d.com/ScriptReference/Transform.TransformPoint.html and https://docs.unity3d.com/ScriptReference/Transform.InverseTransformPoint.html which I believe would be better for performance as you could perform this translation once and then cache the resulting matrix and use for ALL the offset calculations.

    And then finally, job this all up or have a compute shader perform the calculations, essentially the more parralel we could make this the faster it will be.

    Unfortunately it does not look like I will get time to make this, but hopefully this should give you what you need. The performance extras I mention at the end are not ncessary to get this working, and the provided code should get the general idea working so you can at least have a moving navmesh (seemingly moving, remember the trick is it is actually static and you use the movement on agents to move a visual agent elsewhere).
     
    PhoenixAdvanced and Niels40 like this.
  38. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    158
    Hi, I know this is an old post, but I don't suppose you had a chance to update the code that you wrote? I would still be very interested in reading about how you did it, I'm not 100% sure myself.
     
  39. Vincent13122

    Vincent13122

    Joined:
    Oct 26, 2014
    Posts:
    46