Exemplo n.º 1
0
        void OnEnable()
        {
            skeletonUtility  = (SkeletonUtility)target;
            skeletonRenderer = skeletonUtility.GetComponent <SkeletonRenderer>();
            skeleton         = skeletonRenderer.Skeleton;

            if (skeleton == null)
            {
                skeletonRenderer.Initialize(false);
                skeletonRenderer.LateUpdate();
                skeleton = skeletonRenderer.skeleton;
            }

            if (!skeletonRenderer.valid)
            {
                return;
            }

                        #if !NEW_PREFAB_SYSTEM
            isPrefab |= PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab;
                        #endif
        }
        void OnEnable()
        {
            skeletonUtility  = (SkeletonUtility)target;
            skeletonRenderer = skeletonUtility.GetComponent <SkeletonRenderer>();
            skeleton         = skeletonRenderer.skeleton;
            transform        = skeletonRenderer.transform;

            if (skeleton == null)
            {
                skeletonRenderer.Initialize(false);
                skeletonRenderer.LateUpdate();

                skeleton = skeletonRenderer.skeleton;
            }

            UpdateAttachments();

            if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
            {
                isPrefab = true;
            }
        }
Exemplo n.º 3
0
        public void Remove()
        {
            GetTexture();
            if (texture == null)
            {
                return;
            }
            SkeletonRenderer component = GetComponent <SkeletonRenderer>();

            if (!(component == null))
            {
                Dictionary <Slot, Material> customSlotMaterials = component.CustomSlotMaterials;
                foreach (Slot slot in component.Skeleton.Slots)
                {
                    Material value = null;
                    switch (slot.data.blendMode)
                    {
                    case BlendMode.Multiply:
                        if (customSlotMaterials.TryGetValue(slot, out value) && object.ReferenceEquals(value, GetMaterialFor(multiplyMaterialSource, texture)))
                        {
                            customSlotMaterials.Remove(slot);
                        }
                        break;

                    case BlendMode.Screen:
                        if (customSlotMaterials.TryGetValue(slot, out value) && object.ReferenceEquals(value, GetMaterialFor(screenMaterialSource, texture)))
                        {
                            customSlotMaterials.Remove(slot);
                        }
                        break;
                    }
                }
                Applied = false;
                if (component.valid)
                {
                    component.LateUpdate();
                }
            }
        }
Exemplo n.º 4
0
        static bool UpdateIfSkinMismatch(SkeletonRenderer skeletonRenderer)
        {
            if (!skeletonRenderer.valid)
            {
                return(false);
            }

            var    skin              = skeletonRenderer.Skeleton.Skin;
            string skeletonSkinName  = skin != null ? skin.Name : null;
            string componentSkinName = skeletonRenderer.initialSkinName;
            bool   defaultCase       = skin == null && string.IsNullOrEmpty(componentSkinName);
            bool   fieldMatchesSkin  = defaultCase || string.Equals(componentSkinName, skeletonSkinName, System.StringComparison.Ordinal);

            if (!fieldMatchesSkin)
            {
                Skin skinToSet = string.IsNullOrEmpty(componentSkinName) ? null : skeletonRenderer.Skeleton.Data.FindSkin(componentSkinName);
                skeletonRenderer.Skeleton.Skin = skinToSet;
                skeletonRenderer.Skeleton.SetSlotsToSetupPose();
                skeletonRenderer.LateUpdate();
                return(true);
            }
            return(false);
        }
	void OnEnable () {
		skeletonUtility = (SkeletonUtility)target;
		skeletonRenderer = skeletonUtility.GetComponent<SkeletonRenderer>();
		skeleton = skeletonRenderer.skeleton;
		transform = skeletonRenderer.transform;

		if (skeleton == null) {
			skeletonRenderer.Reset();
			skeletonRenderer.LateUpdate();

			skeleton = skeletonRenderer.skeleton;
		}

		UpdateAttachments();

		if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
			isPrefab = true;

	}
        public override void OnInspectorGUI()
        {
            if (isPrefab)
            {
                GUILayout.Label(new GUIContent("Cannot edit Prefabs", SpineEditorUtilities.Icons.warning));
                return;
            }

            skeletonUtility.boneRoot = (Transform)EditorGUILayout.ObjectField("Bone Root", skeletonUtility.boneRoot, typeof(Transform), true);

            GUILayout.BeginHorizontal();
            EditorGUI.BeginDisabledGroup(skeletonUtility.boneRoot != null);
            {
                if (GUILayout.Button(new GUIContent("Spawn Hierarchy", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(150), GUILayout.Height(24)))
                {
                    SpawnHierarchyContextMenu();
                }
            }
            EditorGUI.EndDisabledGroup();

            //		if (GUILayout.Button(new GUIContent("Spawn Submeshes", SpineEditorUtilities.Icons.subMeshRenderer), GUILayout.Width(150), GUILayout.Height(24)))
            //			skeletonUtility.SpawnSubRenderers(true);

            GUILayout.EndHorizontal();

            EditorGUI.BeginChangeCheck();
            skeleton.FlipX = EditorGUILayout.ToggleLeft("Flip X", skeleton.FlipX);
            skeleton.FlipY = EditorGUILayout.ToggleLeft("Flip Y", skeleton.FlipY);
            if (EditorGUI.EndChangeCheck())
            {
                skeletonRenderer.LateUpdate();
                SceneView.RepaintAll();
            }

                        #if UNITY_4_3
            showSlots = EditorGUILayout.Foldout(showSlots, "Slots");
                        #else
            showSlots.target = EditorGUILayout.Foldout(showSlots.target, "Slots");
            if (EditorGUILayout.BeginFadeGroup(showSlots.faded))
            {
                        #endif
            foreach (KeyValuePair <Slot, List <Attachment> > pair in attachmentTable)
            {
                Slot slot = pair.Key;

                EditorGUILayout.BeginHorizontal();
                EditorGUI.indentLevel = 1;
                EditorGUILayout.LabelField(new GUIContent(slot.Data.Name, SpineEditorUtilities.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);
                    skeletonRenderer.LateUpdate();
                }

                EditorGUILayout.EndHorizontal();



                foreach (Attachment attachment in pair.Value)
                {
                    if (slot.Attachment == attachment)
                    {
                        GUI.contentColor = Color.white;
                    }
                    else
                    {
                        GUI.contentColor = Color.grey;
                    }

                    EditorGUI.indentLevel = 2;
                    bool isAttached = attachment == slot.Attachment;

                    Texture2D icon = null;

                    if (attachment is MeshAttachment)
                    {
                        icon = SpineEditorUtilities.Icons.mesh;
                    }
                    else
                    {
                        icon = SpineEditorUtilities.Icons.image;
                    }

                    bool swap = EditorGUILayout.ToggleLeft(new GUIContent(attachment.Name, icon), attachment == slot.Attachment);

                    if (!isAttached && swap)
                    {
                        slot.Attachment = attachment;
                        skeletonRenderer.LateUpdate();
                    }
                    else if (isAttached && !swap)
                    {
                        slot.Attachment = null;
                        skeletonRenderer.LateUpdate();
                    }

                    GUI.contentColor = Color.white;
                }
            }
                        #if UNITY_4_3
                        #else
        }

        EditorGUILayout.EndFadeGroup();
        if (showSlots.isAnimating)
        {
            Repaint();
        }
                        #endif
        }
Exemplo n.º 7
0
        // 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()
        {
            bool requireRepaint = false;

            if (skeletonRenderer.skeleton != skeleton || activeSkin != skeleton.Skin)
            {
                UpdateAttachments();
            }

            if (isPrefab)
            {
                GUILayout.Label(new GUIContent("Cannot edit Prefabs", Icons.warning));
                return;
            }

            if (!skeletonRenderer.valid)
            {
                GUILayout.Label(new GUIContent("Spine Component invalid. Check Skeleton Data Asset.", Icons.warning));
                return;
            }

            skeletonUtility.boneRoot = (Transform)EditorGUILayout.ObjectField("Bone Root", skeletonUtility.boneRoot, typeof(Transform), true);

            using (new EditorGUI.DisabledGroupScope(skeletonUtility.boneRoot != null)) {
                if (SpineInspectorUtility.LargeCenteredButton(SpawnHierarchyButtonLabel))
                {
                    SpawnHierarchyContextMenu();
                }
            }

            using (new SpineInspectorUtility.BoxScope()) {
                debugSkeleton = EditorGUILayout.Foldout(debugSkeleton, "Debug Skeleton");

                if (debugSkeleton)
                {
                    EditorGUI.BeginChangeCheck();
                    skeleton.FlipX  = EditorGUILayout.ToggleLeft("skeleton.FlipX", skeleton.FlipX);
                    skeleton.FlipY  = EditorGUILayout.ToggleLeft("skeleton.FlipY", skeleton.FlipY);
                    requireRepaint |= EditorGUI.EndChangeCheck();

//					foreach (var t in skeleton.IkConstraints)
//						EditorGUILayout.LabelField(t.Data.Name + " " + t.Mix + " " + t.Target.Data.Name);

                    showSlots.target = EditorGUILayout.Foldout(showSlots.target, SlotsRootLabel);
                    if (showSlots.faded > 0)
                    {
                        using (new EditorGUILayout.FadeGroupScope(showSlots.faded)) {
                            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(new GUIContent(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       = (attachment is MeshAttachment) ? Icons.mesh : Icons.image;
                                    bool isAttached = (attachment == slot.Attachment);
                                    bool swap       = EditorGUILayout.ToggleLeft(new GUIContent(attachment.Name, icon), attachment == slot.Attachment);
                                    if (isAttached != swap)
                                    {
                                        slot.Attachment = isAttached ? null : attachment;
                                        requireRepaint  = true;
                                    }
                                    GUI.contentColor = Color.white;
                                }
                            }
                        }
                    }
                }

                if (showSlots.isAnimating)
                {
                    Repaint();
                }
            }

            if (requireRepaint)
            {
                skeletonRenderer.LateUpdate();
                SceneView.RepaintAll();
            }
        }
        protected virtual void DrawInspectorGUI()
        {
            // JOHN: todo: support multiediting.
            SkeletonRenderer component = (SkeletonRenderer)target;

            using (new EditorGUILayout.HorizontalScope()) {
                EditorGUILayout.PropertyField(skeletonDataAsset);
                const string ReloadButtonLabel = "Reload";
                float        reloadWidth       = GUI.skin.label.CalcSize(new GUIContent(ReloadButtonLabel)).x + 20;
                if (GUILayout.Button(ReloadButtonLabel, GUILayout.Width(reloadWidth)))
                {
                    if (component.skeletonDataAsset != null)
                    {
                        foreach (AtlasAsset aa in component.skeletonDataAsset.atlasAssets)
                        {
                            if (aa != null)
                            {
                                aa.Reset();
                            }
                        }
                        component.skeletonDataAsset.Reset();
                    }
                    component.Initialize(true);
                }
            }

            if (!component.valid)
            {
                component.Initialize(true);
                component.LateUpdate();
                if (!component.valid)
                {
                    return;
                }
            }

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

            if (isInspectingPrefab)
            {
                meshFilter.sharedMesh = null;
            }
                        #endif

            // Initial skin name.
            {
                string[] skins     = new string[component.skeleton.Data.Skins.Count];
                int      skinIndex = 0;
                for (int i = 0; i < skins.Length; i++)
                {
                    string skinNameString = component.skeleton.Data.Skins.Items[i].Name;
                    skins[i] = skinNameString;
                    if (skinNameString == initialSkinName.stringValue)
                    {
                        skinIndex = i;
                    }
                }
                skinIndex = EditorGUILayout.Popup("Initial Skin", skinIndex, skins);
                initialSkinName.stringValue = skins[skinIndex];
            }

            EditorGUILayout.Space();

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

            // More Render Options...
            using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) {
                EditorGUI.indentLevel++;
                advancedFoldout = EditorGUILayout.Foldout(advancedFoldout, "Advanced");
                if (advancedFoldout)
                {
                    EditorGUI.indentLevel++;
                    SeparatorsField(separatorSlotNames);
                    EditorGUILayout.PropertyField(meshes,
                                                  new GUIContent("Render MeshAttachments", "Disable to optimize rendering for skeletons that don't use Mesh Attachments"));
                    EditorGUILayout.PropertyField(immutableTriangles,
                                                  new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility"));
                    EditorGUILayout.Space();

                    const float MinZSpacing = -0.1f;
                    const float MaxZSpacing = 0f;
                    EditorGUILayout.Slider(zSpacing, MinZSpacing, MaxZSpacing);

                    // Optional fields. May be disabled in SkeletonRenderer.
                    if (normals != null)
                    {
                        EditorGUILayout.PropertyField(normals, new GUIContent("Add Normals"));
                    }
                    if (tangents != null)
                    {
                        EditorGUILayout.PropertyField(tangents, new GUIContent("Solve Tangents"));
                    }
                    if (frontFacing != null)
                    {
                        EditorGUILayout.PropertyField(frontFacing);
                    }

                    EditorGUI.indentLevel--;
                }
                EditorGUI.indentLevel--;
            }
        }
    protected virtual void DrawInspectorGUI()
    {
        SkeletonRenderer component = (SkeletonRenderer)target;

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.PropertyField(skeletonDataAsset);
        float reloadWidth = GUI.skin.label.CalcSize(new GUIContent("Reload")).x + 20;

        if (GUILayout.Button("Reload", GUILayout.Width(reloadWidth)))
        {
            if (component.skeletonDataAsset != null)
            {
                foreach (AtlasAsset aa in component.skeletonDataAsset.atlasAssets)
                {
                    if (aa != null)
                    {
                        aa.Reset();
                    }
                }

                component.skeletonDataAsset.Reset();
            }
            component.Initialize(true);
        }
        EditorGUILayout.EndHorizontal();

        if (!component.valid)
        {
            component.Initialize(true);
            component.LateUpdate();
            if (!component.valid)
            {
                return;
            }
        }

        // Initial skin name.
        {
            String[] skins     = new String[component.skeleton.Data.Skins.Count];
            int      skinIndex = 0;
            for (int i = 0; i < skins.Length; i++)
            {
                String name = component.skeleton.Data.Skins.Items[i].Name;
                skins[i] = name;
                if (name == initialSkinName.stringValue)
                {
                    skinIndex = i;
                }
            }

            skinIndex = EditorGUILayout.Popup("Initial Skin", skinIndex, skins);
            initialSkinName.stringValue = skins[skinIndex];
        }

        EditorGUILayout.Space();

        // Sorting Layers
        {
            var renderer = component.GetComponent <Renderer>();
            if (renderer != null)
            {
                EditorGUI.BeginChangeCheck();

                if (EditorGUILayoutSortingLayerField != null && sortingLayerIDProperty != null)
                {
                    EditorGUILayoutSortingLayerField.Invoke(null, new object[] { new GUIContent("Sorting Layer"), sortingLayerIDProperty, EditorStyles.popup });
                }
                else
                {
                    renderer.sortingLayerID = EditorGUILayout.IntField("Sorting Layer ID", renderer.sortingLayerID);
                }

                renderer.sortingOrder = EditorGUILayout.IntField("Order in Layer", renderer.sortingOrder);

                if (EditorGUI.EndChangeCheck())
                {
                    rendererSerializedObject.ApplyModifiedProperties();
                    EditorUtility.SetDirty(renderer);
                }
            }
        }

        // More Render Options...
        {
            advancedFoldout = EditorGUILayout.Foldout(advancedFoldout, "Advanced");
            if (advancedFoldout)
            {
                EditorGUI.indentLevel++;
                EditorGUILayout.PropertyField(submeshSeparators, true);
                EditorGUILayout.Space();
                EditorGUILayout.PropertyField(meshes,
                                              new GUIContent("Render Mesh Attachments", "Disable to optimize rendering for skeletons that don't use Mesh Attachments"));
                EditorGUILayout.PropertyField(immutableTriangles,
                                              new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility"));
                EditorGUILayout.Space();

                const float MinZSpacing = -0.1f;
                const float MaxZSpacing = 0f;
                EditorGUILayout.Slider(zSpacing, MinZSpacing, MaxZSpacing);

                EditorGUILayout.PropertyField(normals);
                EditorGUILayout.PropertyField(tangents);
                EditorGUILayout.PropertyField(front);
                EditorGUILayout.Separator();
                EditorGUI.indentLevel--;
            }
        }
    }
    protected virtual void gui()
    {
        SkeletonRenderer component = (SkeletonRenderer)target;

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.PropertyField(skeletonDataAsset);
        float reloadWidth = GUI.skin.label.CalcSize(new GUIContent("Reload")).x + 20;

        if (GUILayout.Button("Reload", GUILayout.Width(reloadWidth)))
        {
            if (component.skeletonDataAsset != null)
            {
                foreach (AtlasAsset aa in component.skeletonDataAsset.atlasAssets)
                {
                    if (aa != null)
                    {
                        aa.Reset();
                    }
                }

                component.skeletonDataAsset.Reset();
            }
            component.Reset();
        }
        EditorGUILayout.EndHorizontal();

        if (!component.valid)
        {
            component.Reset();
            component.LateUpdate();
            if (!component.valid)
            {
                return;
            }
        }

        // Initial skin name.
        {
            String[] skins     = new String[component.skeleton.Data.Skins.Count];
            int      skinIndex = 0;
            for (int i = 0; i < skins.Length; i++)
            {
                String name = component.skeleton.Data.Skins[i].Name;
                skins[i] = name;
                if (name == initialSkinName.stringValue)
                {
                    skinIndex = i;
                }
            }

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Initial Skin", GUILayout.Width(EditorGUIUtility.labelWidth));
            skinIndex = EditorGUILayout.Popup(skinIndex, skins);
            EditorGUILayout.EndHorizontal();

            initialSkinName.stringValue = skins[skinIndex];
        }

        EditorGUILayout.PropertyField(meshes,
                                      new GUIContent("Render Meshes", "Disable to optimize rendering for skeletons that don't use meshes"));
        EditorGUILayout.PropertyField(immutableTriangles,
                                      new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility"));
        EditorGUILayout.PropertyField(normals);
        EditorGUILayout.PropertyField(tangents);
        EditorGUILayout.PropertyField(submeshSeparators, true);
    }
        protected virtual void DrawInspectorGUI()
        {
            SkeletonRenderer component = (SkeletonRenderer)target;

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(skeletonDataAsset);
            float reloadWidth = GUI.skin.label.CalcSize(new GUIContent("Reload")).x + 20;

            if (GUILayout.Button("Reload", GUILayout.Width(reloadWidth)))
            {
                if (component.skeletonDataAsset != null)
                {
                    foreach (AtlasAsset aa in component.skeletonDataAsset.atlasAssets)
                    {
                        if (aa != null)
                        {
                            aa.Reset();
                        }
                    }

                    component.skeletonDataAsset.Reset();
                }
                component.Initialize(true);
            }
            EditorGUILayout.EndHorizontal();

            if (!component.valid)
            {
                component.Initialize(true);
                component.LateUpdate();
                if (!component.valid)
                {
                    return;
                }
            }

            // Initial skin name.
            {
                String[] skins     = new String[component.skeleton.Data.Skins.Count];
                int      skinIndex = 0;
                for (int i = 0; i < skins.Length; i++)
                {
                    String skinNameString = component.skeleton.Data.Skins.Items[i].Name;
                    skins[i] = skinNameString;
                    if (skinNameString == initialSkinName.stringValue)
                    {
                        skinIndex = i;
                    }
                }

                skinIndex = EditorGUILayout.Popup("Initial Skin", skinIndex, skins);
                initialSkinName.stringValue = skins[skinIndex];
            }

            EditorGUILayout.Space();

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

            // More Render Options...
            {
                using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) {
                    EditorGUI.indentLevel++;
                    advancedFoldout = EditorGUILayout.Foldout(advancedFoldout, "Advanced");
                    if (advancedFoldout)
                    {
                        EditorGUI.indentLevel++;
                        SeparatorsField(separatorSlotNames);
                        EditorGUILayout.PropertyField(meshes,
                                                      new GUIContent("Render Mesh Attachments", "Disable to optimize rendering for skeletons that don't use Mesh Attachments"));
                        EditorGUILayout.PropertyField(immutableTriangles,
                                                      new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility"));
                        EditorGUILayout.Space();

                        const float MinZSpacing = -0.1f;
                        const float MaxZSpacing = 0f;
                        EditorGUILayout.Slider(zSpacing, MinZSpacing, MaxZSpacing);

                        if (normals != null)
                        {
                            EditorGUILayout.PropertyField(normals);
                            EditorGUILayout.PropertyField(tangents);
                        }

                        if (front != null)
                        {
                            EditorGUILayout.PropertyField(front);
                        }
                        EditorGUI.indentLevel--;
                    }
                    EditorGUI.indentLevel--;
                }
            }
        }