[unity] Make SkeletonDebug an EditorWindow.

This commit is contained in:
pharan 2017-05-16 06:03:05 +08:00
parent 7d8c2a8771
commit 742ffe5497
24 changed files with 696 additions and 168 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

View File

@ -0,0 +1,92 @@
fileFormatVersion: 2
guid: 02822eb69e09dd947b434ab81e3d938f
timeCreated: 1494878353
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Android
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: WebGL
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

View File

@ -0,0 +1,92 @@
fileFormatVersion: 2
guid: c1aae98dd56b14c4b8c25360000b7e9e
timeCreated: 1494878353
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Android
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: WebGL
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

View File

@ -0,0 +1,92 @@
fileFormatVersion: 2
guid: 4709175437c21f64bab9b061f98a49fc
timeCreated: 1494878353
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Android
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: WebGL
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

View File

@ -0,0 +1,92 @@
fileFormatVersion: 2
guid: ed0736a1eb519ef42b4892d1db2426b3
timeCreated: 1494878353
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Android
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: WebGL
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 634 B

View File

@ -1,13 +1,15 @@
fileFormatVersion: 2
guid: bfd9f3d2607e9e44c97384d7575a17dc
timeCreated: 1494878353
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
@ -15,14 +17,12 @@ TextureImporter:
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
generateCubemap: 6
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 1024
@ -33,20 +33,59 @@ TextureImporter:
wrapMode: 1
nPOTScale: 0
lightmap: 0
rGBM: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: .5, y: .5}
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
buildTargetSettings: []
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 1024
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 1024
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Android
maxTextureSize: 1024
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: WebGL
maxTextureSize: 1024
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 790 B

After

Width:  |  Height:  |  Size: 672 B

View File

@ -95,8 +95,6 @@ namespace Spine.Unity.Editor {
SceneView.RepaintAll();
requireRepaint = false;
}
DrawSkeletonUtilityButton(multi);
}
}

View File

@ -49,9 +49,6 @@ namespace Spine.Unity.Editor {
base.DrawInspectorGUI(multi);
EditorGUILayout.PropertyField(autoReset);
EditorGUILayout.PropertyField(layerMixModes, true);
if (!TargetIsValid) return;
if (!isInspectingPrefab)
DrawSkeletonUtilityButton(multi);
}
}
}

View File

@ -33,49 +33,85 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Spine.Unity.Modules;
using UnityEditor.AnimatedValues;
namespace Spine.Unity.Editor {
using Editor = UnityEditor.Editor;
using Icons = SpineEditorUtilities.Icons;
[CustomEditor(typeof(SkeletonDebug))]
public class SkeletonDebugEditor : Editor {
public class SkeletonDebugWindow : EditorWindow {
const bool IsUtilityWindow = true;
[MenuItem("CONTEXT/SkeletonRenderer/Open Skeleton Debug Window", false, 5000)]
public static void Init () {
var window = EditorWindow.GetWindow<SkeletonDebugWindow>(IsUtilityWindow);
window.minSize = new Vector2(330f, 360f);
window.maxSize = new Vector2(600f, 4000f);
window.titleContent = new GUIContent("Skeleton Debug", Icons.spine);
window.Show();
window.OnSelectionChange();
}
static AnimBool showSlotsTree = new AnimBool(false);
static AnimBool showSkeleton = new AnimBool(true);
static AnimBool showSlotsTree = new AnimBool(false);
static AnimBool showConstraintsTree = new AnimBool(false);
static AnimBool showDrawOrderTree = new AnimBool(false);
static AnimBool showEventDataTree = new AnimBool(false);
static AnimBool showInspectBoneTree = new AnimBool(false);
protected static bool showBoneNames, showPaths = true, showShapes = true, showConstraints = true;
Vector2 scrollPos;
GUIContent SlotsRootLabel, SkeletonRootLabel;
GUIStyle BoldFoldoutStyle;
SkeletonDebug skeletonDebug;
SkeletonRenderer skeletonRenderer;
public SkeletonRenderer skeletonRenderer;
Skeleton skeleton;
Skin activeSkin;
bool isPrefab;
SerializedProperty bpo;
Bone bone;
[SpineBone(dataField:"skeletonRenderer")]
public string boneName;
readonly Dictionary<Slot, List<Attachment>> attachmentTable = new Dictionary<Slot, List<Attachment>>();
#region Menus
[MenuItem("CONTEXT/SkeletonRenderer/Debug with SkeletonDebug", false, 5000)]
static void AddSkeletonDebug (MenuCommand command) {
var go = ((SkeletonRenderer)command.context).gameObject;
go.AddComponent<SkeletonDebug>();
Undo.RegisterCreatedObjectUndo(go, "Add SkeletonDebug");
}
#endregion
void OnSelectionChange () {
bool noSkeletonRenderer = false;
void OnEnable () {
Initialize();
var selectedObject = Selection.activeGameObject;
if (selectedObject == null) {
noSkeletonRenderer = true;
} else {
var selectedSkeletonRenderer = selectedObject.GetComponent<SkeletonRenderer>();
if (selectedSkeletonRenderer == null) {
noSkeletonRenderer = true;
} else if (skeletonRenderer != selectedSkeletonRenderer) {
skeletonRenderer = selectedSkeletonRenderer;
skeletonRenderer.Initialize(false);
skeletonRenderer.LateUpdate();
skeleton = skeletonRenderer.skeleton;
isPrefab |= PrefabUtility.GetPrefabType(selectedObject) == PrefabType.Prefab;
UpdateAttachments();
}
}
if (noSkeletonRenderer) {
skeletonRenderer = null;
skeleton = null;
attachmentTable.Clear();
isPrefab = false;
boneName = string.Empty;
bone = null;
}
Repaint();
}
void Initialize () {
void OnGUI () {
if (SlotsRootLabel == null) {
SlotsRootLabel = new GUIContent("Slots", Icons.slotRoot);
SkeletonRootLabel = new GUIContent("Skeleton", Icons.skeleton);
@ -85,39 +121,13 @@ namespace Spine.Unity.Editor {
BoldFoldoutStyle.fixedWidth = 0;
}
if (skeleton == null) {
skeletonDebug = (SkeletonDebug)target;
skeletonRenderer = skeletonDebug.GetComponent<SkeletonRenderer>();
skeletonRenderer.Initialize(false);
skeletonRenderer.LateUpdate();
skeleton = skeletonRenderer.skeleton;
}
if (attachmentTable.Count == 0) UpdateAttachments();
if (!skeletonRenderer.valid) return;
isPrefab |= PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab;
}
public void OnSceneGUI () {
var transform = skeletonRenderer.transform;
if (skeleton == null) return;
if (isPrefab) return;
if (showPaths) SpineHandles.DrawPaths(transform, skeleton);
if (showConstraints) SpineHandles.DrawConstraints(transform, skeleton);
if (showBoneNames) SpineHandles.DrawBoneNames(transform, skeleton);
if (showShapes) SpineHandles.DrawBoundingBoxes(transform, skeleton);
}
public override void OnInspectorGUI () {
Initialize();
bool requireRepaint = false;
EditorGUILayout.Space();
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.ObjectField("Debug Selection", skeletonRenderer, typeof(SkeletonRenderer), true);
EditorGUI.EndDisabledGroup();
if (skeletonRenderer.skeleton != skeleton || activeSkin != skeleton.Skin) {
UpdateAttachments();
}
if (skeleton == null || skeletonRenderer == null || !skeletonRenderer.valid) return;
if (isPrefab) {
GUILayout.Label(new GUIContent("Cannot edit Prefabs", Icons.warning));
@ -129,37 +139,96 @@ namespace Spine.Unity.Editor {
return;
}
EditorGUILayout.HelpBox("This is a debug component. Changes are not serialized.", MessageType.Info);
if (activeSkin != skeleton.Skin)
UpdateAttachments();
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
using (new SpineInspectorUtility.BoxScope(false)) {
if (SpineInspectorUtility.CenteredButton(new GUIContent("Skeleton.SetToSetupPose()"))) {
skeleton.SetToSetupPose();
requireRepaint = true;
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.LabelField("Scene View", EditorStyles.boldLabel);
using (new SpineInspectorUtility.LabelWidthScope()) {
SkeletonRendererInspector.showBoneNames = EditorGUILayout.Toggle("Show Bone Names", SkeletonRendererInspector.showBoneNames);
SkeletonRendererInspector.showPaths = EditorGUILayout.Toggle("Show Paths", SkeletonRendererInspector.showPaths);
SkeletonRendererInspector.showShapes = EditorGUILayout.Toggle("Show Shapes", SkeletonRendererInspector.showShapes);
SkeletonRendererInspector.showConstraints = EditorGUILayout.Toggle("Show Constraints", SkeletonRendererInspector.showConstraints);
}
requireRepaint |= EditorGUI.EndChangeCheck();
using (new SpineInspectorUtility.BoxScope()) {
// Skeleton
showSkeleton.target = EditorGUILayout.Foldout(showSkeleton.target, SkeletonRootLabel, BoldFoldoutStyle);
if (showSkeleton.faded > 0) {
using (new EditorGUILayout.FadeGroupScope(showSkeleton.faded)) {
using (new SpineInspectorUtility.IndentScope()) {
using (new SpineInspectorUtility.IndentScope()) {
using (new EditorGUILayout.FadeGroupScope(showSkeleton.faded)) {
EditorGUI.BeginChangeCheck();
skeleton.SetColor(EditorGUILayout.ColorField(".R .G .B .A", skeleton.GetColor()));
skeleton.FlipX = EditorGUILayout.ToggleLeft(".FlipX", skeleton.FlipX);
skeleton.FlipY = EditorGUILayout.ToggleLeft(".FlipY", skeleton.FlipY);
EditorGUILayout.Space();
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);
}
// Flip
EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(160f));
EditorGUILayout.LabelField("Flip", GUILayout.MaxWidth(EditorGUIUtility.labelWidth - 20f));
skeleton.FlipX = EditorGUILayout.ToggleLeft(".FlipX", skeleton.FlipX, GUILayout.MaxWidth(70f));
skeleton.FlipY = EditorGUILayout.ToggleLeft(".FlipY", skeleton.FlipY, GUILayout.MaxWidth(70f));
GUILayout.EndHorizontal();
// Color
skeleton.SetColor(EditorGUILayout.ColorField(".R .G .B .A", skeleton.GetColor()));
requireRepaint |= EditorGUI.EndChangeCheck();
}
}
}
// Bone
showInspectBoneTree.target = EditorGUILayout.Foldout(showInspectBoneTree.target, new GUIContent("Bone", Icons.bone), BoldFoldoutStyle);
if (showInspectBoneTree.faded > 0) {
using (new SpineInspectorUtility.IndentScope()) {
using (new EditorGUILayout.FadeGroupScope(showInspectBoneTree.faded)) {
if (bpo == null) bpo = new SerializedObject(this).FindProperty("boneName");
EditorGUILayout.PropertyField(bpo);
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 boneParent = bone.Parent;
if (boneParent != null) EditorGUILayout.TextField("parent", boneParent.Data.Name);
EditorGUILayout.Space();
EditorGUILayout.Slider("Local Rotation", bone.Rotation, -180f, 180f);
EditorGUILayout.Vector2Field("Local Position", new Vector2(bone.X, bone.Y));
EditorGUILayout.Vector2Field("Local Scale", new Vector2(bone.ScaleX, bone.ScaleY));
EditorGUILayout.Vector2Field("Local Shear", new Vector2(bone.ShearX, bone.ShearY));
// EditorGUILayout.Space();
// EditorGUILayout.LabelField("LocalToWorld Matrix");
// EditorGUILayout.Vector2Field("AB", new Vector2(bone.A, bone.B));
// EditorGUILayout.Vector2Field("CD", new Vector2(bone.C, bone.D));
}
}
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(new GUIContent("Skeleton.SetSlotsToSetupPose()"))) {
skeleton.SetSlotsToSetupPose();
requireRepaint = true;
}
int baseIndent = EditorGUI.indentLevel;
foreach (KeyValuePair<Slot, List<Attachment>> pair in attachmentTable) {
Slot slot = pair.Key;
@ -194,22 +263,22 @@ namespace Spine.Unity.Editor {
// Constraints
const string NoneText = "<none>";
showConstraintsTree.target = EditorGUILayout.Foldout(showConstraintsTree.target, "Constraints", BoldFoldoutStyle);
showConstraintsTree.target = EditorGUILayout.Foldout(showConstraintsTree.target, new GUIContent("Constraints", Icons.constraintRoot), BoldFoldoutStyle);
if (showConstraintsTree.faded > 0) {
using (new EditorGUILayout.FadeGroupScope(showConstraintsTree.faded)) {
using (new SpineInspectorUtility.IndentScope()) {
using (new SpineInspectorUtility.IndentScope()) {
using (new EditorGUILayout.FadeGroupScope(showConstraintsTree.faded)) {
const float MixMin = 0f;
const float MixMax = 1f;
EditorGUILayout.LabelField(string.Format("IK Constraints ({0})", skeleton.IkConstraints.Count), EditorStyles.boldLabel);
EditorGUILayout.LabelField(new GUIContent(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(c.Data.Name);
EditorGUILayout.LabelField(new GUIContent(c.Data.Name, Icons.constraintIK));
EditorGUI.BeginChangeCheck();
c.BendDirection = EditorGUILayout.Toggle("Bend Direction Positive", c.BendDirection > 0) ? 1 : -1;
c.Mix = EditorGUILayout.Slider("Mix", c.Mix, MixMin, MixMax);
c.BendDirection = EditorGUILayout.Toggle("Bend Direction +", c.BendDirection > 0) ? 1 : -1;
if (EditorGUI.EndChangeCheck()) requireRepaint = true;
EditorGUILayout.Space();
@ -220,11 +289,11 @@ namespace Spine.Unity.Editor {
}
}
EditorGUILayout.LabelField(string.Format("Transform Constraints ({0})", skeleton.TransformConstraints.Count), EditorStyles.boldLabel);
EditorGUILayout.LabelField(new GUIContent(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(c.Data.Name);
EditorGUILayout.LabelField(new GUIContent(c.Data.Name, Icons.constraintTransform));
EditorGUI.BeginChangeCheck();
c.TranslateMix = EditorGUILayout.Slider("TranslateMix", c.TranslateMix, MixMin, MixMax);
@ -240,11 +309,11 @@ namespace Spine.Unity.Editor {
}
}
EditorGUILayout.LabelField(string.Format("Path Constraints ({0})", skeleton.PathConstraints.Count), EditorStyles.boldLabel);
EditorGUILayout.LabelField(new GUIContent(string.Format("Path Constraints ({0})", skeleton.PathConstraints.Count), Icons.constraintPath), EditorStyles.boldLabel);
using (new SpineInspectorUtility.IndentScope()) {
if (skeleton.PathConstraints.Count > 0) {
foreach (var c in skeleton.PathConstraints) {
EditorGUILayout.LabelField(c.Data.Name);
EditorGUILayout.LabelField(new GUIContent(c.Data.Name, Icons.constraintPath));
EditorGUILayout.LabelField("PositionMode." + c.Data.PositionMode);
EditorGUILayout.LabelField("SpacingMode." + c.Data.SpacingMode);
EditorGUILayout.LabelField("RotateMode." + c.Data.RotateMode);
@ -267,19 +336,69 @@ namespace Spine.Unity.Editor {
}
}
if (showSlotsTree.isAnimating || showSkeleton.isAnimating || showConstraintsTree.isAnimating)
showDrawOrderTree.target = EditorGUILayout.Foldout(showDrawOrderTree.target, new GUIContent("Draw Order and Separators", Icons.slotRoot), BoldFoldoutStyle);
if (showDrawOrderTree.faded > 0) {
using (new SpineInspectorUtility.IndentScope()) {
using (new EditorGUILayout.FadeGroupScope(showDrawOrderTree.faded)) {
if (Application.isPlaying) {
foreach (var slot in skeleton.DrawOrder) {
if (skeletonRenderer.separatorSlots.Contains(slot)) EditorGUILayout.LabelField("------");
EditorGUILayout.LabelField(new GUIContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false));
}
} else {
foreach (var slot in skeleton.DrawOrder) {
var slotNames = skeletonRenderer.separatorSlotNames;
for (int i = 0, n = slotNames.Length; i < n; i++) {
if (string.Equals(slotNames[i], slot.Data.Name, System.StringComparison.Ordinal)) {
EditorGUILayout.LabelField("------");
break;
}
}
EditorGUILayout.LabelField(new GUIContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false));
}
}
}
}
}
showEventDataTree.target = EditorGUILayout.Foldout(showEventDataTree.target, new GUIContent("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(new GUIContent(e.Name, Icons.userEvent));
}
} else {
EditorGUILayout.LabelField(NoneText);
}
}
}
}
if (IsAnimating(showSlotsTree, showSkeleton, showConstraintsTree, showDrawOrderTree, showEventDataTree, showInspectBoneTree))
Repaint();
}
if (requireRepaint) {
skeletonRenderer.LateUpdate();
Repaint();
SceneView.RepaintAll();
}
EditorGUILayout.EndScrollView();
}
static bool IsAnimating (params AnimBool[] animBools) {
foreach (var a in animBools)
if (a.isAnimating) return true;
return false;
}
void UpdateAttachments () {
skeleton = skeletonRenderer.skeleton;
//skeleton = skeletonRenderer.skeleton;
Skin defaultSkin = skeleton.Data.DefaultSkin;
Skin skin = skeleton.Skin ?? defaultSkin;
bool notDefaultSkin = skin != defaultSkin;
@ -294,8 +413,5 @@ namespace Spine.Unity.Editor {
activeSkin = skeleton.Skin;
}
}
}

View File

@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: 7b337e07bc016684dabf04793dd00ea3
timeCreated: 1494814889
guid: 7093e73ff3cf6c543ac5865980070b49
timeCreated: 1494837950
licenseType: Free
MonoImporter:
serializedVersion: 2

View File

@ -36,11 +36,13 @@ using UnityEngine;
namespace Spine.Unity.Editor {
using Event = UnityEngine.Event;
using Icons = SpineEditorUtilities.Icons;
[CustomEditor(typeof(SkeletonRenderer))]
[CanEditMultipleObjects]
public class SkeletonRendererInspector : UnityEditor.Editor {
protected static bool advancedFoldout;
internal static bool showBoneNames, showPaths, showShapes, showConstraints = true;
protected SerializedProperty skeletonDataAsset, initialSkinName;
protected SerializedProperty initialFlipX, initialFlipY;
@ -76,8 +78,8 @@ namespace Spine.Unity.Editor {
SpineEditorUtilities.ConfirmInitialization();
// Labels
SkeletonDataAssetLabel = new GUIContent("SkeletonData Asset", SpineEditorUtilities.Icons.spine);
SkeletonUtilityButtonContent = new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility);
SkeletonDataAssetLabel = new GUIContent("SkeletonData Asset", Icons.spine);
SkeletonUtilityButtonContent = new GUIContent("Add Skeleton Utility", Icons.skeletonUtility);
MeshesLabel = new GUIContent("Render MeshAttachments", "Disable to optimize rendering for skeletons that don't use Mesh Attachments");
ImmubleTrianglesLabel = new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility");
PMAVertexColorsLabel = new GUIContent("PMA Vertex Colors", "Use this if you are using the default Spine/Skeleton shader or any premultiply-alpha shader.");
@ -93,7 +95,7 @@ namespace Spine.Unity.Editor {
initialSkinName = so.FindProperty("initialSkinName");
initialFlipX = so.FindProperty("initialFlipX");
initialFlipY = so.FindProperty("initialFlipY");
normals = so.FindProperty("calculateNormals");
normals = so.FindProperty("addNormals");
tangents = so.FindProperty("calculateTangents");
meshes = so.FindProperty("renderMeshes");
immutableTriangles = so.FindProperty("immutableTriangles");
@ -238,7 +240,20 @@ namespace Spine.Unity.Editor {
// More Render Options...
using (new SpineInspectorUtility.BoxScope()) {
EditorGUI.BeginChangeCheck();
if (advancedFoldout = EditorGUILayout.Foldout(advancedFoldout, "Advanced")) {
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));
@ -247,7 +262,7 @@ namespace Spine.Unity.Editor {
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Renderer Settings", EditorStyles.boldLabel);
using (new SpineInspectorUtility.LabelWidthScope()) {
// Optimization options
if (singleSubmesh != null) EditorGUILayout.PropertyField(singleSubmesh, SingleSubmeshLabel);
@ -277,8 +292,30 @@ namespace Spine.Unity.Editor {
}
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();
}
@ -308,6 +345,13 @@ namespace Spine.Unity.Editor {
const string SeparatorsDescription = "Stored names of slots where the Skeleton's render will be split into different batches. This is used by separate components that split the render into different MeshRenderers or GameObjects.";
if (separatorSlotNames.isExpanded) {
EditorGUILayout.PropertyField(separatorSlotNames, new GUIContent(separatorSlotNames.displayName + terminalSlotWarning, SeparatorsDescription), true);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("+", GUILayout.MaxWidth(28f), GUILayout.MaxHeight(15f))) {
separatorSlotNames.arraySize++;
}
GUILayout.EndHorizontal();
EditorGUILayout.Space();
} else
EditorGUILayout.PropertyField(separatorSlotNames, new GUIContent(separatorSlotNames.displayName + string.Format("{0} [{1}]", terminalSlotWarning, separatorSlotNames.arraySize), SeparatorsDescription), true);
@ -318,30 +362,13 @@ namespace Spine.Unity.Editor {
var skeletonRenderer = (SkeletonRenderer)target;
var skeleton = skeletonRenderer.skeleton;
var transform = skeletonRenderer.transform;
if (skeleton == null) return;
if (showPaths) SpineHandles.DrawPaths(transform, skeleton);
SpineHandles.DrawBones(transform, skeleton);
}
public void DrawSkeletonUtilityButton (bool multi) {
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 {
EditorGUILayout.Space();
var component = (Component)target;
if (component.GetComponent<SkeletonUtility>() == null) {
if (SpineInspectorUtility.CenteredButton(SkeletonUtilityButtonContent, 21))
component.gameObject.AddComponent<SkeletonUtility>();
}
}
if (showConstraints) SpineHandles.DrawConstraints(transform, skeleton);
if (showBoneNames) SpineHandles.DrawBoneNames(transform, skeleton);
if (showShapes) SpineHandles.DrawBoundingBoxes(transform, skeleton);
}
override public void OnInspectorGUI () {

View File

@ -70,6 +70,10 @@ namespace Spine.Unity.Editor {
public static Texture2D spine;
public static Texture2D userEvent;
public static Texture2D constraintNib;
public static Texture2D constraintRoot;
public static Texture2D constraintTransform;
public static Texture2D constraintPath;
public static Texture2D constraintIK;
public static Texture2D warning;
public static Texture2D skeletonUtility;
public static Texture2D hingeChain;
@ -97,6 +101,12 @@ namespace Spine.Unity.Editor {
spine = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-spine.png");
userEvent = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-event.png");
constraintNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-constraintNib.png");
constraintRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-constraints.png");
constraintTransform = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-constraintTransform.png");
constraintPath = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-constraintPath.png");
constraintIK = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-constraintIK.png");
warning = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-warning.png");
skeletonUtility = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skeletonUtility.png");
hingeChain = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-hingeChain.png");

View File

@ -140,12 +140,12 @@ namespace Spine.Unity.Editor {
}
}
public static bool LargeCenteredButton (string label, bool sideSpace = true) {
public static bool LargeCenteredButton (string label, bool sideSpace = true, float maxWidth = CenterButtonMaxWidth) {
if (sideSpace) {
bool clicked;
using (new EditorGUILayout.HorizontalScope()) {
EditorGUILayout.Space();
clicked = GUILayout.Button(label, SpineButtonStyle, GUILayout.MaxWidth(CenterButtonMaxWidth), GUILayout.Height(CenterButtonHeight));
clicked = GUILayout.Button(label, SpineButtonStyle, GUILayout.MaxWidth(maxWidth), GUILayout.Height(CenterButtonHeight));
EditorGUILayout.Space();
}
EditorGUILayout.Space();
@ -155,12 +155,12 @@ namespace Spine.Unity.Editor {
}
}
public static bool LargeCenteredButton (GUIContent content, bool sideSpace = true) {
public static bool LargeCenteredButton (GUIContent content, bool sideSpace = true, float maxWidth = CenterButtonMaxWidth) {
if (sideSpace) {
bool clicked;
using (new EditorGUILayout.HorizontalScope()) {
EditorGUILayout.Space();
clicked = GUILayout.Button(content, SpineButtonStyle, GUILayout.MaxWidth(CenterButtonMaxWidth), GUILayout.Height(CenterButtonHeight));
clicked = GUILayout.Button(content, SpineButtonStyle, GUILayout.MaxWidth(maxWidth), GUILayout.Height(CenterButtonHeight));
EditorGUILayout.Space();
}
EditorGUILayout.Space();
@ -170,18 +170,18 @@ namespace Spine.Unity.Editor {
}
}
public static bool CenteredButton (GUIContent content, float height = 20f, bool sideSpace = true) {
public static bool CenteredButton (GUIContent content, float height = 20f, bool sideSpace = true, float maxWidth = CenterButtonMaxWidth) {
if (sideSpace) {
bool clicked;
using (new EditorGUILayout.HorizontalScope()) {
EditorGUILayout.Space();
clicked = GUILayout.Button(content, GUILayout.MaxWidth(CenterButtonMaxWidth), GUILayout.Height(height));
clicked = GUILayout.Button(content, GUILayout.MaxWidth(maxWidth), GUILayout.Height(height));
EditorGUILayout.Space();
}
EditorGUILayout.Space();
return clicked;
} else {
return GUILayout.Button(content, GUILayout.MaxWidth(CenterButtonMaxWidth), GUILayout.Height(height));
return GUILayout.Button(content, GUILayout.MaxWidth(maxWidth), GUILayout.Height(height));
}
}
#endregion

View File

@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 061893380931ebd4f94376c54cdb60dc
folderAsset: yes
timeCreated: 1494814883
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 7e09f6de2e1bcbf4085ca3825dc89489
folderAsset: yes
timeCreated: 1494814895
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 3e60ef41778c8e84e958675f00ce83e8
timeCreated: 1494814901
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,6 +0,0 @@
using UnityEngine;
namespace Spine.Unity.Modules {
[DisallowMultipleComponent]
public class SkeletonDebug : MonoBehaviour { }
}

View File

@ -79,10 +79,19 @@ namespace Spine.Unity.Editor {
skeletonUtility.boneRoot = (Transform)EditorGUILayout.ObjectField("Bone Root", skeletonUtility.boneRoot, typeof(Transform), true);
using (new EditorGUI.DisabledGroupScope(skeletonUtility.boneRoot != null)) {
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;
}
}
}
void SpawnHierarchyContextMenu () {