防止和UnityEngine的PolygonCollider2D重名,所有类包裹在了我自己定义的名称空间
JimDevPack
中,名称空间的声明部分在文章代码中略去了。
定义PolygonCollider2D和基类
基类
public class Collider2D : MonoBehaviour {}
PolygonCollider2D
public class PolygonCollider2D : Collider2D
{public List<Vector2> points;// 绘制多边形的边private void OnDrawGizmos(){Gizmos.color = Color.green;if (points.Count > 1){for (int i = 0; i < points.Count - 1; i++){Gizmos.DrawLine(points[i], points[i + 1]);}Gizmos.DrawLine(points[points.Count - 1], points[0]);}}
}
Editor扩展
[CustomEditor(typeof(PolygonCollider2D))]
public class PolygonCollider2DEditor : Editor
{private PolygonCollider2D polygonCollider;private void OnEnable(){polygonCollider = (PolygonCollider2D)target;if (polygonCollider.points == null){polygonCollider.points = new List<Vector2>();}}public override void OnInspectorGUI(){base.OnInspectorGUI();if (GUILayout.Button("Add Point")){polygonCollider.points.Add(new Vector2());}}private void OnSceneGUI(){Event guiEvent = Event.current;// 如果按住ctrl并且点击了左键,会删除点击位置最近的点if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.control){float closestDistance = float.MaxValue;int closestIndex = -1;// 寻找最近的点for (int i = 0; i < polygonCollider.points.Count; i++){float distance = Vector2.Distance(polygonCollider.points[i], HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin);if (distance < closestDistance){closestDistance = distance;closestIndex = i;}}if (closestIndex != -1){Undo.RecordObject(polygonCollider, "Remove Point");polygonCollider.points.RemoveAt(closestIndex);guiEvent.Use();}}for (int i = 0; i < polygonCollider.points.Count; i++){Handles.color = new Color(0, 0, 1, 1f);EditorGUI.BeginChangeCheck();// 绘制一个可自由移动的HandleVector2 newTargetPosition = Handles.FreeMoveHandle(polygonCollider.points[i], Quaternion.identity, 0.03f, new Vector2(0.5f, 0.5f), Handles.DotHandleCap);if (EditorGUI.EndChangeCheck()){// 记录信息,为了响应撤销Undo.RecordObject(polygonCollider, "Move Point");// 赋值新位置polygonCollider.points[i] = newTargetPosition;}}}
}