Beispiel #1
0
        protected virtual void DrawInspectorGUI(bool multi)
        {
            // Initialize.
            if (Event.current.type == EventType.Layout)
            {
                if (forceReloadQueued)
                {
                    forceReloadQueued = false;
                    if (multi)
                    {
                        foreach (var c in targets)
                        {
                            EditorForceReloadSkeletonDataAssetAndComponent(c as SkeletonRenderer);
                        }
                    }
                    else
                    {
                        EditorForceReloadSkeletonDataAssetAndComponent(target as SkeletonRenderer);
                    }
                }
                else
                {
                    if (multi)
                    {
                        foreach (var c in targets)
                        {
                            var component = c as SkeletonRenderer;
                            if (!component.valid)
                            {
                                EditorForceInitializeComponent(component);
                                if (!component.valid)
                                {
                                    continue;
                                }
                            }
                        }
                    }
                    else
                    {
                        var component = (SkeletonRenderer)target;
                        if (!component.valid)
                        {
                            EditorForceInitializeComponent(component);
                        }
                    }
                }

                                #if NO_PREFAB_MESH
                if (isInspectingPrefab)
                {
                    if (multi)
                    {
                        foreach (var c in targets)
                        {
                            var        component  = (SkeletonRenderer)c;
                            MeshFilter meshFilter = component.GetComponent <MeshFilter>();
                            if (meshFilter != null && meshFilter.sharedMesh != null)
                            {
                                meshFilter.sharedMesh = null;
                            }
                        }
                    }
                    else
                    {
                        var        component  = (SkeletonRenderer)target;
                        MeshFilter meshFilter = component.GetComponent <MeshFilter>();
                        if (meshFilter != null && meshFilter.sharedMesh != null)
                        {
                            meshFilter.sharedMesh = null;
                        }
                    }
                }
                                #endif
            }

            bool valid = TargetIsValid;

            // Fields.
            if (multi)
            {
                using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox)) {
                    SpineInspectorUtility.PropertyFieldFitLabel(skeletonDataAsset, SkeletonDataAssetLabel);
                    if (GUILayout.Button(ReloadButtonString, ReloadButtonStyle, ReloadButtonWidth))
                    {
                        forceReloadQueued = true;
                    }
                }

                if (valid)
                {
                    EditorGUILayout.PropertyField(initialSkinName, SpineInspectorUtility.TempContent("Initial Skin"));
                }
            }
            else
            {
                var component = (SkeletonRenderer)target;

                using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox)) {
                    SpineInspectorUtility.PropertyFieldFitLabel(skeletonDataAsset, SkeletonDataAssetLabel);
                    if (component.valid)
                    {
                        if (GUILayout.Button(ReloadButtonString, ReloadButtonStyle, ReloadButtonWidth))
                        {
                            forceReloadQueued = true;
                        }
                    }
                }

                if (component.skeletonDataAsset == null)
                {
                    EditorGUILayout.HelpBox("Skeleton Data Asset required", MessageType.Warning);
                    return;
                }

                if (!SkeletonDataAssetIsValid(component.skeletonDataAsset))
                {
                    EditorGUILayout.HelpBox("Skeleton Data Asset error. Please check Skeleton Data Asset.", MessageType.Error);
                    return;
                }

                if (valid)
                {
                    EditorGUILayout.PropertyField(initialSkinName, SpineInspectorUtility.TempContent("Initial Skin"));
                }
            }

            EditorGUILayout.Space();

            // Sorting Layers
            SpineInspectorUtility.SortingPropertyFields(sortingProperties, applyModifiedProperties: true);

            if (!valid)
            {
                return;
            }

            // More Render Options...
            using (new SpineInspectorUtility.BoxScope()) {
                EditorGUI.BeginChangeCheck();

                EditorGUILayout.BeginHorizontal(GUILayout.Height(EditorGUIUtility.singleLineHeight + 5));
                advancedFoldout = EditorGUILayout.Foldout(advancedFoldout, "Advanced");
                if (advancedFoldout)
                {
                    EditorGUILayout.Space();
                    if (GUILayout.Button("Debug", EditorStyles.miniButton, GUILayout.Width(65f)))
                    {
                        SkeletonDebugWindow.Init();
                    }
                }
                else
                {
                    EditorGUILayout.Space();
                }
                EditorGUILayout.EndHorizontal();

                if (advancedFoldout)
                {
                    using (new SpineInspectorUtility.IndentScope()) {
                        using (new EditorGUILayout.HorizontalScope()) {
                            SpineInspectorUtility.ToggleLeftLayout(initialFlipX);
                            SpineInspectorUtility.ToggleLeftLayout(initialFlipY);
                            EditorGUILayout.Space();
                        }

                        EditorGUILayout.Space();
                        EditorGUILayout.LabelField("Renderer Settings", EditorStyles.boldLabel);
                        using (new SpineInspectorUtility.LabelWidthScope()) {
                            // Optimization options
                            if (singleSubmesh != null)
                            {
                                EditorGUILayout.PropertyField(singleSubmesh, SingleSubmeshLabel);
                            }
                            if (immutableTriangles != null)
                            {
                                EditorGUILayout.PropertyField(immutableTriangles, ImmubleTrianglesLabel);
                            }
                            EditorGUILayout.PropertyField(clearStateOnDisable, ClearStateOnDisableLabel);
                            EditorGUILayout.Space();
                        }

                        SeparatorsField(separatorSlotNames);
                        EditorGUILayout.Space();

                        // Render options
                        const float MinZSpacing = -0.1f;
                        const float MaxZSpacing = 0f;
                        EditorGUILayout.Slider(zSpacing, MinZSpacing, MaxZSpacing, ZSpacingLabel);
                        EditorGUILayout.Space();

                        using (new SpineInspectorUtility.LabelWidthScope()) {
                            EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Vertex Data", SpineInspectorUtility.UnityIcon <MeshFilter>()), EditorStyles.boldLabel);
                            if (pmaVertexColors != null)
                            {
                                EditorGUILayout.PropertyField(pmaVertexColors, PMAVertexColorsLabel);
                            }
                            EditorGUILayout.PropertyField(tintBlack, TintBlackLabel);

                            // Optional fields. May be disabled in SkeletonRenderer.
                            if (normals != null)
                            {
                                EditorGUILayout.PropertyField(normals, NormalsLabel);
                            }
                            if (tangents != null)
                            {
                                EditorGUILayout.PropertyField(tangents, TangentsLabel);
                            }
                        }

                        EditorGUILayout.Space();

                        if (valid && !isInspectingPrefab)
                        {
                            if (multi)
                            {
                                // Support multi-edit SkeletonUtility button.
                                //	EditorGUILayout.Space();
                                //	bool addSkeletonUtility = GUILayout.Button(buttonContent, GUILayout.Height(30));
                                //	foreach (var t in targets) {
                                //		var component = t as Component;
                                //		if (addSkeletonUtility && component.GetComponent<SkeletonUtility>() == null)
                                //			component.gameObject.AddComponent<SkeletonUtility>();
                                //	}
                            }
                            else
                            {
                                var component = (Component)target;
                                if (component.GetComponent <SkeletonUtility>() == null)
                                {
                                    if (SpineInspectorUtility.CenteredButton(SkeletonUtilityButtonContent, 21, true, 200f))
                                    {
                                        component.gameObject.AddComponent <SkeletonUtility>();
                                    }
                                }
                            }
                        }

                        EditorGUILayout.Space();
                    }
                }

                if (EditorGUI.EndChangeCheck())
                {
                    SceneView.RepaintAll();
                }
            }
        }
        protected virtual void DrawInspectorGUI(bool multi)
        {
            // Initialize.
            if (Event.current.type == EventType.Layout)
            {
                if (forceReloadQueued)
                {
                    forceReloadQueued = false;
                    if (multi)
                    {
                        foreach (var c in targets)
                        {
                            EditorForceReloadSkeletonDataAssetAndComponent(c as SkeletonRenderer);
                        }
                    }
                    else
                    {
                        EditorForceReloadSkeletonDataAssetAndComponent(target as SkeletonRenderer);
                    }
                }
                else
                {
                    if (multi)
                    {
                        foreach (var c in targets)
                        {
                            var component = c as SkeletonRenderer;
                            if (!component.valid)
                            {
                                EditorForceInitializeComponent(component);
                                if (!component.valid)
                                {
                                    continue;
                                }
                            }
                        }
                    }
                    else
                    {
                        var component = (SkeletonRenderer)target;
                        if (!component.valid)
                        {
                            EditorForceInitializeComponent(component);
                        }
                    }
                }

                                #if BUILT_IN_SPRITE_MASK_COMPONENT
                if (setMaskNoneMaterialsQueued)
                {
                    setMaskNoneMaterialsQueued = false;
                    foreach (var c in targets)
                    {
                        EditorSetMaskMaterials(c as SkeletonRenderer, SpriteMaskInteraction.None);
                    }
                }
                if (setInsideMaskMaterialsQueued)
                {
                    setInsideMaskMaterialsQueued = false;
                    foreach (var c in targets)
                    {
                        EditorSetMaskMaterials(c as SkeletonRenderer, SpriteMaskInteraction.VisibleInsideMask);
                    }
                }
                if (setOutsideMaskMaterialsQueued)
                {
                    setOutsideMaskMaterialsQueued = false;
                    foreach (var c in targets)
                    {
                        EditorSetMaskMaterials(c as SkeletonRenderer, SpriteMaskInteraction.VisibleOutsideMask);
                    }
                }

                if (deleteInsideMaskMaterialsQueued)
                {
                    deleteInsideMaskMaterialsQueued = false;
                    foreach (var c in targets)
                    {
                        EditorDeleteMaskMaterials(c as SkeletonRenderer, SpriteMaskInteraction.VisibleInsideMask);
                    }
                }
                if (deleteOutsideMaskMaterialsQueued)
                {
                    deleteOutsideMaskMaterialsQueued = false;
                    foreach (var c in targets)
                    {
                        EditorDeleteMaskMaterials(c as SkeletonRenderer, SpriteMaskInteraction.VisibleOutsideMask);
                    }
                }
                                #endif

#if NO_PREFAB_MESH
                if (isInspectingPrefab)
                {
                    if (multi)
                    {
                        foreach (var c in targets)
                        {
                            var        component  = (SkeletonRenderer)c;
                            MeshFilter meshFilter = component.GetComponent <MeshFilter>();
                            if (meshFilter != null && meshFilter.sharedMesh != null)
                            {
                                meshFilter.sharedMesh = null;
                            }
                        }
                    }
                    else
                    {
                        var        component  = (SkeletonRenderer)target;
                        MeshFilter meshFilter = component.GetComponent <MeshFilter>();
                        if (meshFilter != null && meshFilter.sharedMesh != null)
                        {
                            meshFilter.sharedMesh = null;
                        }
                    }
                }
#endif
            }

            bool valid = TargetIsValid;

            // Fields.
            if (multi)
            {
                using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox)) {
                    SpineInspectorUtility.PropertyFieldFitLabel(skeletonDataAsset, SkeletonDataAssetLabel);
                    if (GUILayout.Button(ReloadButtonString, ReloadButtonStyle, ReloadButtonWidth))
                    {
                        forceReloadQueued = true;
                    }
                }

                if (valid)
                {
                    EditorGUILayout.PropertyField(initialSkinName, SpineInspectorUtility.TempContent("Initial Skin"));
                }
            }
            else
            {
                var component = (SkeletonRenderer)target;

                using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox)) {
                    SpineInspectorUtility.PropertyFieldFitLabel(skeletonDataAsset, SkeletonDataAssetLabel);
                    if (component.valid)
                    {
                        if (GUILayout.Button(ReloadButtonString, ReloadButtonStyle, ReloadButtonWidth))
                        {
                            forceReloadQueued = true;
                        }
                    }
                }

                if (component.skeletonDataAsset == null)
                {
                    EditorGUILayout.HelpBox("Skeleton Data Asset required", MessageType.Warning);
                    return;
                }

                if (!SkeletonDataAssetIsValid(component.skeletonDataAsset))
                {
                    EditorGUILayout.HelpBox("Skeleton Data Asset error. Please check Skeleton Data Asset.", MessageType.Error);
                    return;
                }

                if (valid)
                {
                    EditorGUILayout.PropertyField(initialSkinName, SpineInspectorUtility.TempContent("Initial Skin"));
                }
            }

            EditorGUILayout.Space();

            // Sorting Layers
            SpineInspectorUtility.SortingPropertyFields(sortingProperties, applyModifiedProperties: true);

            if (maskInteraction != null)
            {
                EditorGUILayout.PropertyField(maskInteraction, MaskInteractionLabel);
            }

            if (!valid)
            {
                return;
            }

            string errorMessage = null;
            if (MaterialChecks.IsMaterialSetupProblematic((SkeletonRenderer)this.target, ref errorMessage))
            {
                EditorGUILayout.HelpBox(errorMessage, MessageType.Error, true);
            }

            // More Render Options...
            using (new SpineInspectorUtility.BoxScope()) {
                EditorGUI.BeginChangeCheck();

                EditorGUILayout.BeginHorizontal(GUILayout.Height(EditorGUIUtility.singleLineHeight + 5));
                advancedFoldout = EditorGUILayout.Foldout(advancedFoldout, "Advanced");
                if (advancedFoldout)
                {
                    EditorGUILayout.Space();
                    if (GUILayout.Button("Debug", EditorStyles.miniButton, GUILayout.Width(65f)))
                    {
                        SkeletonDebugWindow.Init();
                    }
                }
                else
                {
                    EditorGUILayout.Space();
                }
                EditorGUILayout.EndHorizontal();

                if (advancedFoldout)
                {
                    using (new SpineInspectorUtility.IndentScope()) {
                        using (new EditorGUILayout.HorizontalScope()) {
                            SpineInspectorUtility.ToggleLeftLayout(initialFlipX);
                            SpineInspectorUtility.ToggleLeftLayout(initialFlipY);
                            EditorGUILayout.Space();
                        }

                        EditorGUILayout.Space();
                        EditorGUILayout.LabelField("Renderer Settings", EditorStyles.boldLabel);
                        using (new SpineInspectorUtility.LabelWidthScope()) {
                            // Optimization options
                            if (singleSubmesh != null)
                            {
                                EditorGUILayout.PropertyField(singleSubmesh, SingleSubmeshLabel);
                            }
                                                        #if PER_MATERIAL_PROPERTY_BLOCKS
                            if (fixDrawOrder != null)
                            {
                                EditorGUILayout.PropertyField(fixDrawOrder, FixDrawOrderLabel);
                            }
                                                        #endif
                            if (immutableTriangles != null)
                            {
                                EditorGUILayout.PropertyField(immutableTriangles, ImmubleTrianglesLabel);
                            }
                            EditorGUILayout.PropertyField(clearStateOnDisable, ClearStateOnDisableLabel);
                            EditorGUILayout.Space();
                        }

                        SeparatorsField(separatorSlotNames);
                        EditorGUILayout.Space();

                        // Render options
                        const float MinZSpacing = -0.1f;
                        const float MaxZSpacing = 0f;
                        EditorGUILayout.Slider(zSpacing, MinZSpacing, MaxZSpacing, ZSpacingLabel);
                        EditorGUILayout.Space();

                        using (new SpineInspectorUtility.LabelWidthScope()) {
                            EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Vertex Data", SpineInspectorUtility.UnityIcon <MeshFilter>()), EditorStyles.boldLabel);
                            if (pmaVertexColors != null)
                            {
                                EditorGUILayout.PropertyField(pmaVertexColors, PMAVertexColorsLabel);
                            }
                            EditorGUILayout.PropertyField(tintBlack, TintBlackLabel);

                            // Optional fields. May be disabled in SkeletonRenderer.
                            if (normals != null)
                            {
                                EditorGUILayout.PropertyField(normals, NormalsLabel);
                            }
                            if (tangents != null)
                            {
                                EditorGUILayout.PropertyField(tangents, TangentsLabel);
                            }
                        }

                                                #if BUILT_IN_SPRITE_MASK_COMPONENT
                        EditorGUILayout.Space();
                        if (maskMaterialsNone.arraySize > 0 || maskMaterialsInside.arraySize > 0 || maskMaterialsOutside.arraySize > 0)
                        {
                            EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Mask Interaction Materials", SpineInspectorUtility.UnityIcon <SpriteMask>()), EditorStyles.boldLabel);
                            bool differentMaskModesSelected = maskInteraction.hasMultipleDifferentValues;
                            int  activeMaskInteractionValue = differentMaskModesSelected ? -1 : maskInteraction.intValue;

                            bool ignoredParam = true;
                            MaskMaterialsEditingField(ref setMaskNoneMaterialsQueued, ref ignoredParam, maskMaterialsNone, MaskMaterialsNoneLabel,
                                                      differentMaskModesSelected, allowDelete: false, isActiveMaterial: activeMaskInteractionValue == (int)SpriteMaskInteraction.None);
                            MaskMaterialsEditingField(ref setInsideMaskMaterialsQueued, ref deleteInsideMaskMaterialsQueued, maskMaterialsInside, MaskMaterialsInsideLabel,
                                                      differentMaskModesSelected, allowDelete: true, isActiveMaterial: activeMaskInteractionValue == (int)SpriteMaskInteraction.VisibleInsideMask);
                            MaskMaterialsEditingField(ref setOutsideMaskMaterialsQueued, ref deleteOutsideMaskMaterialsQueued, maskMaterialsOutside, MaskMaterialsOutsideLabel,
                                                      differentMaskModesSelected, allowDelete: true, isActiveMaterial: activeMaskInteractionValue == (int)SpriteMaskInteraction.VisibleOutsideMask);
                        }
                                                #endif

                        EditorGUILayout.Space();

                        if (valid && !isInspectingPrefab)
                        {
                            if (multi)
                            {
                                // Support multi-edit SkeletonUtility button.
                                //	EditorGUILayout.Space();
                                //	bool addSkeletonUtility = GUILayout.Button(buttonContent, GUILayout.Height(30));
                                //	foreach (var t in targets) {
                                //		var component = t as Component;
                                //		if (addSkeletonUtility && component.GetComponent<SkeletonUtility>() == null)
                                //			component.gameObject.AddComponent<SkeletonUtility>();
                                //	}
                            }
                            else
                            {
                                var component = (Component)target;
                                if (component.GetComponent <SkeletonUtility>() == null)
                                {
                                    if (SpineInspectorUtility.CenteredButton(SkeletonUtilityButtonContent, 21, true, 200f))
                                    {
                                        component.gameObject.AddComponent <SkeletonUtility>();
                                    }
                                }
                            }
                        }

                        EditorGUILayout.Space();
                    }
                }

                if (EditorGUI.EndChangeCheck())
                {
                    SceneView.RepaintAll();
                }
            }
        }
        protected virtual void DrawInspectorGUI(bool multi)
        {
            bool valid             = TargetIsValid;
            var  reloadWidth       = GUILayout.Width(GUI.skin.label.CalcSize(new GUIContent(ReloadButtonLabel)).x + 20);
            var  reloadButtonStyle = EditorStyles.miniButtonRight;

            if (multi)
            {
                using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox)) {
                    SpineInspectorUtility.PropertyFieldFitLabel(skeletonDataAsset, SkeletonDataAssetLabel);
                    if (GUILayout.Button(ReloadButtonLabel, reloadButtonStyle, reloadWidth))
                    {
                        foreach (var c in targets)
                        {
                            var component = c as SkeletonRenderer;
                            if (component.skeletonDataAsset != null)
                            {
                                foreach (AtlasAsset aa in component.skeletonDataAsset.atlasAssets)
                                {
                                    if (aa != null)
                                    {
                                        aa.Clear();
                                    }
                                }
                                component.skeletonDataAsset.Clear();
                            }
                            component.Initialize(true);
                        }
                    }
                }

                foreach (var c in targets)
                {
                    var component = c as SkeletonRenderer;
                    if (!component.valid)
                    {
                        if (Event.current.type == EventType.Layout)
                        {
                            component.Initialize(true);
                            component.LateUpdate();
                        }
                        if (!component.valid)
                        {
                            continue;
                        }
                    }

                                        #if NO_PREFAB_MESH
                    if (isInspectingPrefab)
                    {
                        MeshFilter meshFilter = component.GetComponent <MeshFilter>();
                        if (meshFilter != null)
                        {
                            meshFilter.sharedMesh = null;
                        }
                    }
                                        #endif
                }

                if (valid)
                {
                    EditorGUILayout.PropertyField(initialSkinName);
                }
            }
            else
            {
                var component = (SkeletonRenderer)target;

                if (!component.valid && Event.current.type == EventType.Layout)
                {
                    component.Initialize(true);
                    // component.LateUpdate();
                }

                using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox)) {
                    SpineInspectorUtility.PropertyFieldFitLabel(skeletonDataAsset, SkeletonDataAssetLabel);
                    if (component.valid)
                    {
                        if (GUILayout.Button(ReloadButtonLabel, reloadButtonStyle, reloadWidth))
                        {
                            if (component.skeletonDataAsset != null)
                            {
                                foreach (AtlasAsset aa in component.skeletonDataAsset.atlasAssets)
                                {
                                    if (aa != null)
                                    {
                                        aa.Clear();
                                    }
                                }
                                component.skeletonDataAsset.Clear();
                            }
                            component.Initialize(true);
                        }
                    }
                }

                if (component.skeletonDataAsset == null)
                {
                    EditorGUILayout.HelpBox("Skeleton Data Asset required", MessageType.Warning);
                    return;
                }

                                #if NO_PREFAB_MESH
                if (isInspectingPrefab)
                {
                    MeshFilter meshFilter = component.GetComponent <MeshFilter>();
                    if (meshFilter != null)
                    {
                        meshFilter.sharedMesh = null;
                    }
                }
                                #endif

                // Initial skin name.
                if (component.valid)
                {
                    var skeletonDataSkins = component.skeleton.Data.Skins;
                    int skinCount         = skeletonDataSkins.Count;
                    if (loadedSkinList != skeletonDataSkins)
                    {
                        skins          = new GUIContent[skinCount];
                        loadedSkinList = skeletonDataSkins;
                        for (int i = 0; i < skins.Length; i++)
                        {
                            string skinNameString = skeletonDataSkins.Items[i].Name;
                            skins[i] = new GUIContent(skinNameString, Icons.skin);
                        }
                    }

                    int skinIndex = 0;
                    for (int i = 0; i < skins.Length; i++)
                    {
                        string skinNameString = skeletonDataSkins.Items[i].Name;
                        if (skinNameString == initialSkinName.stringValue)
                        {
                            skinIndex = i;
                        }
                    }

                    skinIndex = EditorGUILayout.Popup(SpineInspectorUtility.TempContent("Initial Skin"), skinIndex, skins);
                    if (skins.Length > 0)                     // Support attachmentless/skinless SkeletonData.
                    {
                        initialSkinName.stringValue = skins[skinIndex].text;
                    }
                }
            }

            EditorGUILayout.Space();

            // Sorting Layers
            //SpineInspectorUtility.SortingPropertyFields(sortingProperties, applyModifiedProperties: true);

            if (!TargetIsValid)
            {
                return;
            }
            // More Render Options...
            using (new SpineInspectorUtility.BoxScope()) {
                EditorGUI.BeginChangeCheck();

                EditorGUILayout.BeginHorizontal(GUILayout.Height(EditorGUIUtility.singleLineHeight + 5));
                advancedFoldout = EditorGUILayout.Foldout(advancedFoldout, "Advanced");
                if (advancedFoldout)
                {
                    EditorGUILayout.Space();
                    if (GUILayout.Button("Debug", EditorStyles.miniButton, GUILayout.Width(65f)))
                    {
                        SkeletonDebugWindow.Init();
                    }
                }
                else
                {
                    EditorGUILayout.Space();
                }
                EditorGUILayout.EndHorizontal();

                if (advancedFoldout)
                {
                    using (new SpineInspectorUtility.IndentScope()) {
                        using (new EditorGUILayout.HorizontalScope()) {
                            initialFlipX.boolValue = EditorGUILayout.ToggleLeft(initialFlipX.displayName, initialFlipX.boolValue, GUILayout.Width(120f));
                            initialFlipY.boolValue = EditorGUILayout.ToggleLeft(initialFlipY.displayName, initialFlipY.boolValue, GUILayout.Width(120f));
                            EditorGUILayout.Space();
                        }

                        EditorGUILayout.Space();
                        EditorGUILayout.LabelField("Renderer Settings", EditorStyles.boldLabel);
                        using (new SpineInspectorUtility.LabelWidthScope()) {
                            // Optimization options
                            if (singleSubmesh != null)
                            {
                                EditorGUILayout.PropertyField(singleSubmesh, SingleSubmeshLabel);
                            }
                            //if (meshes != null) EditorGUILayout.PropertyField(meshes, MeshesLabel);
                            if (immutableTriangles != null)
                            {
                                EditorGUILayout.PropertyField(immutableTriangles, ImmubleTrianglesLabel);
                            }
                            EditorGUILayout.PropertyField(clearStateOnDisable, ClearStateOnDisableLabel);
                            EditorGUILayout.Space();
                        }

                        SeparatorsField(separatorSlotNames);
                        EditorGUILayout.Space();

                        // Render options
                        const float MinZSpacing = -0.1f;
                        const float MaxZSpacing = 0f;
                        EditorGUILayout.Slider(zSpacing, MinZSpacing, MaxZSpacing, ZSpacingLabel);
                        EditorGUILayout.Space();

                        using (new SpineInspectorUtility.LabelWidthScope()) {
                            EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Vertex Data", SpineInspectorUtility.UnityIcon <MeshFilter>()), EditorStyles.boldLabel);
                            if (pmaVertexColors != null)
                            {
                                EditorGUILayout.PropertyField(pmaVertexColors, PMAVertexColorsLabel);
                            }
                            EditorGUILayout.PropertyField(tintBlack, TintBlackLabel);

                            // Optional fields. May be disabled in SkeletonRenderer.
                            if (normals != null)
                            {
                                EditorGUILayout.PropertyField(normals, NormalsLabel);
                            }
                            if (tangents != null)
                            {
                                EditorGUILayout.PropertyField(tangents, TangentsLabel);
                            }
                        }

                        EditorGUILayout.Space();

                        if (TargetIsValid && !isInspectingPrefab)
                        {
                            if (multi)
                            {
                                // Support multi-edit SkeletonUtility button.
                                //	EditorGUILayout.Space();
                                //	bool addSkeletonUtility = GUILayout.Button(buttonContent, GUILayout.Height(30));
                                //	foreach (var t in targets) {
                                //		var component = t as Component;
                                //		if (addSkeletonUtility && component.GetComponent<SkeletonUtility>() == null)
                                //			component.gameObject.AddComponent<SkeletonUtility>();
                                //	}
                            }
                            else
                            {
                                var component = (Component)target;
                                if (component.GetComponent <SkeletonUtility>() == null)
                                {
                                    if (SpineInspectorUtility.CenteredButton(SkeletonUtilityButtonContent, 21, true, 200f))
                                    {
                                        component.gameObject.AddComponent <SkeletonUtility>();
                                    }
                                }
                            }
                        }

                        EditorGUILayout.Space();
                    }
                }

                if (EditorGUI.EndChangeCheck())
                {
                    SceneView.RepaintAll();
                }
            }
        }