using UnityEngine; using SuperTiled2Unity.Editor.Geometry; namespace SuperTiled2Unity.Editor { public static class CollisionObjectExtensions { public static void AddCollider(this CollisionObject collision, SuperTile tile, GameObject goParent, SuperImportContext importContext) { var go = new GameObject(collision.m_ObjectName); if (collision.CollisionShapeType == CollisionShapeType.Polygon) { AddPolygonCollider(go, collision, tile, importContext); } else if (collision.CollisionShapeType == CollisionShapeType.Polyline) { AddEdgeCollider(go, collision, tile, importContext); } else if (collision.CollisionShapeType == CollisionShapeType.Ellipse) { AddEllipseCollider(go, collision, tile, importContext); } else if (collision.CollisionShapeType == CollisionShapeType.Rectangle) { AddBoxCollider(go, collision, tile, importContext); } else if (collision.CollisionShapeType == CollisionShapeType.Point) { AddPointCollider(go, collision, importContext); } // Additional settings on the collider that was just added var addedCollider = go.GetComponent(); if (addedCollider != null) { addedCollider.isTrigger = importContext.GetIsTriggerOverridable(collision.m_IsTrigger); addedCollider.gameObject.layer = LayerMask.NameToLayer(collision.m_PhysicsLayer); } goParent.AddChildWithUniqueName(go); } private static void AddPolygonCollider(GameObject go, CollisionObject collision, SuperTile tile, SuperImportContext importContext) { // Note that polygons may need to be decomposed into convex parts var points = importContext.MakePointsPPU(collision.Points); // Triangulate the polygon points var triangulator = new Triangulator(); var triangles = triangulator.TriangulatePolygon(points); // Gather triangles into a collection of convex polygons var composition = new ComposeConvexPolygons(); var convexPolygons = composition.Compose(triangles); PolygonUtils.AddCompositePolygonCollider(go, convexPolygons, importContext); } private static void AddEdgeCollider(GameObject go, CollisionObject collision, SuperTile tile, SuperImportContext importContext) { var edge = go.AddComponent(); edge.points = importContext.MakePointsPPU(collision.Points); go.AddComponent(); } private static void AddEllipseCollider(GameObject go, CollisionObject collision, SuperTile tile, SuperImportContext importContext) { // Add a circle collider if width == height. Otherwise, we have to use am approximate polygon representation. if (collision.m_Size.x == collision.m_Size.y) { var cirlce = go.AddComponent(); cirlce.offset = importContext.MakePointPPU(collision.m_Size.x, -collision.m_Size.y) * 0.5f; cirlce.radius = importContext.MakeScalar(collision.m_Size.x) * 0.5f; var xpos = importContext.MakeScalar(collision.m_Position.x); var ypos = importContext.MakeScalar(collision.m_Position.y); go.transform.localPosition = new Vector3(xpos, ypos); go.transform.localEulerAngles = new Vector3(0, 0, importContext.MakeRotation(collision.m_Rotation)); go.AddComponent(); } else { AddPolygonCollider(go, collision, tile, importContext); } } private static void AddBoxCollider(GameObject go, CollisionObject collision, SuperTile tile, SuperImportContext importContext) { var box = go.AddComponent(); box.offset = importContext.MakePointPPU(collision.m_Size.x, -collision.m_Size.y) * 0.5f; box.size = importContext.MakeSize(collision.m_Size); var xpos = importContext.MakeScalar(collision.m_Position.x); var ypos = importContext.MakeScalar(collision.m_Position.y); go.transform.localPosition = new Vector3(xpos, ypos); go.transform.localEulerAngles = new Vector3(0, 0, importContext.MakeRotation(collision.m_Rotation)); go.AddComponent(); } private static void AddPointCollider(GameObject go, CollisionObject collision, SuperImportContext importContext) { var xpos = importContext.MakeScalar(collision.m_Position.x); var ypos = importContext.MakeScalar(collision.m_Position.y); go.transform.localPosition = new Vector3(xpos, ypos); go.transform.localEulerAngles = new Vector3(0, 0, importContext.MakeRotation(collision.m_Rotation)); go.AddComponent(); } } }