diff --git a/spine-unity/Assets/spine-unity/Asset Types/RegionlessAttachmentLoader.cs b/spine-unity/Assets/spine-unity/Asset Types/RegionlessAttachmentLoader.cs new file mode 100644 index 000000000..cbfd25c12 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Asset Types/RegionlessAttachmentLoader.cs @@ -0,0 +1,84 @@ +/****************************************************************************** + * Spine Runtimes Software License v2.5 + * + * Copyright (c) 2013-2016, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable, and + * non-transferable license to use, install, execute, and perform the Spine + * Runtimes software and derivative works solely for personal or internal + * use. Without the written permission of Esoteric Software (see Section 2 of + * the Spine Software License Agreement), you may not (a) modify, translate, + * adapt, or develop new applications using the Spine Runtimes or otherwise + * create derivative works or improvements of the Spine Runtimes or (b) remove, + * delete, alter, or obscure any trademarks or any copyright, trademark, patent, + * or other intellectual property or proprietary rights notices on or in the + * Software, including any copy thereof. Redistributions in binary or source + * form must include this license and terms. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF + * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +using System; +using UnityEngine; + +namespace Spine.Unity { + + public class RegionlessAttachmentLoader : AttachmentLoader { + + static AtlasRegion emptyRegion; + static AtlasRegion EmptyRegion { + get { + if (emptyRegion == null) { + emptyRegion = new AtlasRegion { + name = "Empty AtlasRegion", + page = new AtlasPage { + name = "Empty AtlasPage", + rendererObject = new Material(Shader.Find("Spine/Special/HiddenPass")) { name = "NoRender Material" } + } + }; + } + return emptyRegion; + } + } + + public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) { + RegionAttachment attachment = new RegionAttachment(name) { + RendererObject = EmptyRegion + }; + return attachment; + } + + public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) { + MeshAttachment attachment = new MeshAttachment(name) { + RendererObject = EmptyRegion + }; + return attachment; + } + + public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) { + return new BoundingBoxAttachment(name); + } + + public PathAttachment NewPathAttachment (Skin skin, string name) { + return new PathAttachment(name); + } + + public PointAttachment NewPointAttachment (Skin skin, string name) { + return new PointAttachment(name); + } + + public ClippingAttachment NewClippingAttachment (Skin skin, string name) { + return new ClippingAttachment(name); + } + } +} diff --git a/spine-unity/Assets/spine-unity/Asset Types/RegionlessAttachmentLoader.cs.meta b/spine-unity/Assets/spine-unity/Asset Types/RegionlessAttachmentLoader.cs.meta new file mode 100644 index 000000000..5d7a368b9 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Asset Types/RegionlessAttachmentLoader.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 15f0f78b87720c047a320c5e0e3f91b7 +timeCreated: 1520505662 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs b/spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs index f1846e0c8..66b0cd97c 100644 --- a/spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs +++ b/spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs @@ -126,7 +126,7 @@ namespace Spine.Unity { Atlas[] atlasArray = this.GetAtlasArray(); #if !SPINE_TK2D - attachmentLoader = new AtlasAttachmentLoader(atlasArray); + attachmentLoader = (atlasArray.Length == 0) ? (AttachmentLoader)new RegionlessAttachmentLoader() : (AttachmentLoader)new AtlasAttachmentLoader(atlasArray); skeletonDataScale = scale; #else if (spriteCollection != null) { diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs index 0ae00c3ce..750f56855 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs @@ -274,6 +274,9 @@ namespace Spine.Unity.Editor { EditorGUILayout.LabelField("spine-tk2d", EditorStyles.boldLabel); EditorGUILayout.PropertyField(spriteCollection, true); #endif + + if (atlasAssets.arraySize == 0) + EditorGUILayout.HelpBox("AtlasAssets array is empty. Skeleton's attachments will load without being mapped to images.", MessageType.Info); } void HandleAtlasAssetsNulls () { @@ -485,7 +488,7 @@ namespace Spine.Unity.Editor { } void DrawWarningList () { - foreach (var line in warnings) + foreach (string line in warnings) EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(line, Icons.warning)); } @@ -525,25 +528,30 @@ namespace Spine.Unity.Editor { if (detectedNullAtlasEntry) { warnings.Add("AtlasAsset elements should not be null."); } else { - var missingPaths = SpineEditorUtilities.GetRequiredAtlasRegions(AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue)); + List missingPaths = null; + if (atlasAssets.arraySize > 0) { + missingPaths = SpineEditorUtilities.GetRequiredAtlasRegions(AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue)); - foreach (var atlas in atlasList) { - for (int i = 0; i < missingPaths.Count; i++) { - if (atlas.FindRegion(missingPaths[i]) != null) { - missingPaths.RemoveAt(i); - i--; + foreach (var atlas in atlasList) { + for (int i = 0; i < missingPaths.Count; i++) { + if (atlas.FindRegion(missingPaths[i]) != null) { + missingPaths.RemoveAt(i); + i--; + } } } + + #if SPINE_TK2D + if (missingPaths.Count > 0) + warnings.Add("Missing regions. SkeletonDataAsset requires tk2DSpriteCollectionData or Spine AtlasAssets."); + #endif } - #if SPINE_TK2D - if (missingPaths.Count > 0) - warnings.Add("Missing regions. SkeletonDataAsset requires tk2DSpriteCollectionData or Spine AtlasAssets."); - #endif - - foreach (var str in missingPaths) - warnings.Add("Missing Region: '" + str + "'"); - + if (missingPaths != null) { + foreach (string str in missingPaths) + warnings.Add("Missing Region: '" + str + "'"); + } + } } @@ -629,7 +637,10 @@ namespace Spine.Unity.Editor { PreviewRenderUtility previewRenderUtility; Camera PreviewUtilityCamera { get { - if (previewRenderUtility == null) return null; + if (previewRenderUtility == null) { + + return null; + } #if UNITY_2017_1_OR_NEWER return previewRenderUtility.camera; @@ -770,7 +781,7 @@ namespace Spine.Unity.Editor { skeleton.SetToSetupPose(); animationState.SetAnimation(0, targetAnimation, loop); } else { - var sameAnimation = (currentTrack.Animation == targetAnimation); + bool sameAnimation = (currentTrack.Animation == targetAnimation); if (sameAnimation) { currentTrack.TimeScale = (currentTrack.TimeScale == 0) ? 1f : 0f; // pause/play } else { @@ -974,18 +985,19 @@ namespace Spine.Unity.Editor { for (int i = 0; i < currentAnimationEvents.Count; i++) { float fr = currentAnimationEventTimes[i]; - var evRect = new Rect(barRect); - evRect.x = Mathf.Clamp(((fr / t.Animation.Duration) * width) - (Icons.userEvent.width / 2), barRect.x, float.MaxValue); - evRect.width = Icons.userEvent.width; - evRect.height = Icons.userEvent.height; - evRect.y += Icons.userEvent.height; + var evRect = new Rect(barRect) { + x = Mathf.Clamp(((fr / t.Animation.Duration) * width) - (Icons.userEvent.width / 2), barRect.x, float.MaxValue), + y = barRect.y + Icons.userEvent.height, + width = Icons.userEvent.width, + height = Icons.userEvent.height + }; GUI.DrawTexture(evRect, Icons.userEvent); Event ev = Event.current; if (ev.type == EventType.Repaint) { if (evRect.Contains(ev.mousePosition)) { - Rect tooltipRect = new Rect(evRect); GUIStyle tooltipStyle = EditorStyles.helpBox; + Rect tooltipRect = new Rect(evRect); tooltipRect.width = tooltipStyle.CalcSize(new GUIContent(currentAnimationEvents[i].Data.Name)).x; tooltipRect.y -= 4; tooltipRect.x += 4;