// Window GUI void OnGUI() { bool requireRepaint = false; if (staticLostValues) { Clear(); OnSelectionChange(); staticLostValues = false; requireRepaint = true; } if (SlotsRootLabel == null) { SlotsRootLabel = new GUIContent("Slots", Icons.slotRoot); SkeletonRootLabel = new GUIContent("Skeleton", Icons.skeleton); BoldFoldoutStyle = new GUIStyle(EditorStyles.foldout); BoldFoldoutStyle.fontStyle = FontStyle.Bold; BoldFoldoutStyle.stretchWidth = true; BoldFoldoutStyle.fixedWidth = 0; } EditorGUILayout.Space(); EditorGUI.BeginDisabledGroup(true); EditorGUILayout.ObjectField(SpineInspectorUtility.TempContent("Debug Selection", Icons.spine), skeletonRenderer, typeof(SkeletonRenderer), true); EditorGUI.EndDisabledGroup(); if (skeleton == null || skeletonRenderer == null) { EditorGUILayout.HelpBox("No SkeletonRenderer Spine GameObject selected.", MessageType.Info); return; } if (isPrefab) { EditorGUILayout.HelpBox("SkeletonDebug only debugs Spine GameObjects in the scene.", MessageType.Warning); return; } if (!skeletonRenderer.valid) { EditorGUILayout.HelpBox("Spine Component is invalid. Check SkeletonData Asset.", MessageType.Error); return; } if (activeSkin != skeleton.Skin) { UpdateAttachments(); } scrollPos = EditorGUILayout.BeginScrollView(scrollPos); using (new SpineInspectorUtility.BoxScope(false)) { if (SpineInspectorUtility.CenteredButton(SpineInspectorUtility.TempContent("Skeleton.SetToSetupPose()"))) { skeleton.SetToSetupPose(); requireRepaint = true; } EditorGUI.BeginChangeCheck(); EditorGUILayout.LabelField("Scene View", EditorStyles.boldLabel); using (new SpineInspectorUtility.LabelWidthScope()) { showBoneNames = EditorGUILayout.Toggle("Show Bone Names", showBoneNames); showPaths = EditorGUILayout.Toggle("Show Paths", showPaths); showShapes = EditorGUILayout.Toggle("Show Shapes", showShapes); showConstraints = EditorGUILayout.Toggle("Show Constraints", showConstraints); } requireRepaint |= EditorGUI.EndChangeCheck(); // Skeleton showSkeleton.target = EditorGUILayout.Foldout(showSkeleton.target, SkeletonRootLabel, BoldFoldoutStyle); if (showSkeleton.faded > 0) { using (new SpineInspectorUtility.IndentScope()) { using (new EditorGUILayout.FadeGroupScope(showSkeleton.faded)) { EditorGUI.BeginChangeCheck(); EditorGUI.BeginDisabledGroup(true); FalseDropDown(".Skin", skeleton.Skin != null ? skeletonRenderer.Skeleton.Skin.Name : "<None>", Icons.skin); EditorGUI.EndDisabledGroup(); // Flip skeleton.ScaleX = EditorGUILayout.DelayedFloatField(".ScaleX", skeleton.ScaleX); skeleton.ScaleY = EditorGUILayout.DelayedFloatField(".ScaleY", skeleton.ScaleY); //EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(160f)); ////EditorGUILayout.LabelField("Scale", GUILayout.Width(EditorGUIUtility.labelWidth - 20f)); //GUILayout.EndHorizontal(); // Color skeleton.SetColor(EditorGUILayout.ColorField(".R .G .B .A", skeleton.GetColor())); requireRepaint |= EditorGUI.EndChangeCheck(); } } } // Bone showInspectBoneTree.target = EditorGUILayout.Foldout(showInspectBoneTree.target, SpineInspectorUtility.TempContent("Bone", Icons.bone), BoldFoldoutStyle); if (showInspectBoneTree.faded > 0) { using (new SpineInspectorUtility.IndentScope()) { using (new EditorGUILayout.FadeGroupScope(showInspectBoneTree.faded)) { showBoneNames = EditorGUILayout.Toggle("Show Bone Names", showBoneNames); if (bpo == null) { bpo = new SerializedObject(this).FindProperty("boneName"); } EditorGUILayout.PropertyField(bpo, SpineInspectorUtility.TempContent("Bone")); if (!string.IsNullOrEmpty(bpo.stringValue)) { if (bone == null || bone.Data.Name != bpo.stringValue) { bone = skeleton.FindBone(bpo.stringValue); } if (bone != null) { using (new EditorGUI.DisabledGroupScope(true)) { var wm = EditorGUIUtility.wideMode; EditorGUIUtility.wideMode = true; EditorGUILayout.Slider("Local Rotation", ViewRound(bone.Rotation), -180f, 180f); EditorGUILayout.Vector2Field("Local Position", RoundVector2(bone.X, bone.Y)); EditorGUILayout.Vector2Field("Local Scale", RoundVector2(bone.ScaleX, bone.ScaleY)); EditorGUILayout.Vector2Field("Local Shear", RoundVector2(bone.ShearX, bone.ShearY)); EditorGUILayout.Space(); var boneParent = bone.Parent; if (boneParent != null) { FalseDropDown("Parent", boneParent.Data.Name, Icons.bone); } const string RoundFormat = "0.##"; var lw = EditorGUIUtility.labelWidth; var fw = EditorGUIUtility.fieldWidth; EditorGUIUtility.labelWidth *= 0.25f; EditorGUIUtility.fieldWidth *= 0.5f; EditorGUILayout.LabelField("LocalToWorld"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.Space(); EditorGUILayout.TextField(".A", bone.A.ToString(RoundFormat)); EditorGUILayout.TextField(".B", bone.B.ToString(RoundFormat)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.Space(); EditorGUILayout.TextField(".C", bone.C.ToString(RoundFormat)); EditorGUILayout.TextField(".D", bone.D.ToString(RoundFormat)); EditorGUILayout.EndHorizontal(); EditorGUIUtility.labelWidth = lw * 0.5f; EditorGUILayout.BeginHorizontal(); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.TextField(".WorldX", bone.WorldX.ToString(RoundFormat)); EditorGUILayout.TextField(".WorldY", bone.WorldY.ToString(RoundFormat)); EditorGUILayout.EndHorizontal(); EditorGUIUtility.labelWidth = lw; EditorGUIUtility.fieldWidth = fw; EditorGUIUtility.wideMode = wm; } } requireRepaint = true; } else { bone = null; } } } } // Slots int preSlotsIndent = EditorGUI.indentLevel; showSlotsTree.target = EditorGUILayout.Foldout(showSlotsTree.target, SlotsRootLabel, BoldFoldoutStyle); if (showSlotsTree.faded > 0) { using (new EditorGUILayout.FadeGroupScope(showSlotsTree.faded)) { if (SpineInspectorUtility.CenteredButton(SpineInspectorUtility.TempContent("Skeleton.SetSlotsToSetupPose()"))) { skeleton.SetSlotsToSetupPose(); requireRepaint = true; } int baseIndent = EditorGUI.indentLevel; foreach (KeyValuePair <Slot, List <Attachment> > pair in attachmentTable) { Slot slot = pair.Key; using (new EditorGUILayout.HorizontalScope()) { EditorGUI.indentLevel = baseIndent + 1; EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false)); EditorGUI.BeginChangeCheck(); Color c = EditorGUILayout.ColorField(new Color(slot.R, slot.G, slot.B, slot.A), GUILayout.Width(60)); if (EditorGUI.EndChangeCheck()) { slot.SetColor(c); requireRepaint = true; } } foreach (var attachment in pair.Value) { GUI.contentColor = slot.Attachment == attachment ? Color.white : Color.grey; EditorGUI.indentLevel = baseIndent + 2; var icon = Icons.GetAttachmentIcon(attachment); bool isAttached = (attachment == slot.Attachment); bool swap = EditorGUILayout.ToggleLeft(SpineInspectorUtility.TempContent(attachment.Name, icon), attachment == slot.Attachment); if (isAttached != swap) { slot.Attachment = isAttached ? null : attachment; requireRepaint = true; } GUI.contentColor = Color.white; } } } } EditorGUI.indentLevel = preSlotsIndent; // Constraints const string NoneText = "<none>"; showConstraintsTree.target = EditorGUILayout.Foldout(showConstraintsTree.target, SpineInspectorUtility.TempContent("Constraints", Icons.constraintRoot), BoldFoldoutStyle); if (showConstraintsTree.faded > 0) { using (new SpineInspectorUtility.IndentScope()) { using (new EditorGUILayout.FadeGroupScope(showConstraintsTree.faded)) { const float MixMin = 0f; const float MixMax = 1f; EditorGUI.BeginChangeCheck(); showConstraints = EditorGUILayout.Toggle("Show Constraints", showConstraints); requireRepaint |= EditorGUI.EndChangeCheck(); EditorGUILayout.Space(); EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(string.Format("IK Constraints ({0})", skeleton.IkConstraints.Count), Icons.constraintIK), EditorStyles.boldLabel); using (new SpineInspectorUtility.IndentScope()) { if (skeleton.IkConstraints.Count > 0) { foreach (var c in skeleton.IkConstraints) { EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(c.Data.Name, Icons.constraintIK)); FalseDropDown("Goal", c.Data.Target.Name, Icons.bone, true); using (new EditorGUI.DisabledGroupScope(true)) { EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Data.Uniform", tooltip: "Uniformly scales a bone when Ik stretches or compresses."), c.Data.Uniform); } EditorGUI.BeginChangeCheck(); c.Mix = EditorGUILayout.Slider("Mix", c.Mix, MixMin, MixMax); c.BendDirection = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Bend Clockwise", tooltip: "IkConstraint.BendDirection == 1 if clockwise; -1 if counterclockwise."), c.BendDirection > 0) ? 1 : -1; c.Compress = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Compress", tooltip: "Compress single bone IK when the target too close. Not applied when parent bone has nonuniform scale."), c.Compress); c.Stretch = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Stretch", tooltip: "Stretch the parent bone when the target is out of range. Not applied when parent bone has nonuniform scale."), c.Stretch); if (EditorGUI.EndChangeCheck()) { requireRepaint = true; } EditorGUILayout.Space(); } } else { EditorGUILayout.LabelField(NoneText); } } EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(string.Format("Transform Constraints ({0})", skeleton.TransformConstraints.Count), Icons.constraintTransform), EditorStyles.boldLabel); using (new SpineInspectorUtility.IndentScope()) { if (skeleton.TransformConstraints.Count > 0) { foreach (var c in skeleton.TransformConstraints) { EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(c.Data.Name, Icons.constraintTransform)); EditorGUI.BeginDisabledGroup(true); FalseDropDown("Goal", c.Data.Target.Name, Icons.bone); EditorGUI.EndDisabledGroup(); EditorGUI.BeginChangeCheck(); c.TranslateMix = EditorGUILayout.Slider("TranslateMix", c.TranslateMix, MixMin, MixMax); c.RotateMix = EditorGUILayout.Slider("RotateMix", c.RotateMix, MixMin, MixMax); c.ScaleMix = EditorGUILayout.Slider("ScaleMix", c.ScaleMix, MixMin, MixMax); c.ShearMix = EditorGUILayout.Slider("ShearMix", c.ShearMix, MixMin, MixMax); if (EditorGUI.EndChangeCheck()) { requireRepaint = true; } EditorGUILayout.Space(); } } else { EditorGUILayout.LabelField(NoneText); } } EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(string.Format("Path Constraints ({0})", skeleton.PathConstraints.Count), Icons.constraintPath), EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); showPaths = EditorGUILayout.Toggle("Show Paths", showPaths); requireRepaint |= EditorGUI.EndChangeCheck(); using (new SpineInspectorUtility.IndentScope()) { if (skeleton.PathConstraints.Count > 0) { foreach (var c in skeleton.PathConstraints) { EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(c.Data.Name, Icons.constraintPath)); EditorGUI.BeginDisabledGroup(true); FalseDropDown("Path Slot", c.Data.Target.Name, Icons.slot); var activeAttachment = c.Target.Attachment; FalseDropDown("Active Path", activeAttachment != null ? activeAttachment.Name : "<None>", activeAttachment is PathAttachment ? Icons.path : null); EditorGUILayout.LabelField("PositionMode." + c.Data.PositionMode); EditorGUILayout.LabelField("SpacingMode." + c.Data.SpacingMode); EditorGUILayout.LabelField("RotateMode." + c.Data.RotateMode); EditorGUI.EndDisabledGroup(); EditorGUI.BeginChangeCheck(); c.RotateMix = EditorGUILayout.Slider("RotateMix", c.RotateMix, MixMin, MixMax); c.TranslateMix = EditorGUILayout.Slider("TranslateMix", c.TranslateMix, MixMin, MixMax); c.Position = EditorGUILayout.FloatField("Position", c.Position); c.Spacing = EditorGUILayout.FloatField("Spacing", c.Spacing); if (EditorGUI.EndChangeCheck()) { requireRepaint = true; } EditorGUILayout.Space(); } } else { EditorGUILayout.LabelField(NoneText); } } } } } showDrawOrderTree.target = EditorGUILayout.Foldout(showDrawOrderTree.target, SpineInspectorUtility.TempContent("Draw Order and Separators", Icons.slotRoot), BoldFoldoutStyle); //var separatorSlotNamesField = //SpineInspectorUtility.ge if (showDrawOrderTree.faded > 0) { using (new SpineInspectorUtility.IndentScope()) { using (new EditorGUILayout.FadeGroupScope(showDrawOrderTree.faded)) { const string SeparatorString = "------------- v SEPARATOR v -------------"; if (Application.isPlaying) { foreach (var slot in skeleton.DrawOrder) { if (skeletonRenderer.separatorSlots.Contains(slot)) { EditorGUILayout.LabelField(SeparatorString); } EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false)); } } else { foreach (var slot in skeleton.DrawOrder) { var slotNames = SkeletonRendererInspector.GetSeparatorSlotNames(skeletonRenderer); for (int i = 0, n = slotNames.Length; i < n; i++) { if (string.Equals(slotNames[i], slot.Data.Name, System.StringComparison.Ordinal)) { EditorGUILayout.LabelField(SeparatorString); break; } } EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false)); } } } } } showEventDataTree.target = EditorGUILayout.Foldout(showEventDataTree.target, SpineInspectorUtility.TempContent("Events", Icons.userEvent), BoldFoldoutStyle); if (showEventDataTree.faded > 0) { using (new SpineInspectorUtility.IndentScope()) { using (new EditorGUILayout.FadeGroupScope(showEventDataTree.faded)) { if (skeleton.Data.Events.Count > 0) { foreach (var e in skeleton.Data.Events) { EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(e.Name, Icons.userEvent)); } } else { EditorGUILayout.LabelField(NoneText); } } } } showDataTree.target = EditorGUILayout.Foldout(showDataTree.target, SpineInspectorUtility.TempContent("Data Counts", Icons.spine), BoldFoldoutStyle); if (showDataTree.faded > 0) { using (new SpineInspectorUtility.IndentScope()) { using (new EditorGUILayout.FadeGroupScope(showDataTree.faded)) { using (new SpineInspectorUtility.LabelWidthScope()) { var skeletonData = skeleton.Data; EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Bones", Icons.bone, "Skeleton.Data.Bones"), new GUIContent(skeletonData.Bones.Count.ToString())); EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Slots", Icons.slotRoot, "Skeleton.Data.Slots"), new GUIContent(skeletonData.Slots.Count.ToString())); EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Skins", Icons.skinsRoot, "Skeleton.Data.Skins"), new GUIContent(skeletonData.Skins.Count.ToString())); EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Events", Icons.userEvent, "Skeleton.Data.Events"), new GUIContent(skeletonData.Events.Count.ToString())); EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("IK Constraints", Icons.constraintIK, "Skeleton.Data.IkConstraints"), new GUIContent(skeletonData.IkConstraints.Count.ToString())); EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Transform Constraints", Icons.constraintTransform, "Skeleton.Data.TransformConstraints"), new GUIContent(skeletonData.TransformConstraints.Count.ToString())); EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Path Constraints", Icons.constraintPath, "Skeleton.Data.PathConstraints"), new GUIContent(skeletonData.PathConstraints.Count.ToString())); } } } } if (IsAnimating(showSlotsTree, showSkeleton, showConstraintsTree, showDrawOrderTree, showEventDataTree, showInspectBoneTree, showDataTree)) { Repaint(); } } if (requireRepaint) { skeletonRenderer.LateUpdate(); Repaint(); SceneView.RepaintAll(); } EditorGUILayout.EndScrollView(); }
public override void OnInspectorGUI() { if (UnityEngine.Event.current.type == EventType.Layout) { if (forceReloadQueued) { forceReloadQueued = false; foreach (var c in targets) { SpineEditorUtilities.ReloadSkeletonDataAssetAndComponent(c as SkeletonGraphic); } } else { foreach (var c in targets) { var component = c as SkeletonGraphic; if (!component.IsValid) { SpineEditorUtilities.ReinitializeComponent(component); if (!component.IsValid) { continue; } } } } } bool wasChanged = false; EditorGUI.BeginChangeCheck(); using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox)) { SpineInspectorUtility.PropertyFieldFitLabel(skeletonDataAsset, SkeletonDataAssetLabel); if (GUILayout.Button(ReloadButtonString, ReloadButtonStyle, ReloadButtonWidth)) { forceReloadQueued = true; } } EditorGUILayout.PropertyField(material); EditorGUILayout.PropertyField(color); if (thisSkeletonGraphic.skeletonDataAsset == null) { EditorGUILayout.HelpBox("You need to assign a SkeletonDataAsset first.", MessageType.Info); serializedObject.ApplyModifiedProperties(); serializedObject.Update(); return; } string errorMessage = null; if (SpineEditorUtilities.Preferences.componentMaterialWarning && MaterialChecks.IsMaterialSetupProblematic(thisSkeletonGraphic, ref errorMessage)) { EditorGUILayout.HelpBox(errorMessage, MessageType.Error, true); } bool isSingleRendererOnly = (!allowMultipleCanvasRenderers.hasMultipleDifferentValues && allowMultipleCanvasRenderers.boolValue == false); bool isSeparationEnabledButNotMultipleRenderers = isSingleRendererOnly && (!enableSeparatorSlots.hasMultipleDifferentValues && enableSeparatorSlots.boolValue == true); bool meshRendersIncorrectlyWithSingleRenderer = isSingleRendererOnly && SkeletonHasMultipleSubmeshes(); if (isSeparationEnabledButNotMultipleRenderers || meshRendersIncorrectlyWithSingleRenderer) { meshGeneratorSettings.isExpanded = true; } using (new SpineInspectorUtility.BoxScope()) { EditorGUILayout.PropertyField(meshGeneratorSettings, SpineInspectorUtility.TempContent("Advanced..."), includeChildren: true); SkeletonRendererInspector.advancedFoldout = meshGeneratorSettings.isExpanded; if (meshGeneratorSettings.isExpanded) { EditorGUILayout.Space(); using (new SpineInspectorUtility.IndentScope()) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(allowMultipleCanvasRenderers, SpineInspectorUtility.TempContent("Multiple CanvasRenderers")); if (GUILayout.Button(new GUIContent("Trim Renderers", "Remove currently unused CanvasRenderer GameObjects. These will be regenerated whenever needed."), EditorStyles.miniButton, GUILayout.Width(100f))) { foreach (var skeletonGraphic in targets) { ((SkeletonGraphic)skeletonGraphic).TrimRenderers(); } } EditorGUILayout.EndHorizontal(); EditorGUILayout.PropertyField(updateWhenInvisible); // warning box if (isSeparationEnabledButNotMultipleRenderers) { using (new SpineInspectorUtility.BoxScope()) { meshGeneratorSettings.isExpanded = true; EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("'Multiple Canvas Renderers' must be enabled\nwhen 'Enable Separation' is enabled.", Icons.warning), GUILayout.Height(42), GUILayout.Width(340)); } } else if (meshRendersIncorrectlyWithSingleRenderer) { using (new SpineInspectorUtility.BoxScope()) { meshGeneratorSettings.isExpanded = true; EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("This mesh uses multiple atlas pages. You\n" + "need to enable 'Multiple Canvas Renderers'\n" + "for correct rendering. Consider packing\n" + "attachments to a single atlas page if possible.", Icons.warning), GUILayout.Height(60), GUILayout.Width(340)); } } } EditorGUILayout.Space(); SeparatorsField(separatorSlotNames, enableSeparatorSlots, updateSeparatorPartLocation); } } EditorGUILayout.Space(); EditorGUILayout.PropertyField(initialSkinName); { var rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, EditorGUIUtility.singleLineHeight); EditorGUI.PrefixLabel(rect, SpineInspectorUtility.TempContent("Initial Flip")); rect.x += EditorGUIUtility.labelWidth; rect.width = 30f; SpineInspectorUtility.ToggleLeft(rect, initialFlipX, SpineInspectorUtility.TempContent("X", tooltip: "initialFlipX")); rect.x += 35f; SpineInspectorUtility.ToggleLeft(rect, initialFlipY, SpineInspectorUtility.TempContent("Y", tooltip: "initialFlipY")); } EditorGUILayout.Space(); EditorGUILayout.LabelField("Animation", EditorStyles.boldLabel); EditorGUILayout.PropertyField(startingAnimation); EditorGUILayout.PropertyField(startingLoop); EditorGUILayout.PropertyField(timeScale); EditorGUILayout.PropertyField(unscaledTime, SpineInspectorUtility.TempContent(unscaledTime.displayName, tooltip: "If checked, this will use Time.unscaledDeltaTime to make this update independent of game Time.timeScale. Instance SkeletonGraphic.timeScale will still be applied.")); EditorGUILayout.Space(); EditorGUILayout.PropertyField(freeze); EditorGUILayout.Space(); SkeletonRendererInspector.SkeletonRootMotionParameter(targets); EditorGUILayout.Space(); EditorGUILayout.LabelField("UI", EditorStyles.boldLabel); EditorGUILayout.PropertyField(raycastTarget); EditorGUILayout.BeginHorizontal(GUILayout.Height(EditorGUIUtility.singleLineHeight + 5)); EditorGUILayout.PrefixLabel("Match RectTransform with Mesh"); if (GUILayout.Button("Match", EditorStyles.miniButton, GUILayout.Width(65f))) { foreach (var skeletonGraphic in targets) { MatchRectTransformWithBounds((SkeletonGraphic)skeletonGraphic); } } EditorGUILayout.EndHorizontal(); if (TargetIsValid && !isInspectingPrefab) { EditorGUILayout.Space(); if (SpineInspectorUtility.CenteredButton(new GUIContent("Add Skeleton Utility", Icons.skeletonUtility), 21, true, 200f)) { foreach (var t in targets) { var component = t as Component; if (component.GetComponent <SkeletonUtility>() == null) { component.gameObject.AddComponent <SkeletonUtility>(); } } } } wasChanged |= EditorGUI.EndChangeCheck(); if (wasChanged) { serializedObject.ApplyModifiedProperties(); slotsReapplyRequired = true; } if (slotsReapplyRequired && UnityEngine.Event.current.type == EventType.Repaint) { foreach (var target in targets) { var skeletonGraphic = (SkeletonGraphic)target; skeletonGraphic.ReapplySeparatorSlotNames(); skeletonGraphic.LateUpdate(); SceneView.RepaintAll(); } slotsReapplyRequired = false; } }