using System.Linq; using UnityEngine; using System.Collections; public static class Matrix4x4Extension { public static Vector3 Scale(this Matrix4x4 m) { return new Vector3(((Vector3)m.GetColumn(0)).magnitude, ((Vector3)m.GetColumn(1)).magnitude, ((Vector3)m.GetColumn(2)).magnitude); } } public static class Collider2DExtension { public static Vector2 ClosestPointOnBounds(this Collider2D collider, Vector2 point) { if (collider is CircleCollider2D) { var circle = collider as CircleCollider2D; var mat = circle.gameObject.transform.localToWorldMatrix; var scale = mat.Scale(); var radiusScale = Mathf.Max(scale.x, scale.y); var radius = circle.radius*radiusScale; var circlePos = (Vector2)circle.gameObject.transform.position + circle.offset; return (point - circlePos).normalized * radius + (Vector2)collider.transform.position; }else if (collider is BoxCollider2D) { var box = collider as BoxCollider2D; float hw = box.size.x * 0.5f; float hh = box.size.y * 0.5f; Vector3[] corners = new Vector3[4] { new Vector3(-hw, hh, 0), new Vector3(hw, hh, 0), new Vector3(hw, -hh, 0), new Vector3(-hw, -hh, 0) }; Color[] c = new Color[4]{Color.red, Color.green, Color.blue, Color.white}; for (int i = 0; i < 4; ++i) { corners[i] = collider.transform.TransformPoint(corners[i]) + new Vector3(box.offset.x, box.offset.y, 0); corners[i].z = 0; } Vector2[] points = new Vector2[4]; for (int i = 0; i < 4; ++i) { var p0 = corners[i]; var p1 = corners[(i + 1) % 4]; var pt = AdvancedMath.SegmentNearestPoint(p0, p1, (Vector3)point); points[i] = pt; } return points.OrderBy(v => (point - v).magnitude).First(); } return Vector3.zero; } }