diff --git a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs index 8fe388d2d..921cc53f8 100644 --- a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs +++ b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs @@ -285,45 +285,56 @@ namespace Spine.Unity.Editor { if (references.Length == 1) { var skeletonDataAsset = references[0] as SkeletonDataAsset; if (skeletonDataAsset != null) { - DragAndDrop.visualMode = DragAndDropVisualMode.Move; var mousePos = current.mousePosition; - Handles.BeginGUI(); - GUI.Label(new Rect(mousePos + new Vector2(20f, 20f), new Vector2(400f, 20f)), new GUIContent(string.Format("Create Spine GameObject ({0})", skeletonDataAsset.skeletonJSON.name), SpineEditorUtilities.Icons.spine)); - Handles.EndGUI(); + bool invalidSkeletonData = skeletonDataAsset.GetSkeletonData(true) == null; + if (invalidSkeletonData) { + DragAndDrop.visualMode = DragAndDropVisualMode.Rejected; + Handles.BeginGUI(); + GUI.Label(new Rect(mousePos + new Vector2(20f, 20f), new Vector2(400f, 40f)), new GUIContent(string.Format("{0} is invalid.\nCannot create new Spine GameObject.", skeletonDataAsset.name), SpineEditorUtilities.Icons.warning)); + Handles.EndGUI(); + return; + } else { + DragAndDrop.visualMode = DragAndDropVisualMode.Copy; + Handles.BeginGUI(); + GUI.Label(new Rect(mousePos + new Vector2(20f, 20f), new Vector2(400f, 20f)), new GUIContent(string.Format("Create Spine GameObject ({0})", skeletonDataAsset.skeletonJSON.name), SpineEditorUtilities.Icons.spine)); + Handles.EndGUI(); - if (current.type == EventType.DragPerform) { - var spawnPoint = MousePointToWorldPoint2D(mousePos, sceneview.camera); + if (current.type == EventType.DragPerform) { + RectTransform rectTransform = (Selection.activeGameObject == null) ? null : Selection.activeGameObject.GetComponent(); + Plane plane = (rectTransform == null) ? new Plane(Vector3.back, Vector3.zero) : new Plane(-rectTransform.forward, rectTransform.position); + Vector3 spawnPoint = MousePointToWorldPoint2D(mousePos, sceneview.camera, plane); - var menu = new GenericMenu(); - // JOHN: todo: Get rect space spawnPoint if RectTransform is selected. - menu.AddItem(new GUIContent("SkeletonAnimation"), false, HandleSkeletonComponentDrop, new SpawnMenuData { - skeletonDataAsset = skeletonDataAsset, - spawnPoint = spawnPoint, - instantiateDelegate = (data) => InstantiateSkeletonAnimation(data) - }); - - foreach (var spawnType in additionalSpawnTypes) { - menu.AddItem(new GUIContent(spawnType.menuLabel), false, HandleSkeletonComponentDrop, new SpawnMenuData { + var menu = new GenericMenu(); + menu.AddItem(new GUIContent("SkeletonAnimation"), false, HandleSkeletonComponentDrop, new SpawnMenuData { skeletonDataAsset = skeletonDataAsset, spawnPoint = spawnPoint, - instantiateDelegate = spawnType.instantiateDelegate, - isUI = spawnType.isUI + instantiateDelegate = (data) => InstantiateSkeletonAnimation(data) }); + + foreach (var spawnType in additionalSpawnTypes) { + menu.AddItem(new GUIContent(spawnType.menuLabel), false, HandleSkeletonComponentDrop, new SpawnMenuData { + skeletonDataAsset = skeletonDataAsset, + spawnPoint = spawnPoint, + instantiateDelegate = spawnType.instantiateDelegate, + isUI = spawnType.isUI + }); + } + + #if SPINE_SKELETONANIMATOR + menu.AddSeparator(""); + + menu.AddItem(new GUIContent("SkeletonAnimator"), false, HandleSkeletonComponentDrop, new SpawnMenuData { + skeletonDataAsset = skeletonDataAsset, + spawnPoint = spawnPoint, + instantiateDelegate = (data) => InstantiateSkeletonAnimator(data) + }); + #endif + + menu.ShowAsContext(); } - - #if SPINE_SKELETONANIMATOR - menu.AddSeparator(""); - - menu.AddItem(new GUIContent("SkeletonAnimator"), false, HandleSkeletonComponentDrop, new SpawnMenuData { - skeletonDataAsset = skeletonDataAsset, - spawnPoint = spawnPoint, - instantiateDelegate = (data) => InstantiateSkeletonAnimator(data) - }); - #endif - - menu.ShowAsContext(); } + } } @@ -332,25 +343,32 @@ namespace Spine.Unity.Editor { public static void HandleSkeletonComponentDrop (object menuData) { var data = (SpawnMenuData)menuData; - try { - GameObject newGameObject = null; - Component newSkeletonComponent = data.instantiateDelegate.Invoke(data.skeletonDataAsset); - newGameObject = newSkeletonComponent.gameObject; - newGameObject.transform.position = RoundVector(data.spawnPoint, 2); - - var activeGameObject = Selection.activeGameObject; - if (activeGameObject != null) - newGameObject.transform.SetParent(activeGameObject.transform, true); - - if (data.isUI && (activeGameObject == null || activeGameObject.GetComponent() == null)) - Debug.Log("Created a UI Skeleton GameObject not under a RectTransform. It may not be visible until you parent it to a canvas."); - - Selection.activeGameObject = newGameObject; - Undo.RegisterCreatedObjectUndo(newGameObject, "Spawn Spine Skeleton"); - } catch { - Debug.LogError("Could not create Spine GameObject. Make sure your SkeletonData asset is valid."); + if (data.skeletonDataAsset.GetSkeletonData(true) == null) { + EditorUtility.DisplayDialog("Invalid SkeletonDataAsset", "Unable to create Spine GameObject.\n\nPlease check your SkeletonDataAsset.", "Ok"); + return; } + bool isUI = data.isUI; + + GameObject newGameObject = null; + Component newSkeletonComponent = data.instantiateDelegate.Invoke(data.skeletonDataAsset); + newGameObject = newSkeletonComponent.gameObject; + var transform = newGameObject.transform; + + var activeGameObject = Selection.activeGameObject; + if (activeGameObject != null) + transform.SetParent(activeGameObject.transform, false); + + newGameObject.transform.position = isUI ? data.spawnPoint : RoundVector(data.spawnPoint, 2); + + if (isUI && (activeGameObject == null || activeGameObject.GetComponent() == null)) + Debug.Log("Created a UI Skeleton GameObject not under a RectTransform. It may not be visible until you parent it to a canvas."); + + if (!isUI && activeGameObject != null && activeGameObject.transform.localScale != Vector3.one) + Debug.Log("New Spine GameObject was parented to a scaled Transform. It may not be the intended size."); + + Selection.activeGameObject = newGameObject; + Undo.RegisterCreatedObjectUndo(newGameObject, "Create Spine GameObject"); } /// @@ -363,12 +381,14 @@ namespace Spine.Unity.Editor { return vector; } - static Vector3 MousePointToWorldPoint2D (Vector2 mousePosition, Camera camera) { - var plane2D = new Plane(Vector3.back, Vector3.zero); + /// + /// Converts a mouse point to a world point on a plane. + /// + static Vector3 MousePointToWorldPoint2D (Vector2 mousePosition, Camera camera, Plane plane) { var screenPos = new Vector3(mousePosition.x, camera.pixelHeight - mousePosition.y, 0f); var ray = camera.ScreenPointToRay(screenPos); float distance; - bool hit = plane2D.Raycast(ray, out distance); + bool hit = plane.Raycast(ray, out distance); return ray.GetPoint(distance); } #endregion @@ -890,6 +910,7 @@ namespace Spine.Unity.Editor { texImporter.spriteImportMode = SpriteImportMode.None; texImporter.maxTextureSize = 2048; + EditorUtility.SetDirty(texImporter); AssetDatabase.ImportAsset(texturePath); AssetDatabase.SaveAssets(); diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs index 7688488a9..bd9ede169 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs +++ b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs @@ -52,6 +52,9 @@ namespace Spine.Unity.Editor { static SpineEditorUtilities.InstantiateDelegate instantiateDelegate; static SkeletonGraphicInspector () { + if (!SpineEditorUtilities.initialized) + return; + if (instantiateDelegate == null) instantiateDelegate = new SpineEditorUtilities.InstantiateDelegate(SpawnSkeletonGraphicFromDrop); @@ -158,9 +161,8 @@ namespace Spine.Unity.Editor { var parentGameObject = Selection.activeObject as GameObject; var parentTransform = parentGameObject == null ? null : parentGameObject.GetComponent(); - if (parentTransform == null) { + if (parentTransform == null) Debug.LogWarning("Your new SkeletonGraphic will not be visible until it is placed under a Canvas"); - } var gameObject = NewSkeletonGraphicGameObject("New SkeletonGraphic"); gameObject.transform.SetParent(parentTransform, false); diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs index fa3d577b6..b57b0b3f6 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs +++ b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs @@ -39,7 +39,7 @@ using Spine; namespace Spine.Unity { [ExecuteInEditMode, RequireComponent(typeof(CanvasRenderer), typeof(RectTransform)), DisallowMultipleComponent] [AddComponentMenu("Spine/SkeletonGraphic (Unity UI Canvas)")] - public class SkeletonGraphic : MaskableGraphic, ISkeletonComponent, IAnimationStateComponent { + public class SkeletonGraphic : MaskableGraphic, ISkeletonComponent, IAnimationStateComponent, ISkeletonAnimation { #region Inspector public SkeletonDataAsset skeletonDataAsset; @@ -67,15 +67,13 @@ namespace Spine.Unity { Clear(); Initialize(true); startingAnimation = ""; - if (skeletonDataAsset.atlasAssets.Length > 1 || skeletonDataAsset.atlasAssets[0].materials.Length > 1) { + if (skeletonDataAsset.atlasAssets.Length > 1 || skeletonDataAsset.atlasAssets[0].materials.Length > 1) Debug.LogError("Unity UI does not support multiple textures per Renderer. Your skeleton will not be rendered correctly. Recommend using SkeletonAnimation instead. This requires the use of a Screen space camera canvas."); - } } else { if (freeze) return; skeleton.SetToSetupPose(); - if (!string.IsNullOrEmpty(startingAnimation)) { + if (!string.IsNullOrEmpty(startingAnimation)) skeleton.PoseWithAnimation(startingAnimation, 0f, false); - } } } else { if (skeletonDataAsset != null) @@ -89,13 +87,8 @@ namespace Spine.Unity { protected override void Reset () { base.Reset(); - if (canvas == null) { - Debug.LogWarningFormat("SkeletonGraphic requires a Canvas to be visible. Move this GameObject ({0}) in the Hierarchy so it becomes a child of a Canvas.", gameObject.name); - } - - if (material == null || material.shader != Shader.Find("Spine/SkeletonGraphic (Premultiply Alpha)")) { - Debug.LogWarning("SkeletonGraphic works best with the SkeletonGraphic material."); - } + if (material == null || material.shader != Shader.Find("Spine/SkeletonGraphic (Premultiply Alpha)")) + Debug.LogWarning("SkeletonGraphic works best with the SkeletonGraphic material."); } #endif #endregion @@ -149,7 +142,7 @@ namespace Spine.Unity { if (UpdateComplete != null) UpdateComplete(this); } - void LateUpdate () { + public void LateUpdate () { if (freeze) return; //this.SetVerticesDirty(); // Which is better? UpdateMesh(); @@ -169,10 +162,9 @@ namespace Spine.Unity { protected Spine.Unity.MeshGeneration.ISimpleMeshGenerator spineMeshGenerator; public Spine.Unity.MeshGeneration.ISimpleMeshGenerator SpineMeshGenerator { get { return this.spineMeshGenerator; } } - public delegate void UpdateDelegate (SkeletonGraphic skeletonGraphic); - public event UpdateDelegate UpdateLocal; - public event UpdateDelegate UpdateWorld; - public event UpdateDelegate UpdateComplete; + public event UpdateBonesDelegate UpdateLocal; + public event UpdateBonesDelegate UpdateWorld; + public event UpdateBonesDelegate UpdateComplete; public void Clear () { skeleton = null;