News Forums Troubleshooting What does NavMeshRig.Awake() do? And can I do it incrementally using a yield?

Tagged: 

This topic contains 11 replies, has 3 voices, and was last updated by  GamesOfEdan 2 weeks, 5 days ago.

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • #26881

    GamesOfEdan
    Participant

    Hi all,

    I’m loading prefab terrains at runtime which include a navmesh (originally created in the editor at design-time). The NavMesh is doing something significant in the Awake() and creates a noticeable frame-rate stutter when the prefab is loaded into the engine.

    Is there any way I can initialise the NavMeshRig (at runtime) using a coroutine to stagger the initialisation over a number of frames and thus maintain an acceptable frame rate?

    Thanks in advance.
    Carmine.

    #26948

    CodersExpo
    Participant

    Well I believe the awake is called through the NavMeshRig component. So this would call the base RAINComponent Awake to deserialize the RAIN object. Then NavMeshRig initializes and registers the navigation graph with the Navigation.Instance.Register(graph).

    I recall discussing in this forum dynamically load navigation graphs and register them.

    I believe the impact is due to the serialization process. I’ve not tried to do what you’re doing here per se’ but this might get you headed in the right direction. If you have more questions or need more help to get a solution you can work with, I’ll try to help. We can always see what Rival Theory has to say by just emailing support too.

    BTW….
    I believe you can override the Awake method of the NavMeshRig too since it is public override.

    • This reply was modified 1 month ago by  CodersExpo.
    • This reply was modified 1 month ago by  CodersExpo.
    • This reply was modified 1 month ago by  CodersExpo.
    #27029

    GamesOfEdan
    Participant

    Thanks,

    In my initial tests, I noticed that if I broke the NavMesh into smaller (overlapping) pieces, loaded from a coroutine, I could stop the frame stutter. I haven’t quite completed these tests, but it agrees with your description that serialisation is creating a noticeable delay, for which I reduce when loading smaller nav-meshes.

    I’ll take a look at your link, thanks for that.

    I’ve tried overriding the Awake() functions with older versions of RAIN to change behaviour for other things, and it seemed to work ok. I would do the same here if there was some incremental load/serialisation function I could call manually to break it up over multiple frames. I’ll have to investigate the RAIN serialisation interfaces. Thanks again.

    • This reply was modified 1 month ago by  GamesOfEdan.
    #27031

    GamesOfEdan
    Participant

    Hi CodersExpo,

    I had already looked at, and tried, the example code in your linked forum post. But from what I can tell, it’s actually generating the nevmesh at runtime, rather than simply loading one in (that was previously created in the editor). So that created a significant frame-rate delay, plus it took a longer time.
    Basically I want to create the navmeshes in the editor at design-time, and load them in at run-time without any frame-rate stuttering.

    So I may need to investigate the RAIN serialisation lib & see if there’s any functions exposed that will aloow me to incrementally load the navmesh.

    Thanks.
    Carmine.

    #27039

    CodersExpo
    Participant

    hmmmm…I’m not sure this can be done. As I said above, when the application starts NavMeshRig components are initialized. I mean there is an Awake method that calls the base class serialization and registers the Navigation Mesh with the NavigationManager.Instance. It’s base class is an abstract RAINComponent that subclasses MonoBehavior.

    So, it appears to me that each one of the NavigationMesh Rig components is initialized with its own Awake method and registered separately when the application starts. I’m not sure how/if you can get in and toggle this.

    I could be wrong but I don’t believe we can dynamically load preexisting navigation mesh rig components in a controlled way. Although, I wonder if we create them and then disable them in the inspector. It doesn’t appear they load when inactive. I would have to inspect the NavigationManager to see for sure.

    If this is the case, then perhaps you can create your navigation mesh rig assets and set the component to inactive in the inspector. Then when that application starts you find the game object and set its active status to true. Then register it with the NavigationManager. Try that. You might also email support and ask to be sure I’m correct in my analysis.

    #27040

    GamesOfEdan
    Participant

    I suspected that to be the case. Thanks for the suggestions.
    You see, I’m procedurally generating the world and loading/unloading sections as the player navigates through. This means that prefabs cannot all be loaded at the start.
    During my prototyping, I tried this technique using Waypoint networks and it worked ok. I’ve also loaded navmeshes in my “main world” on startup which works fine (since the delay is on startup). However, if I ever try to load a navmesh via a prefab instantiation, I’ll notice a loading stutter.

    So it seems that I might have to try waypoint networks or smaller overlapping navmeshes (as mentioned in my previous post).

    I must admit, it has been a while since I was last using RAIN nav components, so it took a while to refresh my memory

    Thanks for all your help. It’s very much appreciated.

    #27042

    CodersExpo
    Participant

    So I just tried creating a navigation mesh rig. Set up all the properties and made it into a prefab. Then deleted it from the scene. At runtime I have a custom script instantiate it..

    var instance = GameObject.Instantiate(Resources.Load(“MainMesh”, typeof(GameObject))) as GameObject;

    …and it works like a charm…of course my mesh was rather small. So you should be able to control how fast you load in the prefabs and I think you’re right, keeping them small will help a great deal to allow for faster loading. I personally feel its better anyway because I have greater control over each mesh settings and using graph tags.

    Now the only issue I can see is if you have to change properties and regenerate the mesh at runtime. That might not be possible but I sent an email asking the support team at RT.

    • This reply was modified 1 month ago by  CodersExpo.
    • This reply was modified 1 month ago by  CodersExpo.
    #27046

    GamesOfEdan
    Participant

    Thanks for your investigation. I agree that using smaller meshes and instantiating inside a coroutine (ie. incrementally loading over successive frames) does in fact reduce any visible frame stutter.

    However, here’s one gotcha I’ve noticed both with NavMesh & Waypoints Networks: They don’t account for any change in the gameObject’s transform. So if I instantiate a prefab with a navmesh/waypoint-network, and move it’s world location, the navmesh/waypoint-network remain at the original (design-time) position. This becomes a problem when I’m procedurally generating the world from pieces(prefabs) that are translated/rotated to different world locations at runtime.

    For a Waypoint-Network I guess I can iterate each waypoint and manually move them, but I don’t know if I can do something similar for a NavMesh. During my prototyping, I was using RAIN{Indie} and the waypoints did (from what I remember) observe the gameObject transform location.

    I’ll keep trying, thanks for all your help

    #27263

    CodersExpo
    Participant

    Yah, the main problem you will run into is if you try to move the NavMesh. The vertices are absolute so even if you position the prefab elsewhere the NavMesh will stay at its generated position. You can go through the vertices of the graph though and adjust them after instancing it I think. I would need to play around more with this and may very well try to once I get a little free time.

    #27283

    GamesOfEdan
    Participant

    Thanks for the confirmation.

    Moving waypoints via the WaypointSet works well.
    And Waypoint Networks serialise quickly.
    So I’ll carry on with a Waypoint Network solution.
    So far, so good.

    Thanks again.

    #28218

    prime
    Keymaster

    Awake causes the NavMeshRig to be deserialized. In the current version of RAIN this is a bit slow. We have an update (not yet released) that significantly speeds up the operation. Contact Jester (jester at rival theory dot com) if you want access for testing.

    #28235

    GamesOfEdan
    Participant

    Thanks Prime for the info.
    I gathered that the navmesh was being deserialised & originally wondered if there was any way I could distribute this process over multiple frames (eg coroutine) or thread, via the API, to eliminate the noticeable frame stutter.
    In any case, I’ve returned to using Waypoint Networks. I may approach/attempt this again in the future.

    Also, thanks for the email link.
    Much appreciated.

    Sincerely,
    Carmine.

Viewing 12 posts - 1 through 12 (of 12 total)

You must be logged in to reply to this topic.