void AddEdgeCollider2Ds(Transform parent) { // find all valid colliders, add them to projection var colliders = GameObject.FindObjectsOfType <EdgeCollider2D>(); var filtered = colliders.Where(co => IsValidCollider(co)).ToList(); foreach (var collider in filtered) { // 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.ScaleFromEdgeCollider2D(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>()); // create mesh from edgecollider2D by stepping through each point // and creating a triangle with point, point-1 and point-1 with y=1 List <Vector3> vertices = new List <Vector3>(); List <int> indices = new List <int>(); // start at 2nd point so we can use the first one in our triangle, for (int i = 1; i < collider.points.Length; ++i) { Vector2 a2D = collider.points[i - 1]; Vector2 b2D = collider.points[i]; // convert to 3D // point A // point B // point C := A with y+1 Vector3 a3D = new Vector3(a2D.x, 0, a2D.y); Vector3 b3D = new Vector3(b2D.x, 0, b2D.y); Vector3 c3D = new Vector3(a2D.x, 1, a2D.y); // add 3 vertices vertices.Add(a3D); vertices.Add(b3D); vertices.Add(c3D); // add last 3 vertices as indices indices.Add(vertices.Count - 1); indices.Add(vertices.Count - 2); indices.Add(vertices.Count - 3); } // create mesh var mesh = new Mesh(); mesh.vertices = vertices.ToArray(); mesh.triangles = indices.ToArray(); //mesh.RecalculateNormals(); mesh.RecalculateBounds(); // assign it to the mesh filter go.GetComponent <MeshFilter>().sharedMesh = mesh; MakeUnwalkable(go); } }