public override void OnInspectorGUI() { 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); bool hasRootBone = skeletonUtility.boneRoot != null; using (new EditorGUI.DisabledGroupScope(hasRootBone)) { if (SpineInspectorUtility.LargeCenteredButton(SpawnHierarchyButtonLabel)) { SpawnHierarchyContextMenu(); } } if (hasRootBone) { if (SpineInspectorUtility.CenteredButton(new GUIContent("Remove Hierarchy"))) { Undo.RegisterCompleteObjectUndo(skeletonUtility, "Remove Hierarchy"); Undo.DestroyObjectImmediate(skeletonUtility.boneRoot.gameObject); skeletonUtility.boneRoot = null; } } }
public override void OnInspectorGUI() { #if !NEW_PREFAB_SYSTEM if (isPrefab) { GUILayout.Label(new GUIContent("Cannot edit Prefabs", Icons.warning)); return; } #endif serializedObject.Update(); if ((skeletonRenderer != null && !skeletonRenderer.valid) || (skeletonGraphic != null && !skeletonGraphic.IsValid)) { GUILayout.Label(new GUIContent("Spine Component invalid. Check Skeleton Data Asset.", Icons.warning)); return; } EditorGUILayout.PropertyField(serializedObject.FindProperty("boneRoot"), SpineInspectorUtility.TempContent("Skeleton Root")); EditorGUILayout.PropertyField(serializedObject.FindProperty("flipBy180DegreeRotation"), SpineInspectorUtility.TempContent("Flip by Rotation", null, "If true, Skeleton.ScaleX and Skeleton.ScaleY are followed " + "by 180 degree rotation. If false, negative Transform scale is used. " + "Note that using negative scale is consistent with previous behaviour (hence the default), " + "however causes serious problems with rigidbodies and physics. Therefore, it is recommended to " + "enable this parameter where possible. When creating hinge chains for a chain of skeleton bones " + "via SkeletonUtilityBone, it is mandatory to have this parameter enabled.")); bool hasRootBone = skeletonUtility.boneRoot != null; if (!hasRootBone) { EditorGUILayout.HelpBox("No hierarchy found. Use Spawn Hierarchy to generate GameObjects for bones.", MessageType.Info); } using (new EditorGUI.DisabledGroupScope(hasRootBone)) { if (SpineInspectorUtility.LargeCenteredButton(SpawnHierarchyButtonLabel)) { SpawnHierarchyContextMenu(); } } if (hasRootBone) { if (SpineInspectorUtility.CenteredButton(new GUIContent("Remove Hierarchy"))) { Undo.RegisterCompleteObjectUndo(skeletonUtility, "Remove Hierarchy"); Undo.DestroyObjectImmediate(skeletonUtility.boneRoot.gameObject); skeletonUtility.boneRoot = null; } } serializedObject.ApplyModifiedProperties(); }
internal static void RecommendRigidbodyButton (Component component) { bool hasCollider2D = component.GetComponent<Collider2D>() != null || component.GetComponent<BoundingBoxFollower>() != null; bool hasCollider3D = !hasCollider2D && component.GetComponent<Collider>(); bool missingRigidBody = (hasCollider2D && component.GetComponent<Rigidbody2D>() == null) || (hasCollider3D && component.GetComponent<Rigidbody>() == null); if (missingRigidBody) { using (new SpineInspectorUtility.BoxScope()) { EditorGUILayout.HelpBox("Collider detected. Unity recommends adding a Rigidbody to the Transforms of any colliders that are intended to be dynamically repositioned and rotated.", MessageType.Warning); var rbType = hasCollider2D ? typeof(Rigidbody2D) : typeof(Rigidbody); string rbLabel = string.Format("Add {0}", rbType.Name); var rbContent = SpineInspectorUtility.TempContent(rbLabel, SpineInspectorUtility.UnityIcon(rbType), "Add a rigidbody to this GameObject to be the Physics body parent of the attached collider."); if (SpineInspectorUtility.CenteredButton(rbContent)) component.gameObject.AddComponent(rbType); } } }
public override void OnInspectorGUI() { #if !NEW_PREFAB_SYSTEM if (isPrefab) { GUILayout.Label(new GUIContent("Cannot edit Prefabs", Icons.warning)); return; } #endif if (!skeletonRenderer.valid) { GUILayout.Label(new GUIContent("Spine Component invalid. Check Skeleton Data Asset.", Icons.warning)); return; } EditorGUILayout.PropertyField(serializedObject.FindProperty("boneRoot"), SpineInspectorUtility.TempContent("Skeleton Root")); bool hasRootBone = skeletonUtility.boneRoot != null; if (!hasRootBone) { EditorGUILayout.HelpBox("No hierarchy found. Use Spawn Hierarchy to generate GameObjects for bones.", MessageType.Info); } using (new EditorGUI.DisabledGroupScope(hasRootBone)) { if (SpineInspectorUtility.LargeCenteredButton(SpawnHierarchyButtonLabel)) { SpawnHierarchyContextMenu(); } } if (hasRootBone) { if (SpineInspectorUtility.CenteredButton(new GUIContent("Remove Hierarchy"))) { Undo.RegisterCompleteObjectUndo(skeletonUtility, "Remove Hierarchy"); Undo.DestroyObjectImmediate(skeletonUtility.boneRoot.gameObject); skeletonUtility.boneRoot = null; } } }
void HandleAtlasAssetsNulls() { bool hasNulls = false; foreach (var a in targetSkeletonDataAsset.atlasAssets) { if (a == null) { hasNulls = true; break; } } if (hasNulls) { if (targetSkeletonDataAsset.atlasAssets.Length == 1) { EditorGUILayout.HelpBox("Atlas array cannot have null entries!", MessageType.None); } else { EditorGUILayout.HelpBox("Atlas array should not have null entries!", MessageType.Error); if (SpineInspectorUtility.CenteredButton(SpineInspectorUtility.TempContent("Remove null entries"))) { var trimmedAtlasAssets = new List <AtlasAsset>(); foreach (var a in targetSkeletonDataAsset.atlasAssets) { if (a != null) { trimmedAtlasAssets.Add(a); } } targetSkeletonDataAsset.atlasAssets = trimmedAtlasAssets.ToArray(); serializedObject.Update(); } } } }
override public void OnInspectorGUI() { if (serializedObject.isEditingMultipleObjects) { using (new SpineInspectorUtility.BoxScope()) { EditorGUILayout.LabelField("SkeletonData", EditorStyles.boldLabel); EditorGUILayout.PropertyField(skeletonJSON, SpineInspectorUtility.TempContent(skeletonJSON.displayName, Icons.spine)); EditorGUILayout.PropertyField(scale); } using (new SpineInspectorUtility.BoxScope()) { EditorGUILayout.LabelField("Atlas", EditorStyles.boldLabel); #if !SPINE_TK2D EditorGUILayout.PropertyField(atlasAssets, true); #else using (new EditorGUI.DisabledGroupScope(spriteCollection.objectReferenceValue != null)) { EditorGUILayout.PropertyField(atlasAssets, true); } EditorGUILayout.LabelField("spine-tk2d", EditorStyles.boldLabel); EditorGUILayout.PropertyField(spriteCollection, true); #endif } using (new SpineInspectorUtility.BoxScope()) { EditorGUILayout.LabelField("Mix Settings", EditorStyles.boldLabel); SpineInspectorUtility.PropertyFieldWideLabel(defaultMix, DefaultMixLabel, 160); EditorGUILayout.Space(); } return; } { // Lazy initialization because accessing EditorStyles values in OnEnable during a recompile causes UnityEditor to throw null exceptions. (Unity 5.3.5) idlePlayButtonStyle = idlePlayButtonStyle ?? new GUIStyle(EditorStyles.miniButton); if (activePlayButtonStyle == null) { activePlayButtonStyle = new GUIStyle(idlePlayButtonStyle); activePlayButtonStyle.normal.textColor = Color.red; } } serializedObject.Update(); EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(target.name + " (SkeletonDataAsset)", Icons.spine), EditorStyles.whiteLargeLabel); if (m_skeletonData != null) { EditorGUILayout.LabelField("(Drag and Drop to instantiate.)", EditorStyles.miniLabel); } EditorGUI.BeginChangeCheck(); // SkeletonData using (new SpineInspectorUtility.BoxScope()) { using (new EditorGUILayout.HorizontalScope()) { EditorGUILayout.LabelField("SkeletonData", EditorStyles.boldLabel); if (m_skeletonData != null) { var sd = m_skeletonData; string m = string.Format("{8} - {0} {1}\nBones: {2}\nConstraints: \n {5} IK \n {6} Path \n {7} Transform\n\nSlots: {3}\nSkins: {4}\n\nAnimations: {9}", sd.Version, string.IsNullOrEmpty(sd.Version) ? "" : "export ", sd.Bones.Count, sd.Slots.Count, sd.Skins.Count, sd.IkConstraints.Count, sd.PathConstraints.Count, sd.TransformConstraints.Count, skeletonJSON.objectReferenceValue.name, sd.Animations.Count); EditorGUILayout.LabelField(GUIContent.none, new GUIContent(Icons.info, m), GUILayout.Width(30f)); } } EditorGUILayout.PropertyField(skeletonJSON, SpineInspectorUtility.TempContent(skeletonJSON.displayName, Icons.spine)); EditorGUILayout.PropertyField(scale); } // if (m_skeletonData != null) { // if (SpineInspectorUtility.CenteredButton(new GUIContent("Instantiate", Icons.spine, "Creates a new Spine GameObject in the active scene using this Skeleton Data.\nYou can also instantiate by dragging the SkeletonData asset from Project view into Scene View."))) // SpineEditorUtilities.ShowInstantiateContextMenu(this.m_skeletonDataAsset, Vector3.zero); // } // Atlas using (new SpineInspectorUtility.BoxScope()) { EditorGUILayout.LabelField("Atlas", EditorStyles.boldLabel); #if !SPINE_TK2D EditorGUILayout.PropertyField(atlasAssets, true); #else using (new EditorGUI.DisabledGroupScope(spriteCollection.objectReferenceValue != null)) { EditorGUILayout.PropertyField(atlasAssets, true); } EditorGUILayout.LabelField("spine-tk2d", EditorStyles.boldLabel); EditorGUILayout.PropertyField(spriteCollection, true); #endif { bool hasNulls = false; foreach (var a in m_skeletonDataAsset.atlasAssets) { if (a == null) { hasNulls = true; break; } } if (hasNulls) { if (m_skeletonDataAsset.atlasAssets.Length == 1) { EditorGUILayout.HelpBox("Atlas array cannot have null entries!", MessageType.None); } else { EditorGUILayout.HelpBox("Atlas array should not have null entries!", MessageType.Error); if (SpineInspectorUtility.CenteredButton(SpineInspectorUtility.TempContent("Remove null entries"))) { var trimmedAtlasAssets = new List <AtlasAsset>(); foreach (var a in m_skeletonDataAsset.atlasAssets) { if (a != null) { trimmedAtlasAssets.Add(a); } } m_skeletonDataAsset.atlasAssets = trimmedAtlasAssets.ToArray(); serializedObject.Update(); } } } } } if (EditorGUI.EndChangeCheck()) { if (serializedObject.ApplyModifiedProperties()) { if (m_previewUtility != null) { m_previewUtility.Cleanup(); m_previewUtility = null; } m_skeletonDataAsset.Clear(); m_skeletonData = null; OnEnable(); // Should call RepopulateWarnings. return; } } // Some code depends on the existence of m_skeletonAnimation instance. // If m_skeletonAnimation is lazy-instantiated elsewhere, this can cause contents to change between Layout and Repaint events, causing GUILayout control count errors. InitPreview(); if (m_skeletonData != null) { GUILayout.Space(20f); using (new SpineInspectorUtility.BoxScope(false)) { EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Mix Settings", Icons.animationRoot), EditorStyles.boldLabel); DrawAnimationStateInfo(); EditorGUILayout.Space(); } EditorGUILayout.LabelField("Preview", EditorStyles.boldLabel); DrawAnimationList(); EditorGUILayout.Space(); DrawSlotList(); EditorGUILayout.Space(); DrawUnityTools(); } else { #if !SPINE_TK2D // Reimport Button using (new EditorGUI.DisabledGroupScope(skeletonJSON.objectReferenceValue == null)) { if (GUILayout.Button(SpineInspectorUtility.TempContent("Attempt Reimport", Icons.warning))) { DoReimport(); } } #else EditorGUILayout.HelpBox("Couldn't load SkeletonData.", MessageType.Error); #endif // List warnings. foreach (var line in warnings) { EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(line, Icons.warning)); } } if (!Application.isPlaying) { serializedObject.ApplyModifiedProperties(); } }
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(); } } }
// 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() { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(skeletonDataAsset); 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; } using (new SpineInspectorUtility.BoxScope()) { EditorGUILayout.PropertyField(meshGeneratorSettings, SpineInspectorUtility.TempContent("Advanced..."), includeChildren: true); SkeletonRendererInspector.advancedFoldout = meshGeneratorSettings.isExpanded; } 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(); 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>(); } } } } bool wasChanged = EditorGUI.EndChangeCheck(); if (wasChanged) { serializedObject.ApplyModifiedProperties(); } }
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; } }
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) { 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(); } } }