evershade/Packages/super-tiled2unity.v2.2.0/Editor/Extensions/CollisionObjectExtensions.cs

117 lines
5.1 KiB
C#

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<Collider2D>();
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<EdgeCollider2D>();
edge.points = importContext.MakePointsPPU(collision.Points);
go.AddComponent<SuperColliderComponent>();
}
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<CircleCollider2D>();
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<SuperColliderComponent>();
}
else
{
AddPolygonCollider(go, collision, tile, importContext);
}
}
private static void AddBoxCollider(GameObject go, CollisionObject collision, SuperTile tile, SuperImportContext importContext)
{
var box = go.AddComponent<BoxCollider2D>();
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<SuperColliderComponent>();
}
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<SuperColliderComponent>();
}
}
}