using System; using System.Collections.Generic; using UnityEditor.UIElements; using UnityEngine.UIElements; using UnityEngine; namespace UnityEditor.U2D.Sprites { internal abstract partial class SpriteFrameModuleBase : SpriteEditorModuleBase { protected enum GizmoMode { BorderEditing, RectEditing } protected class Styles { public readonly GUIStyle dragdot = "U2D.dragDot"; public readonly GUIStyle dragdotactive = "U2D.dragDotActive"; public readonly GUIStyle createRect = "U2D.createRect"; public readonly GUIStyle pivotdotactive = "U2D.pivotDotActive"; public readonly GUIStyle pivotdot = "U2D.pivotDot"; public readonly GUIStyle dragBorderdot = new GUIStyle(); public readonly GUIStyle dragBorderDotActive = new GUIStyle(); public readonly GUIStyle toolbar; public Styles() { toolbar = new GUIStyle(EditorStyles.inspectorBig); toolbar.margin.top = 0; toolbar.margin.bottom = 0; createRect.border = new RectOffset(3, 3, 3, 3); dragBorderdot.fixedHeight = 5f; dragBorderdot.fixedWidth = 5f; dragBorderdot.normal.background = EditorGUIUtility.whiteTexture; dragBorderDotActive.fixedHeight = dragBorderdot.fixedHeight; dragBorderDotActive.fixedWidth = dragBorderdot.fixedWidth; dragBorderDotActive.normal.background = EditorGUIUtility.whiteTexture; } } private static Styles s_Styles; protected static Styles styles { get { if (s_Styles == null) s_Styles = new Styles(); return s_Styles; } } private const float kInspectorWidth = 330f; private const float kInspectorHeight = 170; private const float kPivotFieldPrecision = 0.0001f; private float m_Zoom = 1.0f; private GizmoMode m_GizmoMode; private VisualElement m_NameElement; private TextField m_NameField; private VisualElement m_PositionElement; private IntegerField m_PositionFieldX; private IntegerField m_PositionFieldY; private IntegerField m_PositionFieldW; private IntegerField m_PositionFieldH; private IntegerField m_BorderFieldL; private IntegerField m_BorderFieldT; private IntegerField m_BorderFieldR; private IntegerField m_BorderFieldB; private EnumField m_PivotField; private EnumField m_PivotUnitModeField; private VisualElement m_CustomPivotElement; private FloatField m_CustomPivotFieldX; private FloatField m_CustomPivotFieldY; private VisualElement m_SelectedFrameInspector; private bool ShouldShowRectScaling() { return hasSelected && m_GizmoMode == GizmoMode.RectEditing; } private static Rect inspectorRect { get { return new Rect( 0, 0, kInspectorWidth, kInspectorHeight); } } private void RemoveMainUI(VisualElement mainView) { if (mainView.Contains(m_SelectedFrameInspector)) mainView.Remove(m_SelectedFrameInspector); mainView.UnregisterCallback(SelectionChange); } protected void UpdatePositionField(FocusOutEvent evt) { if (hasSelected) { m_PositionFieldX.SetValueWithoutNotify((int)selectedSpriteRect.x); m_PositionFieldY.SetValueWithoutNotify((int)selectedSpriteRect.y); m_PositionFieldW.SetValueWithoutNotify((int)selectedSpriteRect.width); m_PositionFieldH.SetValueWithoutNotify((int)selectedSpriteRect.height); } } private void UpdateBorderField(FocusOutEvent evt) { if (hasSelected) { m_BorderFieldL.SetValueWithoutNotify((int)selectedSpriteBorder.x); m_BorderFieldB.SetValueWithoutNotify((int)selectedSpriteBorder.y); m_BorderFieldR.SetValueWithoutNotify((int)selectedSpriteBorder.z); m_BorderFieldT.SetValueWithoutNotify((int)selectedSpriteBorder.w); } } void SetupIntegerField(IntegerField field, EventCallback onFocusOutEvent, EventCallback> onChangeEvent) { field.RegisterCallback(onFocusOutEvent); field.RegisterValueChangedCallback(onChangeEvent); } void SetDragFieldLimit(IntegerField field, int value) { // The only way to know if value change is due to dragger or text input var t = field.Q("unity-text-input"); if (!t.focusController.IsFocused(t)) { // Value changed due to drag. We set back the field so to show the drag limit field.SetValueWithoutNotify(value); } } void OnPositionIntXChange(ChangeEvent evt) { if (hasSelected) { var rect = selectedSpriteRect; rect.x = evt.newValue; selectedSpriteRect = rect; SetDragFieldLimit(m_PositionFieldX, (int)selectedSpriteRect.x); m_PositionFieldW.SetValueWithoutNotify((int)selectedSpriteRect.width); } } void OnPositionIntYChange(ChangeEvent evt) { if (hasSelected) { var rect = selectedSpriteRect; rect.y = evt.newValue; selectedSpriteRect = rect; SetDragFieldLimit(m_PositionFieldY, (int)selectedSpriteRect.y); m_PositionFieldH.SetValueWithoutNotify((int)selectedSpriteRect.height); } } void OnPositionIntWChange(ChangeEvent evt) { if (hasSelected) { var rect = selectedSpriteRect; rect.width = evt.newValue; selectedSpriteRect = rect; SetDragFieldLimit(m_PositionFieldW, (int)selectedSpriteRect.width); m_PositionFieldX.SetValueWithoutNotify((int)selectedSpriteRect.x); } } void OnPositionIntHChange(ChangeEvent evt) { if (hasSelected) { var rect = selectedSpriteRect; rect.height = evt.newValue; selectedSpriteRect = rect; SetDragFieldLimit(m_PositionFieldH, (int)selectedSpriteRect.height); m_PositionFieldY.SetValueWithoutNotify((int)selectedSpriteRect.y); } } void OnBorderIntLChange(ChangeEvent evt) { if (hasSelected) { var border = selectedSpriteBorder; border.x = evt.newValue; selectedSpriteBorder = border; SetDragFieldLimit(m_BorderFieldL, (int)selectedSpriteBorder.x); } } void OnBorderIntBChange(ChangeEvent evt) { if (hasSelected) { var border = selectedSpriteBorder; border.y = evt.newValue; selectedSpriteBorder = border; SetDragFieldLimit(m_BorderFieldB, (int)selectedSpriteBorder.y); } } void OnBorderIntRChange(ChangeEvent evt) { if (hasSelected) { var border = selectedSpriteBorder; border.z = (evt.newValue + border.x) <= selectedSpriteRect.width ? evt.newValue : selectedSpriteRect.width - border.x; selectedSpriteBorder = border; SetDragFieldLimit(m_BorderFieldR, (int)selectedSpriteBorder.z); } } void OnBorderIntTChange(ChangeEvent evt) { if (hasSelected) { var border = selectedSpriteBorder; border.w = (evt.newValue + border.y) <= selectedSpriteRect.height ? evt.newValue : selectedSpriteRect.height - border.y; selectedSpriteBorder = border; SetDragFieldLimit(m_BorderFieldT, (int)selectedSpriteBorder.w); } } private void AddMainUI(VisualElement mainView) { var visualTree = AssetDatabase.LoadAssetAtPath("Packages/com.unity.2d.sprite/Editor/UI/SpriteEditor/SpriteFrameModuleInspector.uxml") as VisualTreeAsset; m_SelectedFrameInspector = visualTree.CloneTree().Q("spriteFrameModuleInspector"); m_NameElement = m_SelectedFrameInspector.Q("name"); m_NameField = m_SelectedFrameInspector.Q("spriteName"); m_NameField.RegisterValueChangedCallback((evt) => { if (hasSelected) { selectedSpriteName = evt.newValue; } }); m_NameField.RegisterCallback((focus) => { if (hasSelected) { m_NameField.SetValueWithoutNotify(selectedSpriteName); } }); m_PositionElement = m_SelectedFrameInspector.Q("position"); m_PositionFieldX = m_PositionElement.Q("positionX"); SetupIntegerField(m_PositionFieldX, UpdatePositionField, OnPositionIntXChange); m_PositionFieldY = m_PositionElement.Q("positionY"); SetupIntegerField(m_PositionFieldY, UpdatePositionField, OnPositionIntYChange); m_PositionFieldW = m_PositionElement.Q("positionW"); SetupIntegerField(m_PositionFieldW, UpdatePositionField, OnPositionIntWChange); m_PositionFieldH = m_PositionElement.Q("positionH"); SetupIntegerField(m_PositionFieldH, UpdatePositionField, OnPositionIntHChange); var borderElement = m_SelectedFrameInspector.Q("border"); m_BorderFieldL = borderElement.Q("borderL"); SetupIntegerField(m_BorderFieldL, UpdateBorderField, OnBorderIntLChange); m_BorderFieldT = borderElement.Q("borderT"); SetupIntegerField(m_BorderFieldT, UpdateBorderField, OnBorderIntTChange); m_BorderFieldR = borderElement.Q("borderR"); SetupIntegerField(m_BorderFieldR, UpdateBorderField, OnBorderIntRChange); m_BorderFieldB = borderElement.Q("borderB"); SetupIntegerField(m_BorderFieldB, UpdateBorderField, OnBorderIntBChange); m_PivotField = m_SelectedFrameInspector.Q("pivotField"); m_PivotField.Init(SpriteAlignment.Center); m_PivotField.label = L10n.Tr("Pivot"); m_PivotField.RegisterValueChangedCallback((evt) => { if (hasSelected) { SpriteAlignment alignment = (SpriteAlignment)evt.newValue; SetSpritePivotAndAlignment(selectedSpritePivot, alignment); m_CustomPivotElement.SetEnabled(selectedSpriteAlignment == SpriteAlignment.Custom); Vector2 pivot = selectedSpritePivotInCurUnitMode; m_CustomPivotFieldX.SetValueWithoutNotify(pivot.x); m_CustomPivotFieldY.SetValueWithoutNotify(pivot.y); } }); m_PivotUnitModeField = m_SelectedFrameInspector.Q("pivotUnitModeField"); m_PivotUnitModeField.Init(PivotUnitMode.Normalized); m_PivotUnitModeField.label = L10n.Tr("Pivot Unit Mode"); m_PivotUnitModeField.RegisterValueChangedCallback((evt) => { if (hasSelected) { pivotUnitMode = (PivotUnitMode)evt.newValue; Vector2 pivot = selectedSpritePivotInCurUnitMode; m_CustomPivotFieldX.SetValueWithoutNotify(pivot.x); m_CustomPivotFieldY.SetValueWithoutNotify(pivot.y); } }); m_CustomPivotElement = m_SelectedFrameInspector.Q("customPivot"); m_CustomPivotFieldX = m_CustomPivotElement.Q("customPivotX"); m_CustomPivotFieldX.RegisterValueChangedCallback((evt) => { if (hasSelected) { float newValue = (float)evt.newValue; float pivotX = pivotUnitMode == PivotUnitMode.Pixels ? ConvertFromRectToNormalizedSpace(new Vector2(newValue, 0.0f), selectedSpriteRect).x : newValue; var pivot = selectedSpritePivot; pivot.x = pivotX; SetSpritePivotAndAlignment(pivot, selectedSpriteAlignment); } }); m_CustomPivotFieldY = m_CustomPivotElement.Q("customPivotY"); m_CustomPivotFieldY.RegisterValueChangedCallback((evt) => { if (hasSelected) { float newValue = (float)evt.newValue; float pivotY = pivotUnitMode == PivotUnitMode.Pixels ? ConvertFromRectToNormalizedSpace(new Vector2(0.0f, newValue), selectedSpriteRect).y : newValue; var pivot = selectedSpritePivot; pivot.y = pivotY; SetSpritePivotAndAlignment(pivot, selectedSpriteAlignment); } }); //// Force an update of all the fields. PopulateSpriteFrameInspectorField(); mainView.RegisterCallback(SelectionChange); // Stop mouse events from reaching the main view. m_SelectedFrameInspector.pickingMode = PickingMode.Ignore; m_SelectedFrameInspector.RegisterCallback((e) => { e.StopPropagation(); }); m_SelectedFrameInspector.RegisterCallback((e) => { e.StopPropagation(); }); m_SelectedFrameInspector.AddToClassList("moduleWindow"); m_SelectedFrameInspector.AddToClassList("bottomRightFloating"); mainView.Add(m_SelectedFrameInspector); } private void SelectionChange(SpriteSelectionChangeEvent evt) { m_SelectedFrameInspector.style.display = hasSelected ? DisplayStyle.Flex : DisplayStyle.None; PopulateSpriteFrameInspectorField(); } private void UIUndoCallback() { PopulateSpriteFrameInspectorField(); } protected void PopulateSpriteFrameInspectorField() { m_SelectedFrameInspector.style.display = hasSelected ? DisplayStyle.Flex : DisplayStyle.None; if (!hasSelected) return; m_NameElement.SetEnabled(containsMultipleSprites); m_NameField.SetValueWithoutNotify(selectedSpriteName); m_PositionElement.SetEnabled(containsMultipleSprites); var spriteRect = selectedSpriteRect; m_PositionFieldX.SetValueWithoutNotify(Mathf.RoundToInt(spriteRect.x)); m_PositionFieldY.SetValueWithoutNotify(Mathf.RoundToInt(spriteRect.y)); m_PositionFieldW.SetValueWithoutNotify(Mathf.RoundToInt(spriteRect.width)); m_PositionFieldH.SetValueWithoutNotify(Mathf.RoundToInt(spriteRect.height)); var spriteBorder = selectedSpriteBorder; m_BorderFieldL.SetValueWithoutNotify(Mathf.RoundToInt(spriteBorder.x)); m_BorderFieldT.SetValueWithoutNotify(Mathf.RoundToInt(spriteBorder.w)); m_BorderFieldR.SetValueWithoutNotify(Mathf.RoundToInt(spriteBorder.z)); m_BorderFieldB.SetValueWithoutNotify(Mathf.RoundToInt(spriteBorder.y)); m_PivotField.SetValueWithoutNotify(selectedSpriteAlignment); m_PivotUnitModeField.SetValueWithoutNotify(pivotUnitMode); Vector2 pivot = selectedSpritePivotInCurUnitMode; m_CustomPivotFieldX.SetValueWithoutNotify(pivot.x); m_CustomPivotFieldY.SetValueWithoutNotify(pivot.y); m_CustomPivotElement.SetEnabled(hasSelected && selectedSpriteAlignment == SpriteAlignment.Custom); } private static Vector2 ApplySpriteAlignmentToPivot(Vector2 pivot, Rect rect, SpriteAlignment alignment) { if (alignment != SpriteAlignment.Custom) { Vector2[] snapPoints = GetSnapPointsArray(rect); Vector2 texturePos = snapPoints[(int)alignment]; return ConvertFromTextureToNormalizedSpace(texturePos, rect); } return pivot; } private static Vector2 ConvertFromTextureToNormalizedSpace(Vector2 texturePos, Rect rect) { return new Vector2((texturePos.x - rect.xMin) / rect.width, (texturePos.y - rect.yMin) / rect.height); } private static Vector2 ConvertFromNormalizedToRectSpace(Vector2 normalizedPos, Rect rect) { Vector2 rectPos = new Vector2(rect.width * normalizedPos.x, rect.height * normalizedPos.y); // This is to combat the lack of precision formating on the UI controls. rectPos.x = Mathf.Round(rectPos.x / kPivotFieldPrecision) * kPivotFieldPrecision; rectPos.y = Mathf.Round(rectPos.y / kPivotFieldPrecision) * kPivotFieldPrecision; return rectPos; } private static Vector2 ConvertFromRectToNormalizedSpace(Vector2 rectPos, Rect rect) { return new Vector2(rectPos.x / rect.width, rectPos.y / rect.height); } private static Vector2[] GetSnapPointsArray(Rect rect) { Vector2[] snapPoints = new Vector2[9]; snapPoints[(int)SpriteAlignment.TopLeft] = new Vector2(rect.xMin, rect.yMax); snapPoints[(int)SpriteAlignment.TopCenter] = new Vector2(rect.center.x, rect.yMax); snapPoints[(int)SpriteAlignment.TopRight] = new Vector2(rect.xMax, rect.yMax); snapPoints[(int)SpriteAlignment.LeftCenter] = new Vector2(rect.xMin, rect.center.y); snapPoints[(int)SpriteAlignment.Center] = new Vector2(rect.center.x, rect.center.y); snapPoints[(int)SpriteAlignment.RightCenter] = new Vector2(rect.xMax, rect.center.y); snapPoints[(int)SpriteAlignment.BottomLeft] = new Vector2(rect.xMin, rect.yMin); snapPoints[(int)SpriteAlignment.BottomCenter] = new Vector2(rect.center.x, rect.yMin); snapPoints[(int)SpriteAlignment.BottomRight] = new Vector2(rect.xMax, rect.yMin); return snapPoints; } protected void Repaint() { spriteEditor.RequestRepaint(); } protected void HandleGizmoMode() { GizmoMode oldGizmoMode = m_GizmoMode; var evt = eventSystem.current; if (evt.control) m_GizmoMode = GizmoMode.BorderEditing; else m_GizmoMode = GizmoMode.RectEditing; if (oldGizmoMode != m_GizmoMode && (evt.type == EventType.KeyDown || evt.type == EventType.KeyUp) && (evt.keyCode == KeyCode.LeftControl || evt.keyCode == KeyCode.RightControl || evt.keyCode == KeyCode.LeftAlt || evt.keyCode == KeyCode.RightAlt)) Repaint(); } protected bool MouseOnTopOfInspector() { if (hasSelected == false) return false; var point = GUIClip.Unclip(eventSystem.current.mousePosition); point = m_SelectedFrameInspector.parent.LocalToWorld(point); var selectedElement = m_SelectedFrameInspector.panel.Pick(point); if (selectedElement != null && selectedElement.pickingMode != PickingMode.Ignore && selectedElement.FindCommonAncestor(m_SelectedFrameInspector) == m_SelectedFrameInspector) return true; return false; } protected void HandlePivotHandle() { if (!hasSelected) return; EditorGUI.BeginChangeCheck(); SpriteAlignment alignment = selectedSpriteAlignment; Vector2 pivot = selectedSpritePivot; Rect rect = selectedSpriteRect; pivot = ApplySpriteAlignmentToPivot(pivot, rect, alignment); Vector2 pivotHandlePosition = SpriteEditorHandles.PivotSlider(rect, pivot, styles.pivotdot, styles.pivotdotactive); if (EditorGUI.EndChangeCheck()) { // Pivot snapping only happen when ctrl is press. Same as scene view snapping move if (eventSystem.current.control) SnapPivotToSnapPoints(pivotHandlePosition, out pivot, out alignment); else if (pivotUnitMode == PivotUnitMode.Pixels) SnapPivotToPixels(pivotHandlePosition, out pivot, out alignment); else { pivot = pivotHandlePosition; alignment = SpriteAlignment.Custom; } SetSpritePivotAndAlignment(pivot, alignment); PopulateSpriteFrameInspectorField(); } } protected void HandleBorderSidePointScalingSliders() { if (!hasSelected) return; GUIStyle dragDot = styles.dragBorderdot; GUIStyle dragDotActive = styles.dragBorderDotActive; var color = new Color(0f, 1f, 0f); Rect rect = selectedSpriteRect; Vector4 border = selectedSpriteBorder; float left = rect.xMin + border.x; float right = rect.xMax - border.z; float top = rect.yMax - border.w; float bottom = rect.yMin + border.y; EditorGUI.BeginChangeCheck(); float horizontal = bottom - (bottom - top) / 2; float vertical = left - (left - right) / 2; float center = horizontal; HandleBorderPointSlider(ref left, ref center, MouseCursor.ResizeHorizontal, false, dragDot, dragDotActive, color); center = horizontal; HandleBorderPointSlider(ref right, ref center, MouseCursor.ResizeHorizontal, false, dragDot, dragDotActive, color); center = vertical; HandleBorderPointSlider(ref center, ref top, MouseCursor.ResizeVertical, false, dragDot, dragDotActive, color); center = vertical; HandleBorderPointSlider(ref center, ref bottom, MouseCursor.ResizeVertical, false, dragDot, dragDotActive, color); if (EditorGUI.EndChangeCheck()) { border.x = left - rect.xMin; border.z = rect.xMax - right; border.w = rect.yMax - top; border.y = bottom - rect.yMin; selectedSpriteBorder = border; PopulateSpriteFrameInspectorField(); } } protected void HandleBorderCornerScalingHandles() { if (!hasSelected) return; GUIStyle dragDot = styles.dragBorderdot; GUIStyle dragDotActive = styles.dragBorderDotActive; var color = new Color(0f, 1f, 0f); Rect rect = selectedSpriteRect; Vector4 border = selectedSpriteBorder; float left = rect.xMin + border.x; float right = rect.xMax - border.z; float top = rect.yMax - border.w; float bottom = rect.yMin + border.y; EditorGUI.BeginChangeCheck(); // Handle corner points, but hide them if border values are below 1 HandleBorderPointSlider(ref left, ref top, MouseCursor.ResizeUpLeft, border.x < 1 && border.w < 1, dragDot, dragDotActive, color); HandleBorderPointSlider(ref right, ref top, MouseCursor.ResizeUpRight, border.z < 1 && border.w < 1, dragDot, dragDotActive, color); HandleBorderPointSlider(ref left, ref bottom, MouseCursor.ResizeUpRight, border.x < 1 && border.y < 1, dragDot, dragDotActive, color); HandleBorderPointSlider(ref right, ref bottom, MouseCursor.ResizeUpLeft, border.z < 1 && border.y < 1, dragDot, dragDotActive, color); if (EditorGUI.EndChangeCheck()) { border.x = left - rect.xMin; border.z = rect.xMax - right; border.w = rect.yMax - top; border.y = bottom - rect.yMin; selectedSpriteBorder = border; PopulateSpriteFrameInspectorField(); } } protected void HandleBorderSideScalingHandles() { if (hasSelected == false) return; Rect rect = new Rect(selectedSpriteRect); Vector4 border = selectedSpriteBorder; float left = rect.xMin + border.x; float right = rect.xMax - border.z; float top = rect.yMax - border.w; float bottom = rect.yMin + border.y; Vector2 screenRectTopLeft = Handles.matrix.MultiplyPoint(new Vector3(rect.xMin, rect.yMin)); Vector2 screenRectBottomRight = Handles.matrix.MultiplyPoint(new Vector3(rect.xMax, rect.yMax)); float screenRectWidth = Mathf.Abs(screenRectBottomRight.x - screenRectTopLeft.x); float screenRectHeight = Mathf.Abs(screenRectBottomRight.y - screenRectTopLeft.y); EditorGUI.BeginChangeCheck(); left = HandleBorderScaleSlider(left, rect.yMax, screenRectWidth, screenRectHeight, true); right = HandleBorderScaleSlider(right, rect.yMax, screenRectWidth, screenRectHeight, true); top = HandleBorderScaleSlider(rect.xMin, top, screenRectWidth, screenRectHeight, false); bottom = HandleBorderScaleSlider(rect.xMin, bottom, screenRectWidth, screenRectHeight, false); if (EditorGUI.EndChangeCheck()) { border.x = left - rect.xMin; border.z = rect.xMax - right; border.w = rect.yMax - top; border.y = bottom - rect.yMin; selectedSpriteBorder = border; PopulateSpriteFrameInspectorField(); } } protected void HandleBorderPointSlider(ref float x, ref float y, MouseCursor mouseCursor, bool isHidden, GUIStyle dragDot, GUIStyle dragDotActive, Color color) { var originalColor = GUI.color; if (isHidden) GUI.color = new Color(0, 0, 0, 0); else GUI.color = color; Vector2 point = SpriteEditorHandles.PointSlider(new Vector2(x, y), mouseCursor, dragDot, dragDotActive); x = point.x; y = point.y; GUI.color = originalColor; } protected float HandleBorderScaleSlider(float x, float y, float width, float height, bool isHorizontal) { float handleSize = styles.dragBorderdot.fixedWidth; Vector2 point = Handles.matrix.MultiplyPoint(new Vector2(x, y)); float result; EditorGUI.BeginChangeCheck(); if (isHorizontal) { Rect newRect = new Rect(point.x - handleSize * .5f, point.y, handleSize, height); result = SpriteEditorHandles.ScaleSlider(point, MouseCursor.ResizeHorizontal, newRect).x; } else { Rect newRect = new Rect(point.x, point.y - handleSize * .5f, width, handleSize); result = SpriteEditorHandles.ScaleSlider(point, MouseCursor.ResizeVertical, newRect).y; } if (EditorGUI.EndChangeCheck()) return result; return isHorizontal ? x : y; } protected void DrawSpriteRectGizmos() { if (eventSystem.current.type != EventType.Repaint) return; SpriteEditorUtility.BeginLines(new Color(0f, 1f, 0f, 0.7f)); var selectedGUID = selected != null ? selected.spriteID : new GUID(); for (int i = 0; i < spriteCount; i++) { Vector4 border = GetSpriteBorderAt(i); if (m_GizmoMode != GizmoMode.BorderEditing && (m_RectsCache != null && m_RectsCache.spriteRects[i].spriteID != selectedGUID)) { // border does not contain negative values if (border.sqrMagnitude < Mathf.Epsilon * 8) continue; } var rect = GetSpriteRectAt(i); SpriteEditorUtility.DrawLine(new Vector3(rect.xMin + border.x, rect.yMin), new Vector3(rect.xMin + border.x, rect.yMax)); SpriteEditorUtility.DrawLine(new Vector3(rect.xMax - border.z, rect.yMin), new Vector3(rect.xMax - border.z, rect.yMax)); SpriteEditorUtility.DrawLine(new Vector3(rect.xMin, rect.yMin + border.y), new Vector3(rect.xMax, rect.yMin + border.y)); SpriteEditorUtility.DrawLine(new Vector3(rect.xMin, rect.yMax - border.w), new Vector3(rect.xMax, rect.yMax - border.w)); } SpriteEditorUtility.EndLines(); if (ShouldShowRectScaling()) { Rect r = selectedSpriteRect; SpriteEditorUtility.BeginLines(new Color(0f, 0.1f, 0.3f, 0.25f)); SpriteEditorUtility.DrawBox(new Rect(r.xMin + 1f / m_Zoom, r.yMin + 1f / m_Zoom, r.width, r.height)); SpriteEditorUtility.EndLines(); SpriteEditorUtility.BeginLines(new Color(0.25f, 0.5f, 1f, 0.75f)); SpriteEditorUtility.DrawBox(r); SpriteEditorUtility.EndLines(); } } protected void DrawRectGizmos(IEnumerable rects, Color color) { if (eventSystem.current.type != EventType.Repaint) return; SpriteEditorUtility.BeginLines(color); foreach (var rect in rects) { SpriteEditorUtility.DrawLine(new Vector3(rect.xMin, rect.yMin), new Vector3(rect.xMin, rect.yMax)); SpriteEditorUtility.DrawLine(new Vector3(rect.xMax, rect.yMin), new Vector3(rect.xMax, rect.yMax)); SpriteEditorUtility.DrawLine(new Vector3(rect.xMin, rect.yMin), new Vector3(rect.xMax, rect.yMin)); SpriteEditorUtility.DrawLine(new Vector3(rect.xMin, rect.yMax), new Vector3(rect.xMax, rect.yMax)); } SpriteEditorUtility.EndLines(); } // implements ISpriteEditorModule public override void DoMainGUI() { m_Zoom = Handles.matrix.GetColumn(0).magnitude; } public override void DoPostGUI() { } } }