ExtendRealityLtd / VRTK

An example of how to use the Tilia packages to create great content with VRTK v4.
https://www.vrtk.io/
MIT License
3.69k stars 1k forks source link

033_CameraRig_TeleportingInNavMesh Teleportable areas not consistent with the generated NavMesh #1555

Closed Samahu closed 6 years ago

Samahu commented 6 years ago

Precheck

Environment

Steps to reproduce

Run example 033 of VRTK: https://github.com/thestonefox/VRTK/blob/master/Assets/VRTK/Examples/033_CameraRig_TeleportingInNavMesh.unity Show navigation map editor: Window > Navigation, Unity editor will show a blue overlay indicating the generated navigation mesh. Feel free to clear and re-bake the NavMesh

Expected behavior

Run the scene 033 and put on your headset, the teleport pointer changes between green and red indicating that the area is accessible/teleportable or not as it looks up this information from the calculated NavMesh. The red/green colors of the teleport pointer should match the generated NavMesh shown in Unity editor.

Current behavior

The teleport pointer indicator changes between green (teleportable) and red (non-teleportable) in a way that doesn't match the generated NavMesh. It may seem to match for half of the time but it doesn't actually. You should try couple different places when the surface is flat and accessible according to NavMesh but the pointer would render as red.

Note 1: This is not because of the location are slope like or near an edge, this was tested on a flat surface of the terrain and the NavMesh overlay displayed it with blue color indicating it 'Walkable'. Note 2: I did verify that there was nothing wrong with the generated NavMesh by adding a NavMesh Test Agent. The NavMesh Test Agent would use walkable routes and avoid non-walkables (takes re-routes) as highlighted by generated NavMesh. Note 3: The problem seem to occur only when you have a terrain and some other static objects as in the example scene. If you have only terrain and then do the test, the (Teleport + NavMesh) seem to work fine.

bddckr commented 6 years ago

Not sure, but maybe the teleporting stuff takes the play area (and your physical position inside of it) into account?

Samahu commented 6 years ago

I did track the code responsible for querying NavMesh

Basically the method ValidDestination found in file:

https://github.com/thestonefox/VRTK/blob/master/Assets/VRTK/Scripts/Pointers/PointerRenderers/VRTK_BasePointerRenderer.cs

checks for a single point as follows:

protected virtual bool ValidDestination() 
{ 
    bool validNavMeshLocation = false; 
    if (destinationHit.transform != null) 
    { 
        NavMeshHit hit; 
        validNavMeshLocation = NavMesh.SamplePosition(destinationHit.point, out hit,  navMeshCheckDistance, NavMesh.AllAreas); 
    } 
    if (navMeshCheckDistance == 0f)  
    {  
        validNavMeshLocation = true;  
    } 
    return (validNavMeshLocation && destinationHit.collider != null && !(VRTK_PolicyList.Check(destinationHit.collider.gameObject, invalidListPolicy)));
}

So I am not sure how play area could affect the query.

Samahu commented 6 years ago

So after some experimentation, I found out that the NavMeshLimitDistance property of the VRTK_HeightAdjustTeleport (which controls the navMeshCheckDistance var within ValidDestination method) needs to have a value close to the agent radius.

Unity by default has an agent radius size of 0.5 when it bakes NavMesh, the example 033_CameraRig_TeleportingInNavMesh has a value of 0.1 for the NavMeshLimitDistance. If you change the value of NavMeshLimitDistance to 0.5 or 0.4 then the example works fine.

An alternative way that I have tested and gives good results too is to enable "Manual Voxel Size" when you bake NavMesh and set the value to smaller value (for example 0.05). This would increase the number of generated voxels and causes the NavMesh query to give correct values without changing NavMeshLimitDistance value. However, when you increase the number of generated voxels this would significantly increase build times.

I will close this issue.