Search Unity

NavMeshBuildSource for Physics Colliders

Discussion in 'Navigation' started by emrys90, Jul 8, 2017.

  1. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    489
    How do I build the struct for physics colliders? What I've tried so far is to match the struct similar to the results returned from NavMeshBuilder.CollectSources, but I have not been able to find out how to do the matrix transform for it. Here's what I've got so far.

    var s = new NavMeshBuildSource();
    s.area = 0;
    s.component = collider;

    if (collider is BoxCollider)
    {
    s.shape = NavMeshBuildSourceShape.Box;
    }
    else if (collider is CapsuleCollider)
    {
    s.shape = NavMeshBuildSourceShape.Capsule;
    }
    else if (collider is SphereCollider)
    {
    s.shape = NavMeshBuildSourceShape.Sphere;
    }
    else
    {
    throw new System.Exception("Unsupported collider type! " + collider);
    }

    s.size = collider.bounds.size;
    s.transform = collider.transform.localToWorldMatrix;

    The localToWorldMatrix is what the API shows to use for the mesh filters, but what it gives for colliders is different than what NavMeshBuilder.CollectSources returns, and it causes the nav mesh to not be built.
     
  2. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    489
    Also, even what is returned by NavMeshBuilder.CollectSources doesn't seem to take into account if the collider has a center position different than 0,0,0. Anything I can do about that?
     
  3. JohnTomorrow

    JohnTomorrow

    Joined:
    Apr 19, 2013
    Posts:
    100
    Maybe try this:

    Vector3 pos = transform.TransformPoint (collider.center);
    buildSource.transform.SetTRS (pos, collider.transform.rotation, collider.transform.localScale);
     
    Last edited: Aug 9, 2017
  4. JohnTomorrow

    JohnTomorrow

    Joined:
    Apr 19, 2013
    Posts:
    100
    This should work:

    Code (CSharp):
    1.     void GetBoxColliderBuildSources () {
    2.         BoxCollider[] colliders = GetComponentsInChildren<BoxCollider> ();
    3.         for (int i = 0; i < colliders.Length; i++) {
    4.             BoxCollider collider = colliders[i];
    5.             if ((colliderValidLayers.value & 1 << collider.gameObject.layer) != 1 << collider.gameObject.layer) continue;
    6.             if (collider.isTrigger) continue;
    7.  
    8.             var s = new NavMeshBuildSource ();
    9.             s.shape = NavMeshBuildSourceShape.Box;
    10.             s.component = collider;
    11.             var center = collider.transform.TransformPoint (collider.center);
    12.             var scale = collider.transform.lossyScale;
    13.             var size = new Vector3 (collider.size.x * Mathf.Abs (scale.x), collider.size.y * Mathf.Abs (scale.y), collider.size.z * Mathf.Abs (scale.z));
    14.             s.transform = Matrix4x4.TRS (center, collider.transform.rotation, Vector3.one);
    15.             s.size = size;
    16.             s.area = 0;
    17.             sources.Add (s);
    18.         }
    19.     }
     
  5. Q-ro

    Q-ro

    Joined:
    Feb 14, 2016
    Posts:
    10
    I know is an old post but i really need this code to work, just one thing is stopping me from actually doing so, what is "colliderValidLayers" ??
     
  6. JohnTomorrow

    JohnTomorrow

    Joined:
    Apr 19, 2013
    Posts:
    100
    Its a LayerMask. You can set it to the layers that you want to include as navmesh sources. You will need to declare it and set the values in the inspector.

    public LayerMask colliderValidLayers;