void AddPolygonCollider2Ds(Transform parent) { // find all valid colliders, add them to projection var colliders = GameObject.FindObjectsOfType <PolygonCollider2D>(); var filtered = colliders.Where(co => IsValidCollider(co)).ToList(); foreach (var collider in filtered) { for (int i = 0; i < collider.pathCount; i++) { // note: creating a primitive is necessary in order for it to bake properly var go = GameObject.CreatePrimitive(PrimitiveType.Cube); go.isStatic = true; go.transform.parent = parent; // position via offset and transformpoint var localPos = new Vector3(collider.offset.x, collider.offset.y, 0); var worldPos = collider.transform.TransformPoint(localPos); go.transform.position = new Vector3(worldPos.x, 0, worldPos.y); // scale depending on scale * collider size (circle=radius/box=size/...) go.transform.localScale = NavMeshUtils2D.ScaleFromPolygonCollider2D(collider); // rotation go.transform.rotation = Quaternion.Euler(NavMeshUtils2D.RotationTo3D(collider.transform.eulerAngles)); // remove box collider. note that baking uses the meshfilter, so // the collider doesn't really matter anyway. DestroyImmediate(go.GetComponent <BoxCollider>()); // Use the triangulator to get indices for creating triangles int[] indices = Triangulation.Triangulate(collider.GetPath(i).ToList()).ToArray(); // convert vector2 points to vector3 vertices var vertices = collider.GetPath(i).Select(p => new Vector3(p.x, 0, p.y)).ToList(); // create mesh var mesh = new Mesh(); mesh.vertices = vertices.ToArray(); mesh.triangles = indices; //mesh.RecalculateNormals(); mesh.RecalculateBounds(); // assign it to the mesh filter go.GetComponent <MeshFilter>().sharedMesh = mesh; MakeUnwalkable(go); } } }