Last active
May 30, 2018 21:04
-
-
Save huiliu/45d7392146e56b8c7e3d89de13ddb95b to your computer and use it in GitHub Desktop.
Revisions
-
huiliu revised this gist
May 30, 2018 . 1 changed file with 142 additions and 185 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,14 +1,11 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.Sprites; public class ChildImage : Image{ protected override void OnPopulateMesh(VertexHelper toFill) { base.OnPopulateMesh(toFill); @@ -19,18 +16,8 @@ protected override void OnPopulateMesh(VertexHelper toFill) } if (type == Type.Sliced) { //GenerateSlicedSprite_(toFill); GenerateSprite(toFill); } } @@ -63,8 +50,7 @@ static void AddQuad(VertexHelper vertexHelper, Vector2 posMin, Vector2 posMax, C vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2); vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex); } private void GenerateSlicedSprite_(VertexHelper toFill) { Vector4 outer, inner, padding, border; @@ -87,43 +73,38 @@ private void GenerateSlicedSpriteLeft(VertexHelper toFill) border = GetAdjustedBorders(border / pixelsPerUnit, rect); padding = padding / pixelsPerUnit; float condition = (border.z + border.x) / rect.width; #region 实际显示size float[] x={0,0,0,0}; x[0] = 0; if (fillAmount <condition) { x[1] = fillAmount / 2 * rect.width; x[2] = x[1]+ 0; x[3] = x[1]*2; } else { x[1] = border.x; x[2] = rect.width *fillAmount-border.z; x[3] =x[2]+border.z; } float []y ={0+rect.y,rect.height+rect.y}; for (int i = 0; i < 4; ++i) { x[i] += rect.x; } #endregion #region uv值 float[] x_uv = {0,0,0,0 }; x_uv[0] =0; if (fillAmount <condition) { x_uv[1] = fillAmount*rect.width/2/sprite.rect.size.x; x_uv[2] = 1 - x_uv[1]; } else @@ -135,23 +116,25 @@ private void GenerateSlicedSpriteLeft(VertexHelper toFill) float y_uv = 1; #endregion toFill.Clear(); for (int i = 0; i < 3; i++) { int i2 = i + 1; AddQuad(toFill, new Vector2(x[i],y[0]), new Vector2(x[i2],y[1]), color, new Vector2(x_uv[i],0), new Vector2(x_uv[i2],y_uv)); } } public SliceFilledType sliceFilledType; static readonly Vector2[] s_VertScratch = new Vector2[4]; static readonly Vector2[] s_UVScratch = new Vector2[4]; private void GenerateSprite(VertexHelper toFill) { Vector4 outer, inner, padding, border; @@ -171,177 +154,151 @@ private void GenerateSlicedSpriteRight(VertexHelper toFill) } Rect rect = GetPixelAdjustedRect(); var adjustedBorders = GetAdjustedBorders(border / pixelsPerUnit, rect); padding = padding / pixelsPerUnit; var tx0 = outer.x; var ty0 = outer.y; var tx1 = outer.z; var ty1 = outer.w; var v = GetDrawingDimensions(preserveAspect); var fill = (tx1 - tx0) * fillAmount; v.x = v.z - (v.x - v.z) * fillAmount; tx0 = tx1 - fill; switch (sliceFilledType) { case SliceFilledType.Left: { s_VertScratch[0] = new Vector2(padding.x, padding.y); //s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w); s_VertScratch[1].x = adjustedBorders.x; s_VertScratch[1].y = adjustedBorders.y; s_VertScratch[2].x = (rect.width - adjustedBorders.z) * fillAmount; s_VertScratch[2].y = rect.height - adjustedBorders.w; s_VertScratch[3] = new Vector2(s_VertScratch[2].x + adjustedBorders.z, rect.height - padding.w); } break; case SliceFilledType.Right: { s_VertScratch[2].x = rect.width - adjustedBorders.z; s_VertScratch[2].y = rect.height - adjustedBorders.w; s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w); s_VertScratch[0].x = rect.width - (rect.width - adjustedBorders.x) * fillAmount - adjustedBorders.x; s_VertScratch[0].y = padding.y; s_VertScratch[1].x = s_VertScratch[0].x + adjustedBorders.x; s_VertScratch[1].y = adjustedBorders.y; } break; case SliceFilledType.Center: { s_VertScratch[0].x = (rect.width - adjustedBorders.x) * fillAmount / 2; s_VertScratch[0].y = padding.y; s_VertScratch[1].x = s_VertScratch[0].x + adjustedBorders.x; s_VertScratch[1].y = adjustedBorders.y; s_VertScratch[2].x = rect.width - (rect.width - adjustedBorders.z) * fillAmount/2 - adjustedBorders.z; s_VertScratch[2].y = rect.height - adjustedBorders.w; s_VertScratch[3] = new Vector2(s_VertScratch[2].x + adjustedBorders.z, rect.height - padding.w); } break; } for (int i = 0; i < 4; ++i) { s_VertScratch[i].x += rect.x; s_VertScratch[i].y += rect.y; } s_UVScratch[0] = new Vector2(outer.x, outer.y); s_UVScratch[1] = new Vector2(inner.x, inner.y); s_UVScratch[2] = new Vector2(inner.z, inner.w); s_UVScratch[3] = new Vector2(outer.z, outer.w); toFill.Clear(); for (int x = 0; x < 3; ++x) { int x2 = x + 1; for (int y = 0; y < 3; ++y) { if (!fillCenter && x == 1 && y == 1) continue; int y2 = y + 1; AddQuad(toFill, new Vector2(s_VertScratch[x].x, s_VertScratch[y].y), new Vector2(s_VertScratch[x2].x, s_VertScratch[y2].y), color, new Vector2(s_UVScratch[x].x, s_UVScratch[y].y), new Vector2(s_UVScratch[x2].x, s_UVScratch[y2].y)); } } } /// Image's dimensions used for drawing. X = left, Y = bottom, Z = right, W = top. private Vector4 GetDrawingDimensions(bool shouldPreserveAspect) { var padding = overrideSprite == null ? Vector4.zero : UnityEngine.Sprites.DataUtility.GetPadding(overrideSprite); var size = overrideSprite == null ? Vector2.zero : new Vector2(overrideSprite.rect.width, overrideSprite.rect.height); Rect r = GetPixelAdjustedRect(); // Debug.Log(string.Format("r:{2}, size:{0}, padding:{1}", size, padding, r)); int spriteW = Mathf.RoundToInt(size.x); int spriteH = Mathf.RoundToInt(size.y); var v = new Vector4( padding.x / spriteW, padding.y / spriteH, (spriteW - padding.z) / spriteW, (spriteH - padding.w) / spriteH); if (shouldPreserveAspect && size.sqrMagnitude > 0.0f) { var spriteRatio = size.x / size.y; var rectRatio = r.width / r.height; if (spriteRatio > rectRatio) { var oldHeight = r.height; r.height = r.width * (1.0f / spriteRatio); r.y += (oldHeight - r.height) * rectTransform.pivot.y; } else { var oldWidth = r.width; r.width = r.height * spriteRatio; r.x += (oldWidth - r.width) * rectTransform.pivot.x; } } v = new Vector4( r.x + r.width * v.x, r.y + r.height * v.y, r.x + r.width * v.z, r.y + r.height * v.w ); return v; } public enum SliceFilledType { Left, Right, -
huiliu created this gist
May 29, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,350 @@ using UnityEngine; using UnityEngine.UI; using UnityEngine.Sprites; /// <summary> /// 参照 https://www.cnblogs.com/ninomiya/p/8134497.html 修改 /// </summary> public class SlicedImage : Image { public SlicedType slicedType; protected override void OnPopulateMesh(VertexHelper toFill) { base.OnPopulateMesh(toFill); if (overrideSprite == null) { base.OnPopulateMesh(toFill); return; } if (type == Type.Sliced) { switch (slicedType) { case SlicedType.Center: GenerateSlicedSpriteCenter(toFill); break; case SlicedType.Left: GenerateSlicedSpriteLeft(toFill); break; case SlicedType.Right: GenerateSlicedSpriteRight(toFill); break; } } } Vector4 GetAdjustedBorders(Vector4 border, Rect rect) { for (int axis = 0; axis <= 1; axis++) { // If the rect is smaller than the combined borders, then there's not room for the borders at their normal size. // In order to avoid artefacts with overlapping borders, we scale the borders down to fit. float combinedBorders = border[axis] + border[axis + 2]; if (rect.size[axis] < combinedBorders && combinedBorders != 0) { float borderScaleRatio = rect.size[axis] / combinedBorders; border[axis] *= borderScaleRatio; border[axis + 2] *= borderScaleRatio; } } return border; } static void AddQuad(VertexHelper vertexHelper, Vector2 posMin, Vector2 posMax, Color32 color, Vector2 uvMin, Vector2 uvMax) { int startIndex = vertexHelper.currentVertCount; vertexHelper.AddVert(new Vector3(posMin.x, posMin.y, 0), color, new Vector2(uvMin.x, uvMin.y)); vertexHelper.AddVert(new Vector3(posMin.x, posMax.y, 0), color, new Vector2(uvMin.x, uvMax.y)); vertexHelper.AddVert(new Vector3(posMax.x, posMax.y, 0), color, new Vector2(uvMax.x, uvMax.y)); vertexHelper.AddVert(new Vector3(posMax.x, posMin.y, 0), color, new Vector2(uvMax.x, uvMin.y)); vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2); vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex); } private void GenerateSlicedSpriteLeft(VertexHelper toFill) { Vector4 outer, inner, padding, border; if (overrideSprite != null) { outer = DataUtility.GetOuterUV(overrideSprite); inner = DataUtility.GetInnerUV(overrideSprite); padding = DataUtility.GetPadding(overrideSprite); border = overrideSprite.border; } else { outer = Vector4.zero; inner = Vector4.zero; padding = Vector4.zero; border = Vector4.zero; } Rect rect = GetPixelAdjustedRect(); border = GetAdjustedBorders(border / pixelsPerUnit, rect); padding = padding / pixelsPerUnit; float condition = (border.z + border.x) / rect.width; var realFillAmount = fillAmount; #region 实际显示size float[] x = { 0, 0, 0, 0 }; { x[0] = 0; if (realFillAmount < condition) { x[1] = realFillAmount / 2 * rect.width; x[2] = x[1] + 0; x[3] = x[1] * 2; } else { x[1] = border.x; x[2] = rect.width * realFillAmount - border.z; x[3] = x[2] + border.z; } } float[] y = { 0 + rect.y, rect.height + rect.y }; Debug.Log(string.Format("xo: {0} {1} {2} {3}", x[0], x[1], x[2], x[3])); for (int i = 0; i < 4; ++i) { x[i] += rect.x; } #endregion #region uv值 float[] x_uv = { 0, 0, 0, 0 }; x_uv[0] = 0; if (realFillAmount < condition) { x_uv[1] = realFillAmount * rect.width / 2 / sprite.rect.size.x; x_uv[2] = 1 - x_uv[1]; } else { x_uv[1] = inner.x; x_uv[2] = inner.z; } x_uv[3] = outer.z; float y_uv = 1; #endregion Debug.Log(string.Format("x: {0} {1} {2} {3}", x[0], x[1], x[2], x[3])); Debug.Log(string.Format("x_uv: {0} {1} {2} {3}", x_uv[0], x_uv[1], x_uv[2], x_uv[3])); toFill.Clear(); for (int i = 0; i < 3; i++) { int i2 = i + 1; AddQuad(toFill, new Vector2(x[i], y[0]), new Vector2(x[i2], y[1]), color, new Vector2(x_uv[i], 0), new Vector2(x_uv[i2], y_uv)); } } private void GenerateSlicedSpriteRight(VertexHelper toFill) { Vector4 outer, inner, padding, border; if (overrideSprite != null) { outer = DataUtility.GetOuterUV(overrideSprite); inner = DataUtility.GetInnerUV(overrideSprite); padding = DataUtility.GetPadding(overrideSprite); border = overrideSprite.border; } else { outer = Vector4.zero; inner = Vector4.zero; padding = Vector4.zero; border = Vector4.zero; } Rect rect = GetPixelAdjustedRect(); border = GetAdjustedBorders(border / pixelsPerUnit, rect); padding = padding / pixelsPerUnit; float condition = (border.z + border.x) / rect.width; var realFillAmount = fillAmount; #region 实际显示size float[] x = { 0, 0, 0, 0 }; Debug.Log(string.Format("rect.x: {0} rect.y: {1} rect.width: {2} rect.heigh: {3}", rect.x, rect.y, rect.width, rect.height)); Debug.Log(string.Format("border.x: {0} border.y: {1} border.z: {2} border.w: {3}", border.x, border.y, border.z, border.w)); { x[0] = 0; if (realFillAmount < condition) { x[1] = realFillAmount / 2 * rect.width; x[2] = x[1] + 0; x[3] = x[1] * 2; } else { x[1] = border.x; x[2] = rect.width * realFillAmount - border.z; x[3] = x[2] + border.z; } var tmp = x[0]; x[0] = x[3]; x[3] = tmp; tmp = x[1]; x[1] = x[2]; x[2] = tmp; } float[] y = { 0 + rect.y, rect.height + rect.y }; Debug.Log(string.Format("xo: {0} {1} {2} {3}", x[0], x[1], x[2], x[3])); for (int i = 0; i < 4; ++i) { x[i] += rect.x; x[i] *= (-1); } #endregion #region uv值 float[] x_uv = { 0, 0, 0, 0 }; x_uv[0] = 0; if (realFillAmount < condition) { x_uv[1] = realFillAmount * rect.width / 2 / sprite.rect.size.x; x_uv[2] = 1 - x_uv[1]; } else { x_uv[1] = inner.x; x_uv[2] = inner.z; } x_uv[3] = outer.z; float y_uv = 1; #endregion Debug.Log(string.Format("x: {0} {1} {2} {3}", x[0], x[1], x[2], x[3])); Debug.Log(string.Format("x_uv: {0} {1} {2} {3}", x_uv[0], x_uv[1], x_uv[2], x_uv[3])); toFill.Clear(); for (int i = 0; i < 3; i++) { int i2 = i + 1; AddQuad(toFill, new Vector2(x[i], y[0]), new Vector2(x[i2], y[1]), color, new Vector2(x_uv[i], 0), new Vector2(x_uv[i2], y_uv)); } } private void GenerateSlicedSpriteCenter(VertexHelper toFill) { Vector4 outer, inner, padding, border; if (overrideSprite != null) { outer = DataUtility.GetOuterUV(overrideSprite); inner = DataUtility.GetInnerUV(overrideSprite); padding = DataUtility.GetPadding(overrideSprite); border = overrideSprite.border; } else { outer = Vector4.zero; inner = Vector4.zero; padding = Vector4.zero; border = Vector4.zero; } Rect rect = GetPixelAdjustedRect(); border = GetAdjustedBorders(border / pixelsPerUnit, rect); padding = padding / pixelsPerUnit; float condition = (border.z + border.x) / rect.width; var realFillAmount = fillAmount / 2; #region 实际显示size float[] x = { 0, 0, 0, 0 }; { x[0] = 0; if (realFillAmount < condition) { x[1] = realFillAmount / 2 * rect.width; x[2] = x[1] + 0; x[3] = x[1] * 2; } else { x[1] = border.x; x[2] = rect.width * realFillAmount - border.z; x[3] = x[2] + border.z; } } float[] y = { 0 + rect.y, rect.height + rect.y }; Debug.Log(string.Format("xo: {0} {1} {2} {3}", x[0], x[1], x[2], x[3])); for (int i = 0; i < 4; ++i) { x[i] += rect.x + rect.width / 2; //x[i] += rect.x; } #endregion #region uv值 float[] x_uv = { 0, 0, 0, 0 }; x_uv[0] = 0; if (realFillAmount < condition) { x_uv[1] = realFillAmount * rect.width / 2 / sprite.rect.size.x; x_uv[2] = 1 - x_uv[1]; } else { x_uv[1] = inner.x; x_uv[2] = inner.z; } x_uv[3] = outer.z; float y_uv = 1; #endregion x[0] = -x[3]; x[1] = -x[2]; Debug.Log(string.Format("x: {0} {1} {2} {3}", x[0], x[1], x[2], x[3])); Debug.Log(string.Format("x_uv: {0} {1} {2} {3}", x_uv[0], x_uv[1], x_uv[2], x_uv[3])); toFill.Clear(); for (int i = 0; i < 3; i++) { int i2 = i + 1; AddQuad(toFill, new Vector2(x[i], y[0]), new Vector2(x[i2], y[1]), color, new Vector2(x_uv[i], 0), new Vector2(x_uv[i2], y_uv)); } } public enum SlicedType { Left, Right, Center } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,160 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor.UI; using UnityEditor; using UnityEditor.AnimatedValues; using System.Linq; [CustomEditor(typeof(SlicedImage))] public class SlicedImageInspector : ImageEditor { SerializedProperty m_FillMethod; SerializedProperty m_FillOrigin; SerializedProperty m_FillAmount; SerializedProperty m_FillClockwise; SerializedProperty m_Type; SerializedProperty m_FillCenter; SerializedProperty m_Sprite; SerializedProperty m_PreserveAspect; GUIContent m_SpriteContent; GUIContent m_SpriteTypeContent; GUIContent m_ClockwiseContent; AnimBool m_ShowSlicedOrTiled; AnimBool m_ShowSliced; AnimBool m_ShowFilled; AnimBool m_ShowType; void SetShowNativeSize(bool instant) { SlicedImage.Type type = (SlicedImage.Type)m_Type.enumValueIndex; bool showNativeSize = (type == SlicedImage.Type.Simple || type == SlicedImage.Type.Filled); base.SetShowNativeSize(showNativeSize, instant); } protected override void OnEnable() { base.OnEnable(); m_SpriteContent = new GUIContent("Source childImage"); m_SpriteTypeContent = new GUIContent("childImage Type"); m_ClockwiseContent = new GUIContent("Clockwise"); m_Sprite = serializedObject.FindProperty("m_Sprite"); m_Type = serializedObject.FindProperty("m_Type"); m_FillCenter = serializedObject.FindProperty("m_FillCenter"); m_FillMethod = serializedObject.FindProperty("m_FillMethod"); m_FillOrigin = serializedObject.FindProperty("m_FillOrigin"); m_FillClockwise = serializedObject.FindProperty("m_FillClockwise"); m_FillAmount = serializedObject.FindProperty("m_FillAmount"); m_PreserveAspect = serializedObject.FindProperty("m_PreserveAspect"); m_ShowType = new AnimBool(m_Sprite.objectReferenceValue != null); m_ShowType.valueChanged.AddListener(Repaint); var typeEnum = (SlicedImage.Type)m_Type.enumValueIndex; m_ShowSlicedOrTiled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == SlicedImage.Type.Sliced); m_ShowSliced = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == SlicedImage.Type.Sliced); m_ShowFilled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == SlicedImage.Type.Filled); m_ShowSlicedOrTiled.valueChanged.AddListener(Repaint); m_ShowSliced.valueChanged.AddListener(Repaint); m_ShowFilled.valueChanged.AddListener(Repaint); SetShowNativeSize(true); } public override void OnInspectorGUI() { serializedObject.Update(); SpriteGUI(); AppearanceControlsGUI(); RaycastControlsGUI(); m_ShowType.target = m_Sprite.objectReferenceValue != null; if (EditorGUILayout.BeginFadeGroup(m_ShowType.faded)) { EditorGUILayout.PropertyField(m_Type, m_SpriteTypeContent); ++EditorGUI.indentLevel; { SlicedImage.Type typeEnum = (SlicedImage.Type)m_Type.enumValueIndex; bool showSlicedOrTiled = (!m_Type.hasMultipleDifferentValues && (typeEnum == SlicedImage.Type.Sliced || typeEnum == SlicedImage.Type.Tiled)); if (showSlicedOrTiled && targets.Length > 1) showSlicedOrTiled = targets.Select(obj => obj as SlicedImage).All(img => img.hasBorder); m_ShowSlicedOrTiled.target = showSlicedOrTiled; m_ShowSliced.target = (showSlicedOrTiled && !m_Type.hasMultipleDifferentValues && typeEnum == SlicedImage.Type.Sliced); m_ShowFilled.target = (!m_Type.hasMultipleDifferentValues && (typeEnum == SlicedImage.Type.Filled)); SlicedImage cImage = target as SlicedImage; if (EditorGUILayout.BeginFadeGroup(m_ShowSlicedOrTiled.faded)) { if (cImage.hasBorder) { EditorGUILayout.PropertyField(m_FillCenter); cImage.slicedType = (SlicedImage.SlicedType)EditorGUILayout.EnumPopup("Fill Origin", cImage.slicedType); EditorGUILayout.PropertyField(m_FillAmount); } } EditorGUILayout.EndFadeGroup(); if (EditorGUILayout.BeginFadeGroup(m_ShowSliced.faded)) { if (cImage.sprite != null && !cImage.hasBorder) EditorGUILayout.HelpBox("This childImage doesn't have a border.", MessageType.Warning); } EditorGUILayout.EndFadeGroup(); if (EditorGUILayout.BeginFadeGroup(m_ShowFilled.faded)) { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_FillMethod); if (EditorGUI.EndChangeCheck()) { m_FillOrigin.intValue = 0; } switch ((SlicedImage.FillMethod)m_FillMethod.enumValueIndex) { case SlicedImage.FillMethod.Horizontal: m_FillOrigin.intValue = (int)(SlicedImage.OriginHorizontal)EditorGUILayout.EnumPopup("Fill Origin", (SlicedImage.OriginHorizontal)m_FillOrigin.intValue); break; case SlicedImage.FillMethod.Vertical: m_FillOrigin.intValue = (int)(SlicedImage.OriginVertical)EditorGUILayout.EnumPopup("Fill Origin", (SlicedImage.OriginVertical)m_FillOrigin.intValue); break; case SlicedImage.FillMethod.Radial90: m_FillOrigin.intValue = (int)(SlicedImage.Origin90)EditorGUILayout.EnumPopup("Fill Origin", (SlicedImage.Origin90)m_FillOrigin.intValue); break; case SlicedImage.FillMethod.Radial180: m_FillOrigin.intValue = (int)(SlicedImage.Origin180)EditorGUILayout.EnumPopup("Fill Origin", (SlicedImage.Origin180)m_FillOrigin.intValue); break; case SlicedImage.FillMethod.Radial360: m_FillOrigin.intValue = (int)(SlicedImage.Origin360)EditorGUILayout.EnumPopup("Fill Origin", (SlicedImage.Origin360)m_FillOrigin.intValue); break; } EditorGUILayout.PropertyField(m_FillAmount); if ((SlicedImage.FillMethod)m_FillMethod.enumValueIndex > SlicedImage.FillMethod.Vertical) { EditorGUILayout.PropertyField(m_FillClockwise, m_ClockwiseContent); } } EditorGUILayout.EndFadeGroup(); } --EditorGUI.indentLevel; } EditorGUILayout.EndFadeGroup(); SetShowNativeSize(false); if (EditorGUILayout.BeginFadeGroup(m_ShowNativeSize.faded)) { EditorGUI.indentLevel++; EditorGUILayout.PropertyField(m_PreserveAspect); EditorGUI.indentLevel--; } EditorGUILayout.EndFadeGroup(); NativeSizeButtonGUI(); serializedObject.ApplyModifiedProperties(); } }