diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused.meta b/spine-unity/Assets/Spine.meta similarity index 67% rename from spine-unity/Assets/spine-unity/Mesh Generation/Unused.meta rename to spine-unity/Assets/Spine.meta index ebee0d38c..27f26801b 100644 --- a/spine-unity/Assets/spine-unity/Mesh Generation/Unused.meta +++ b/spine-unity/Assets/Spine.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 0cb4e560224445d44affd8e57c1ae8b1 +guid: 30918bcaadaaecc42bc215ff52f75b21 folderAsset: yes -timeCreated: 1495071888 +timeCreated: 1488288531 licenseType: Free DefaultImporter: userData: diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/Editor.meta b/spine-unity/Assets/Spine/Editor.meta similarity index 67% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/Editor.meta rename to spine-unity/Assets/Spine/Editor.meta index b27c7269e..973e2aafb 100644 --- a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/Editor.meta +++ b/spine-unity/Assets/Spine/Editor.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: fc5fac7eface2ba4fbb6146017e41192 +guid: ad14d5a4cd7a0444286d315541ee0495 folderAsset: yes -timeCreated: 1500876410 +timeCreated: 1527569319 licenseType: Free DefaultImporter: userData: diff --git a/spine-unity/Assets/Spine/Editor/spine-unity.meta b/spine-unity/Assets/Spine/Editor/spine-unity.meta new file mode 100644 index 000000000..c83b8381a --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 83fbec88df35fe34bab43a5dde6788af +folderAsset: yes +timeCreated: 1527569675 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Editor.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor.meta diff --git a/spine-unity/Assets/spine-unity/Editor/AnimationReferenceAssetEditor.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/AnimationReferenceAssetEditor.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/AnimationReferenceAssetEditor.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/AnimationReferenceAssetEditor.cs diff --git a/spine-unity/Assets/spine-unity/Editor/AnimationReferenceAssetEditor.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/AnimationReferenceAssetEditor.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/AnimationReferenceAssetEditor.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/AnimationReferenceAssetEditor.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs index 15b57d1d6..ec76a4a78 100644 --- a/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs @@ -1,51 +1,51 @@ -/****************************************************************************** - * 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 UnityEngine; - -namespace Spine.Unity.Editor { - public static class AssetDatabaseAvailabilityDetector { - const string MARKER_RESOURCE_NAME = "SpineAssetDatabaseMarker"; - private static bool _isMarkerLoaded; - - public static bool IsAssetDatabaseAvailable (bool forceCheck = false) { - if (!forceCheck && _isMarkerLoaded) - return true; - - TextAsset markerTextAsset = Resources.Load(MARKER_RESOURCE_NAME); - _isMarkerLoaded = markerTextAsset != null; - if (markerTextAsset != null) { - Resources.UnloadAsset(markerTextAsset); - } - - return _isMarkerLoaded; - } - } -} +/****************************************************************************** + * 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 UnityEngine; + +namespace Spine.Unity.Editor { + public static class AssetDatabaseAvailabilityDetector { + const string MARKER_RESOURCE_NAME = "SpineAssetDatabaseMarker"; + private static bool _isMarkerLoaded; + + public static bool IsAssetDatabaseAvailable (bool forceCheck = false) { + if (!forceCheck && _isMarkerLoaded) + return true; + + TextAsset markerTextAsset = Resources.Load(MARKER_RESOURCE_NAME); + _isMarkerLoaded = markerTextAsset != null; + if (markerTextAsset != null) { + Resources.UnloadAsset(markerTextAsset); + } + + return _isMarkerLoaded; + } + } +} diff --git a/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/AtlasAssetInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/AtlasAssetInspector.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/AtlasAssetInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/AtlasAssetInspector.cs diff --git a/spine-unity/Assets/spine-unity/Editor/AtlasAssetInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/AtlasAssetInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/AtlasAssetInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/AtlasAssetInspector.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/BoneFollowerInspector.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/BoneFollowerInspector.cs index 7372c5b17..f1cb32fd0 100644 --- a/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/BoneFollowerInspector.cs @@ -1,208 +1,208 @@ -/****************************************************************************** - * 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 UnityEditor; -using UnityEngine; - -namespace Spine.Unity.Editor { - - using Editor = UnityEditor.Editor; - using Event = UnityEngine.Event; - - [CustomEditor(typeof(BoneFollower)), CanEditMultipleObjects] - public class BoneFollowerInspector : Editor { - SerializedProperty boneName, skeletonRenderer, followZPosition, followBoneRotation, followLocalScale, followSkeletonFlip; - BoneFollower targetBoneFollower; - bool needsReset; - - #region Context Menu Item - [MenuItem ("CONTEXT/SkeletonRenderer/Add BoneFollower GameObject")] - static void AddBoneFollowerGameObject (MenuCommand cmd) { - var skeletonRenderer = cmd.context as SkeletonRenderer; - var go = new GameObject("BoneFollower"); - var t = go.transform; - t.SetParent(skeletonRenderer.transform); - t.localPosition = Vector3.zero; - - var f = go.AddComponent(); - f.skeletonRenderer = skeletonRenderer; - - EditorGUIUtility.PingObject(t); - - Undo.RegisterCreatedObjectUndo(go, "Add BoneFollower"); - } - - // Validate - [MenuItem ("CONTEXT/SkeletonRenderer/Add BoneFollower GameObject", true)] - static bool ValidateAddBoneFollowerGameObject (MenuCommand cmd) { - var skeletonRenderer = cmd.context as SkeletonRenderer; - return skeletonRenderer.valid; - } - #endregion - - void OnEnable () { - skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); - boneName = serializedObject.FindProperty("boneName"); - followBoneRotation = serializedObject.FindProperty("followBoneRotation"); - followZPosition = serializedObject.FindProperty("followZPosition"); - followLocalScale = serializedObject.FindProperty("followLocalScale"); - followSkeletonFlip = serializedObject.FindProperty("followSkeletonFlip"); - - targetBoneFollower = (BoneFollower)target; - if (targetBoneFollower.SkeletonRenderer != null) - targetBoneFollower.SkeletonRenderer.Initialize(false); - - if (!targetBoneFollower.valid || needsReset) { - targetBoneFollower.Initialize(); - targetBoneFollower.LateUpdate(); - needsReset = false; - SceneView.RepaintAll(); - } - } - - public void OnSceneGUI () { - var tbf = target as BoneFollower; - var skeletonRendererComponent = tbf.skeletonRenderer; - if (skeletonRendererComponent == null) return; - - var transform = skeletonRendererComponent.transform; - var skeleton = skeletonRendererComponent.skeleton; - - if (string.IsNullOrEmpty(boneName.stringValue)) { - SpineHandles.DrawBones(transform, skeleton); - SpineHandles.DrawBoneNames(transform, skeleton); - Handles.Label(tbf.transform.position, "No bone selected", EditorStyles.helpBox); - } else { - var targetBone = tbf.bone; - if (targetBone == null) return; - SpineHandles.DrawBoneWireframe(transform, targetBone, SpineHandles.TransformContraintColor); - Handles.Label(targetBone.GetWorldPosition(transform), targetBone.Data.Name, SpineHandles.BoneNameStyle); - } - } - - override public void OnInspectorGUI () { - if (serializedObject.isEditingMultipleObjects) { - if (needsReset) { - needsReset = false; - foreach (var o in targets) { - var bf = (BoneFollower)o; - bf.Initialize(); - bf.LateUpdate(); - } - SceneView.RepaintAll(); - } - - EditorGUI.BeginChangeCheck(); - DrawDefaultInspector(); - needsReset |= EditorGUI.EndChangeCheck(); - return; - } - - if (needsReset && Event.current.type == EventType.Layout) { - targetBoneFollower.Initialize(); - targetBoneFollower.LateUpdate(); - needsReset = false; - SceneView.RepaintAll(); - } - serializedObject.Update(); - - // Find Renderer - if (skeletonRenderer.objectReferenceValue == null) { - SkeletonRenderer parentRenderer = targetBoneFollower.GetComponentInParent(); - if (parentRenderer != null && parentRenderer.gameObject != targetBoneFollower.gameObject) { - skeletonRenderer.objectReferenceValue = parentRenderer; - Debug.Log("Inspector automatically assigned BoneFollower.SkeletonRenderer"); - } - } - - EditorGUILayout.PropertyField(skeletonRenderer); - var skeletonRendererReference = skeletonRenderer.objectReferenceValue as SkeletonRenderer; - if (skeletonRendererReference != null) { - if (skeletonRendererReference.gameObject == targetBoneFollower.gameObject) { - skeletonRenderer.objectReferenceValue = null; - EditorUtility.DisplayDialog("Invalid assignment.", "BoneFollower can only follow a skeleton on a separate GameObject.\n\nCreate a new GameObject for your BoneFollower, or choose a SkeletonRenderer from a different GameObject.", "Ok"); - } - } - - if (!targetBoneFollower.valid) { - needsReset = true; - } - - if (targetBoneFollower.valid) { - EditorGUI.BeginChangeCheck(); - EditorGUILayout.PropertyField(boneName); - needsReset |= EditorGUI.EndChangeCheck(); - - EditorGUILayout.PropertyField(followBoneRotation); - EditorGUILayout.PropertyField(followZPosition); - EditorGUILayout.PropertyField(followLocalScale); - EditorGUILayout.PropertyField(followSkeletonFlip); - - BoneFollowerInspector.RecommendRigidbodyButton(targetBoneFollower); - } else { - var boneFollowerSkeletonRenderer = targetBoneFollower.skeletonRenderer; - if (boneFollowerSkeletonRenderer == null) { - EditorGUILayout.HelpBox("SkeletonRenderer is unassigned. Please assign a SkeletonRenderer (SkeletonAnimation or SkeletonAnimator).", MessageType.Warning); - } else { - boneFollowerSkeletonRenderer.Initialize(false); - - if (boneFollowerSkeletonRenderer.skeletonDataAsset == null) - EditorGUILayout.HelpBox("Assigned SkeletonRenderer does not have SkeletonData assigned to it.", MessageType.Warning); - - if (!boneFollowerSkeletonRenderer.valid) - EditorGUILayout.HelpBox("Assigned SkeletonRenderer is invalid. Check target SkeletonRenderer, its SkeletonDataAsset or the console for other errors.", MessageType.Warning); - } - } - - var current = Event.current; - bool wasUndo = (current.type == EventType.ValidateCommand && current.commandName == "UndoRedoPerformed"); - if (wasUndo) - targetBoneFollower.Initialize(); - - serializedObject.ApplyModifiedProperties(); - } - - internal static void RecommendRigidbodyButton (Component component) { - bool hasCollider2D = component.GetComponent() != null || component.GetComponent() != null; - bool hasCollider3D = !hasCollider2D && component.GetComponent(); - bool missingRigidBody = (hasCollider2D && component.GetComponent() == null) || (hasCollider3D && component.GetComponent() == null); - if (missingRigidBody) { - using (new SpineInspectorUtility.BoxScope()) { - EditorGUILayout.HelpBox("Collider detected. Unity recommends adding a Rigidbody to the parent 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); - } - } - } - } - -} +/****************************************************************************** + * 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 UnityEditor; +using UnityEngine; + +namespace Spine.Unity.Editor { + + using Editor = UnityEditor.Editor; + using Event = UnityEngine.Event; + + [CustomEditor(typeof(BoneFollower)), CanEditMultipleObjects] + public class BoneFollowerInspector : Editor { + SerializedProperty boneName, skeletonRenderer, followZPosition, followBoneRotation, followLocalScale, followSkeletonFlip; + BoneFollower targetBoneFollower; + bool needsReset; + + #region Context Menu Item + [MenuItem ("CONTEXT/SkeletonRenderer/Add BoneFollower GameObject")] + static void AddBoneFollowerGameObject (MenuCommand cmd) { + var skeletonRenderer = cmd.context as SkeletonRenderer; + var go = new GameObject("BoneFollower"); + var t = go.transform; + t.SetParent(skeletonRenderer.transform); + t.localPosition = Vector3.zero; + + var f = go.AddComponent(); + f.skeletonRenderer = skeletonRenderer; + + EditorGUIUtility.PingObject(t); + + Undo.RegisterCreatedObjectUndo(go, "Add BoneFollower"); + } + + // Validate + [MenuItem ("CONTEXT/SkeletonRenderer/Add BoneFollower GameObject", true)] + static bool ValidateAddBoneFollowerGameObject (MenuCommand cmd) { + var skeletonRenderer = cmd.context as SkeletonRenderer; + return skeletonRenderer.valid; + } + #endregion + + void OnEnable () { + skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); + boneName = serializedObject.FindProperty("boneName"); + followBoneRotation = serializedObject.FindProperty("followBoneRotation"); + followZPosition = serializedObject.FindProperty("followZPosition"); + followLocalScale = serializedObject.FindProperty("followLocalScale"); + followSkeletonFlip = serializedObject.FindProperty("followSkeletonFlip"); + + targetBoneFollower = (BoneFollower)target; + if (targetBoneFollower.SkeletonRenderer != null) + targetBoneFollower.SkeletonRenderer.Initialize(false); + + if (!targetBoneFollower.valid || needsReset) { + targetBoneFollower.Initialize(); + targetBoneFollower.LateUpdate(); + needsReset = false; + SceneView.RepaintAll(); + } + } + + public void OnSceneGUI () { + var tbf = target as BoneFollower; + var skeletonRendererComponent = tbf.skeletonRenderer; + if (skeletonRendererComponent == null) return; + + var transform = skeletonRendererComponent.transform; + var skeleton = skeletonRendererComponent.skeleton; + + if (string.IsNullOrEmpty(boneName.stringValue)) { + SpineHandles.DrawBones(transform, skeleton); + SpineHandles.DrawBoneNames(transform, skeleton); + Handles.Label(tbf.transform.position, "No bone selected", EditorStyles.helpBox); + } else { + var targetBone = tbf.bone; + if (targetBone == null) return; + SpineHandles.DrawBoneWireframe(transform, targetBone, SpineHandles.TransformContraintColor); + Handles.Label(targetBone.GetWorldPosition(transform), targetBone.Data.Name, SpineHandles.BoneNameStyle); + } + } + + override public void OnInspectorGUI () { + if (serializedObject.isEditingMultipleObjects) { + if (needsReset) { + needsReset = false; + foreach (var o in targets) { + var bf = (BoneFollower)o; + bf.Initialize(); + bf.LateUpdate(); + } + SceneView.RepaintAll(); + } + + EditorGUI.BeginChangeCheck(); + DrawDefaultInspector(); + needsReset |= EditorGUI.EndChangeCheck(); + return; + } + + if (needsReset && Event.current.type == EventType.Layout) { + targetBoneFollower.Initialize(); + targetBoneFollower.LateUpdate(); + needsReset = false; + SceneView.RepaintAll(); + } + serializedObject.Update(); + + // Find Renderer + if (skeletonRenderer.objectReferenceValue == null) { + SkeletonRenderer parentRenderer = targetBoneFollower.GetComponentInParent(); + if (parentRenderer != null && parentRenderer.gameObject != targetBoneFollower.gameObject) { + skeletonRenderer.objectReferenceValue = parentRenderer; + Debug.Log("Inspector automatically assigned BoneFollower.SkeletonRenderer"); + } + } + + EditorGUILayout.PropertyField(skeletonRenderer); + var skeletonRendererReference = skeletonRenderer.objectReferenceValue as SkeletonRenderer; + if (skeletonRendererReference != null) { + if (skeletonRendererReference.gameObject == targetBoneFollower.gameObject) { + skeletonRenderer.objectReferenceValue = null; + EditorUtility.DisplayDialog("Invalid assignment.", "BoneFollower can only follow a skeleton on a separate GameObject.\n\nCreate a new GameObject for your BoneFollower, or choose a SkeletonRenderer from a different GameObject.", "Ok"); + } + } + + if (!targetBoneFollower.valid) { + needsReset = true; + } + + if (targetBoneFollower.valid) { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(boneName); + needsReset |= EditorGUI.EndChangeCheck(); + + EditorGUILayout.PropertyField(followBoneRotation); + EditorGUILayout.PropertyField(followZPosition); + EditorGUILayout.PropertyField(followLocalScale); + EditorGUILayout.PropertyField(followSkeletonFlip); + + BoneFollowerInspector.RecommendRigidbodyButton(targetBoneFollower); + } else { + var boneFollowerSkeletonRenderer = targetBoneFollower.skeletonRenderer; + if (boneFollowerSkeletonRenderer == null) { + EditorGUILayout.HelpBox("SkeletonRenderer is unassigned. Please assign a SkeletonRenderer (SkeletonAnimation or SkeletonAnimator).", MessageType.Warning); + } else { + boneFollowerSkeletonRenderer.Initialize(false); + + if (boneFollowerSkeletonRenderer.skeletonDataAsset == null) + EditorGUILayout.HelpBox("Assigned SkeletonRenderer does not have SkeletonData assigned to it.", MessageType.Warning); + + if (!boneFollowerSkeletonRenderer.valid) + EditorGUILayout.HelpBox("Assigned SkeletonRenderer is invalid. Check target SkeletonRenderer, its SkeletonDataAsset or the console for other errors.", MessageType.Warning); + } + } + + var current = Event.current; + bool wasUndo = (current.type == EventType.ValidateCommand && current.commandName == "UndoRedoPerformed"); + if (wasUndo) + targetBoneFollower.Initialize(); + + serializedObject.ApplyModifiedProperties(); + } + + internal static void RecommendRigidbodyButton (Component component) { + bool hasCollider2D = component.GetComponent() != null || component.GetComponent() != null; + bool hasCollider3D = !hasCollider2D && component.GetComponent(); + bool missingRigidBody = (hasCollider2D && component.GetComponent() == null) || (hasCollider3D && component.GetComponent() == null); + if (missingRigidBody) { + using (new SpineInspectorUtility.BoxScope()) { + EditorGUILayout.HelpBox("Collider detected. Unity recommends adding a Rigidbody to the parent 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); + } + } + } + } + +} diff --git a/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/BoneFollowerInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/BoneFollowerInspector.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/AtlasAsset Icon.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/AtlasAsset Icon.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/AtlasAsset Icon.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/AtlasAsset Icon.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/AtlasAsset Icon.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/AtlasAsset Icon.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/AtlasAsset Icon.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/AtlasAsset Icon.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/SkeletonDataAsset Icon.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animation.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animation.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animation.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animation.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animationRoot.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animationRoot.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animationRoot.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-animationRoot.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-attachment.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-attachment.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-attachment.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-attachment.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-attachment.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-attachment.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-attachment.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-attachment.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-bone.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-bone.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-bone.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-bone.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-bone.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-bone.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-bone.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-bone.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-boneNib.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boneNib.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-boneNib.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boneNib.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-boneNib.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boneNib.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-boneNib.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boneNib.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-boundingBox.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boundingBox.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-boundingBox.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boundingBox.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-boundingBox.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boundingBox.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-boundingBox.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-boundingBox.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-clipping.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-clipping.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-clipping.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-clipping.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-clipping.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-clipping.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-clipping.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-clipping.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintIK.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintIK.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintIK.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintIK.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintIK.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintIK.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintIK.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintIK.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintNib.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintNib.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintNib.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintNib.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintPath.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintPath.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintPath.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintPath.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintPath.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintPath.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintPath.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintPath.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintTransform.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintTransform.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintTransform.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintTransform.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintTransform.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintTransform.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintTransform.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraintTransform.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraints.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraints.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-constraints.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraints.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraints.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraints.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-constraints.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-constraints.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-event.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-event.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-event.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-event.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-hingeChain.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-hingeChain.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-hingeChain.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-hingeChain.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-hingeChain.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-hingeChain.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-hingeChain.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-hingeChain.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-image.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-image.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-image.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-image.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-image.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-image.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-image.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-image.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-mesh.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-mesh.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-mesh.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-mesh.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-mesh.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-mesh.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-mesh.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-mesh.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-null.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-null.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-null.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-null.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-null.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-null.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-null.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-null.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-path.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-path.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-path.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-path.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-path.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-path.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-path.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-path.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-point.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-point.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-point.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-point.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-point.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-point.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-point.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-point.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-poseBones.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-poseBones.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-poseBones.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-poseBones.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-poseBones.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-poseBones.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-poseBones.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-poseBones.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeleton.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeleton.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeleton.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeleton.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeletonUtility.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeletonUtility.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-skeletonUtility.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeletonUtility.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeletonUtility.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeletonUtility.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-skeletonUtility.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skeletonUtility.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skin.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skin.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skin.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skin.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skinPlaceholder.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinPlaceholder.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-skinPlaceholder.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinPlaceholder.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skinPlaceholder.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinPlaceholder.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-skinPlaceholder.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinPlaceholder.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinsRoot.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinsRoot.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinsRoot.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-skinsRoot.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-slot.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slot.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-slot.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slot.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-slot.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slot.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-slot.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slot.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-slotRoot.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slotRoot.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-slotRoot.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slotRoot.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-slotRoot.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slotRoot.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-slotRoot.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-slotRoot.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-spine.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-spine.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-spine.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-spine.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-subMeshRenderer.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-subMeshRenderer.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-subMeshRenderer.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-subMeshRenderer.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-subMeshRenderer.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-subMeshRenderer.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-subMeshRenderer.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-subMeshRenderer.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-warning.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-warning.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-warning.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-warning.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-warning.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-warning.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-warning.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-warning.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-weights.png b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-weights.png similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-weights.png rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-weights.png diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-weights.png.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-weights.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/GUI/icon-weights.png.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/GUI/icon-weights.png.meta diff --git a/spine-unity/Assets/spine-unity/Editor/Menus.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Menus.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Editor/Menus.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/Menus.cs index 1b18124fd..64cfa4f37 100644 --- a/spine-unity/Assets/spine-unity/Editor/Menus.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Menus.cs @@ -1,84 +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 System.IO; -using UnityEditor; -using UnityEngine; - -namespace Spine.Unity.Editor { - public static class Menus { - [MenuItem("Assets/Create/Spine/Atlas Asset")] - static public void CreateAtlas () { - CreateAsset("New Atlas"); - } - - [MenuItem("Assets/Create/Spine/SkeletonData Asset")] - static public void CreateSkeletonData () { - CreateAsset("New SkeletonData"); - } - - static void CreateAsset (String name) where T : ScriptableObject { - var dir = "Assets/"; - var selected = Selection.activeObject; - if (selected != null) { - var assetDir = AssetDatabase.GetAssetPath(selected.GetInstanceID()); - if (assetDir.Length > 0 && Directory.Exists(assetDir)) - dir = assetDir + "/"; - } - ScriptableObject asset = ScriptableObject.CreateInstance(); - AssetDatabase.CreateAsset(asset, dir + name + ".asset"); - AssetDatabase.SaveAssets(); - EditorUtility.FocusProjectWindow(); - Selection.activeObject = asset; - } - - [MenuItem("GameObject/Spine/SkeletonRenderer", false, 10)] - static public void CreateSkeletonRendererGameObject () { - CreateSpineGameObject("New SkeletonRenderer"); - } - - [MenuItem("GameObject/Spine/SkeletonAnimation", false, 10)] - static public void CreateSkeletonAnimationGameObject () { - CreateSpineGameObject("New SkeletonAnimation"); - } - - static void CreateSpineGameObject (string name) where T : MonoBehaviour { - var parentGameObject = Selection.activeObject as GameObject; - var parentTransform = parentGameObject == null ? null : parentGameObject.transform; - - var gameObject = new GameObject(name, typeof(T)); - gameObject.transform.SetParent(parentTransform, false); - EditorUtility.FocusProjectWindow(); - Selection.activeObject = gameObject; - EditorGUIUtility.PingObject(Selection.activeObject); - } - } -} +/****************************************************************************** + * 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 System.IO; +using UnityEditor; +using UnityEngine; + +namespace Spine.Unity.Editor { + public static class Menus { + [MenuItem("Assets/Create/Spine/Atlas Asset")] + static public void CreateAtlas () { + CreateAsset("New Atlas"); + } + + [MenuItem("Assets/Create/Spine/SkeletonData Asset")] + static public void CreateSkeletonData () { + CreateAsset("New SkeletonData"); + } + + static void CreateAsset (String name) where T : ScriptableObject { + var dir = "Assets/"; + var selected = Selection.activeObject; + if (selected != null) { + var assetDir = AssetDatabase.GetAssetPath(selected.GetInstanceID()); + if (assetDir.Length > 0 && Directory.Exists(assetDir)) + dir = assetDir + "/"; + } + ScriptableObject asset = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(asset, dir + name + ".asset"); + AssetDatabase.SaveAssets(); + EditorUtility.FocusProjectWindow(); + Selection.activeObject = asset; + } + + [MenuItem("GameObject/Spine/SkeletonRenderer", false, 10)] + static public void CreateSkeletonRendererGameObject () { + CreateSpineGameObject("New SkeletonRenderer"); + } + + [MenuItem("GameObject/Spine/SkeletonAnimation", false, 10)] + static public void CreateSkeletonAnimationGameObject () { + CreateSpineGameObject("New SkeletonAnimation"); + } + + static void CreateSpineGameObject (string name) where T : MonoBehaviour { + var parentGameObject = Selection.activeObject as GameObject; + var parentTransform = parentGameObject == null ? null : parentGameObject.transform; + + var gameObject = new GameObject(name, typeof(T)); + gameObject.transform.SetParent(parentTransform, false); + EditorUtility.FocusProjectWindow(); + Selection.activeObject = gameObject; + EditorGUIUtility.PingObject(Selection.activeObject); + } + } +} diff --git a/spine-unity/Assets/spine-unity/Editor/Menus.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Menus.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/Menus.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/Menus.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/PointFollowerEditor.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/PointFollowerEditor.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/PointFollowerEditor.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/PointFollowerEditor.cs diff --git a/spine-unity/Assets/spine-unity/Editor/PointFollowerEditor.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/PointFollowerEditor.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/PointFollowerEditor.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/PointFollowerEditor.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/Resources.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Resources.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/Resources.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/Resources.meta diff --git a/spine-unity/Assets/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt diff --git a/spine-unity/Assets/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt.meta diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonAnimationInspector.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonAnimationInspector.cs index 8d4672615..b5755dcda 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonAnimationInspector.cs @@ -1,143 +1,143 @@ -/****************************************************************************** - * 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 UnityEditor; -using UnityEngine; -using Spine; - -namespace Spine.Unity.Editor { - - [CustomEditor(typeof(SkeletonAnimation))] - [CanEditMultipleObjects] - public class SkeletonAnimationInspector : SkeletonRendererInspector { - protected SerializedProperty animationName, loop, timeScale, autoReset; - protected bool wasAnimationNameChanged; - protected bool requireRepaint; - readonly GUIContent LoopLabel = new GUIContent("Loop", "Whether or not .AnimationName should loop. This only applies to the initial animation specified in the inspector, or any subsequent Animations played through .AnimationName. Animations set through state.SetAnimation are unaffected."); - readonly GUIContent TimeScaleLabel = new GUIContent("Time Scale", "The rate at which animations progress over time. 1 means normal speed. 0.5 means 50% speed."); - - protected override void OnEnable () { - base.OnEnable(); - animationName = serializedObject.FindProperty("_animationName"); - loop = serializedObject.FindProperty("loop"); - timeScale = serializedObject.FindProperty("timeScale"); - } - - protected override void DrawInspectorGUI (bool multi) { - base.DrawInspectorGUI(multi); - if (!TargetIsValid) return; - bool sameData = SpineInspectorUtility.TargetsUseSameData(serializedObject); - - if (multi) { - foreach (var o in targets) - TrySetAnimation(o, multi); - - EditorGUILayout.Space(); - if (!sameData) { - #if UNITY_5_3_OR_NEWER - EditorGUILayout.DelayedTextField(animationName); - #else - animationName.stringValue = EditorGUILayout.TextField(animationName.displayName, animationName.stringValue); - #endif - } else { - EditorGUI.BeginChangeCheck(); - EditorGUILayout.PropertyField(animationName); - wasAnimationNameChanged |= EditorGUI.EndChangeCheck(); // Value used in the next update. - } - EditorGUILayout.PropertyField(loop); - EditorGUILayout.PropertyField(timeScale); - foreach (var o in targets) { - var component = o as SkeletonAnimation; - component.timeScale = Mathf.Max(component.timeScale, 0); - } - } else { - TrySetAnimation(target, multi); - - EditorGUILayout.Space(); - EditorGUI.BeginChangeCheck(); - EditorGUILayout.PropertyField(animationName); - wasAnimationNameChanged |= EditorGUI.EndChangeCheck(); // Value used in the next update. - EditorGUILayout.PropertyField(loop, LoopLabel); - EditorGUILayout.PropertyField(timeScale, TimeScaleLabel); - var component = (SkeletonAnimation)target; - component.timeScale = Mathf.Max(component.timeScale, 0); - EditorGUILayout.Space(); - } - - if (!isInspectingPrefab) { - if (requireRepaint) { - SceneView.RepaintAll(); - requireRepaint = false; - } - } - } - - protected void TrySetAnimation (Object o, bool multi) { - var skeletonAnimation = o as SkeletonAnimation; - if (skeletonAnimation == null) return; - if (!skeletonAnimation.valid) - return; - - if (!isInspectingPrefab) { - if (wasAnimationNameChanged) { - if (!Application.isPlaying) { - if (skeletonAnimation.state != null) skeletonAnimation.state.ClearTrack(0); - skeletonAnimation.skeleton.SetToSetupPose(); - } - - Spine.Animation animationToUse = skeletonAnimation.skeleton.Data.FindAnimation(animationName.stringValue); - - if (!Application.isPlaying) { - if (animationToUse != null) animationToUse.PoseSkeleton(skeletonAnimation.Skeleton, 0f); - skeletonAnimation.Update(0); - skeletonAnimation.LateUpdate(); - requireRepaint = true; - } else { - if (animationToUse != null) - skeletonAnimation.state.SetAnimation(0, animationToUse, loop.boolValue); - else - skeletonAnimation.state.ClearTrack(0); - } - - wasAnimationNameChanged = false; - } - - // Reflect animationName serialized property in the inspector even if SetAnimation API was used. - if (!multi && Application.isPlaying) { - TrackEntry current = skeletonAnimation.state.GetCurrent(0); - if (current != null) { - if (skeletonAnimation.AnimationName != animationName.stringValue) - animationName.stringValue = current.Animation.Name; - } - } - } - } - } -} +/****************************************************************************** + * 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 UnityEditor; +using UnityEngine; +using Spine; + +namespace Spine.Unity.Editor { + + [CustomEditor(typeof(SkeletonAnimation))] + [CanEditMultipleObjects] + public class SkeletonAnimationInspector : SkeletonRendererInspector { + protected SerializedProperty animationName, loop, timeScale, autoReset; + protected bool wasAnimationNameChanged; + protected bool requireRepaint; + readonly GUIContent LoopLabel = new GUIContent("Loop", "Whether or not .AnimationName should loop. This only applies to the initial animation specified in the inspector, or any subsequent Animations played through .AnimationName. Animations set through state.SetAnimation are unaffected."); + readonly GUIContent TimeScaleLabel = new GUIContent("Time Scale", "The rate at which animations progress over time. 1 means normal speed. 0.5 means 50% speed."); + + protected override void OnEnable () { + base.OnEnable(); + animationName = serializedObject.FindProperty("_animationName"); + loop = serializedObject.FindProperty("loop"); + timeScale = serializedObject.FindProperty("timeScale"); + } + + protected override void DrawInspectorGUI (bool multi) { + base.DrawInspectorGUI(multi); + if (!TargetIsValid) return; + bool sameData = SpineInspectorUtility.TargetsUseSameData(serializedObject); + + if (multi) { + foreach (var o in targets) + TrySetAnimation(o, multi); + + EditorGUILayout.Space(); + if (!sameData) { + #if UNITY_5_3_OR_NEWER + EditorGUILayout.DelayedTextField(animationName); + #else + animationName.stringValue = EditorGUILayout.TextField(animationName.displayName, animationName.stringValue); + #endif + } else { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(animationName); + wasAnimationNameChanged |= EditorGUI.EndChangeCheck(); // Value used in the next update. + } + EditorGUILayout.PropertyField(loop); + EditorGUILayout.PropertyField(timeScale); + foreach (var o in targets) { + var component = o as SkeletonAnimation; + component.timeScale = Mathf.Max(component.timeScale, 0); + } + } else { + TrySetAnimation(target, multi); + + EditorGUILayout.Space(); + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(animationName); + wasAnimationNameChanged |= EditorGUI.EndChangeCheck(); // Value used in the next update. + EditorGUILayout.PropertyField(loop, LoopLabel); + EditorGUILayout.PropertyField(timeScale, TimeScaleLabel); + var component = (SkeletonAnimation)target; + component.timeScale = Mathf.Max(component.timeScale, 0); + EditorGUILayout.Space(); + } + + if (!isInspectingPrefab) { + if (requireRepaint) { + SceneView.RepaintAll(); + requireRepaint = false; + } + } + } + + protected void TrySetAnimation (Object o, bool multi) { + var skeletonAnimation = o as SkeletonAnimation; + if (skeletonAnimation == null) return; + if (!skeletonAnimation.valid) + return; + + if (!isInspectingPrefab) { + if (wasAnimationNameChanged) { + if (!Application.isPlaying) { + if (skeletonAnimation.state != null) skeletonAnimation.state.ClearTrack(0); + skeletonAnimation.skeleton.SetToSetupPose(); + } + + Spine.Animation animationToUse = skeletonAnimation.skeleton.Data.FindAnimation(animationName.stringValue); + + if (!Application.isPlaying) { + if (animationToUse != null) animationToUse.PoseSkeleton(skeletonAnimation.Skeleton, 0f); + skeletonAnimation.Update(0); + skeletonAnimation.LateUpdate(); + requireRepaint = true; + } else { + if (animationToUse != null) + skeletonAnimation.state.SetAnimation(0, animationToUse, loop.boolValue); + else + skeletonAnimation.state.ClearTrack(0); + } + + wasAnimationNameChanged = false; + } + + // Reflect animationName serialized property in the inspector even if SetAnimation API was used. + if (!multi && Application.isPlaying) { + TrackEntry current = skeletonAnimation.state.GetCurrent(0); + if (current != null) { + if (skeletonAnimation.AnimationName != animationName.stringValue) + animationName.stringValue = current.Animation.Name; + } + } + } + } + } +} diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonAnimationInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonAnimationInspector.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonAnimatorInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonAnimatorInspector.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonAnimatorInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonAnimatorInspector.cs diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonAnimatorInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonAnimatorInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonAnimatorInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonAnimatorInspector.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBaker.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBaker.cs diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBaker.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBaker.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonBakingWindow.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBakingWindow.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonBakingWindow.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBakingWindow.cs diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonBakingWindow.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBakingWindow.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonBakingWindow.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBakingWindow.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDataAssetInspector.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDataAssetInspector.cs diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDataAssetInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDataAssetInspector.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonDebugWindow.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDebugWindow.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonDebugWindow.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDebugWindow.cs diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonDebugWindow.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDebugWindow.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonDebugWindow.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDebugWindow.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonRendererInspector.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonRendererInspector.cs index 759e4587b..9d50b0aab 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonRendererInspector.cs @@ -1,398 +1,398 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -#define NO_PREFAB_MESH - -using UnityEditor; -using System.Collections.Generic; -using UnityEngine; - -namespace Spine.Unity.Editor { - using Event = UnityEngine.Event; - using Icons = SpineEditorUtilities.Icons; - - [CustomEditor(typeof(SkeletonRenderer))] - [CanEditMultipleObjects] - public class SkeletonRendererInspector : UnityEditor.Editor { - public static bool advancedFoldout; - - protected SerializedProperty skeletonDataAsset, initialSkinName; - protected SerializedProperty initialFlipX, initialFlipY; - protected SerializedProperty singleSubmesh, separatorSlotNames, clearStateOnDisable, immutableTriangles; - protected SerializedProperty normals, tangents, meshes, zSpacing, pmaVertexColors, tintBlack; // MeshGenerator settings - protected SpineInspectorUtility.SerializedSortingProperties sortingProperties; - protected bool isInspectingPrefab; - - protected GUIContent SkeletonDataAssetLabel, SkeletonUtilityButtonContent; - protected GUIContent PMAVertexColorsLabel, ClearStateOnDisableLabel, ZSpacingLabel, MeshesLabel, ImmubleTrianglesLabel, TintBlackLabel, SingleSubmeshLabel; - protected GUIContent NormalsLabel, TangentsLabel; - const string ReloadButtonLabel = "Reload"; - - protected bool TargetIsValid { - get { - if (serializedObject.isEditingMultipleObjects) { - foreach (var o in targets) { - var component = (SkeletonRenderer)o; - if (!component.valid) - return false; - } - return true; - } else { - var component = (SkeletonRenderer)target; - return component.valid; - } - } - } - - protected virtual void OnEnable () { - isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab); - - SpineEditorUtilities.ConfirmInitialization(); - - // Labels - 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."); - ClearStateOnDisableLabel = new GUIContent("Clear State On Disable", "Use this if you are pooling or enabling/disabling your Spine GameObject."); - ZSpacingLabel = new GUIContent("Z Spacing", "A value other than 0 adds a space between each rendered attachment to prevent Z Fighting when using shaders that read or write to the depth buffer. Large values may cause unwanted parallax and spaces depending on camera setup."); - NormalsLabel = new GUIContent("Add Normals", "Use this if your shader requires vertex normals. A more efficient solution for 2D setups is to modify the shader to assume a single normal value for the whole mesh."); - TangentsLabel = new GUIContent("Solve Tangents", "Calculates the tangents per frame. Use this if you are using lit shaders (usually with normal maps) that require vertex tangents."); - TintBlackLabel = new GUIContent("Tint Black (!)", "Adds black tint vertex data to the mesh as UV2 and UV3. Black tinting requires that the shader interpret UV2 and UV3 as black tint colors for this effect to work. You may also use the default [Spine/Skeleton Tint Black] shader.\n\nIf you only need to tint the whole skeleton and not individual parts, the [Spine/Skeleton Tint] shader is recommended for better efficiency and changing/animating the _Black material property via MaterialPropertyBlock."); - SingleSubmeshLabel = new GUIContent("Use Single Submesh", "Simplifies submesh determination by assuming you are only using one Material and need only one submesh. This is will disable render separation and custom slot materials."); - - var so = this.serializedObject; - skeletonDataAsset = so.FindProperty("skeletonDataAsset"); - initialSkinName = so.FindProperty("initialSkinName"); - initialFlipX = so.FindProperty("initialFlipX"); - initialFlipY = so.FindProperty("initialFlipY"); - normals = so.FindProperty("addNormals"); - tangents = so.FindProperty("calculateTangents"); - meshes = so.FindProperty("renderMeshes"); - immutableTriangles = so.FindProperty("immutableTriangles"); - pmaVertexColors = so.FindProperty("pmaVertexColors"); - clearStateOnDisable = so.FindProperty("clearStateOnDisable"); - tintBlack = so.FindProperty("tintBlack"); - singleSubmesh = so.FindProperty("singleSubmesh"); - - separatorSlotNames = so.FindProperty("separatorSlotNames"); - separatorSlotNames.isExpanded = true; - - zSpacing = so.FindProperty("zSpacing"); - - SerializedObject rso = SpineInspectorUtility.GetRenderersSerializedObject(serializedObject); - sortingProperties = new SpineInspectorUtility.SerializedSortingProperties(rso); - } - - public static void ReapplySeparatorSlotNames (SkeletonRenderer skeletonRenderer) { - if (!skeletonRenderer.valid) return; - - var separatorSlots = skeletonRenderer.separatorSlots; - var separatorSlotNames = skeletonRenderer.separatorSlotNames; - var skeleton = skeletonRenderer.skeleton; - - separatorSlots.Clear(); - for (int i = 0, n = separatorSlotNames.Length; i < n; i++) { - var slot = skeleton.FindSlot(separatorSlotNames[i]); - if (slot != null) { - separatorSlots.Add(slot); - } else { - Debug.LogWarning(separatorSlotNames[i] + " is not a slot in " + skeletonRenderer.skeletonDataAsset.skeletonJSON.name); - } - } - } - - GUIContent[] skins; - ExposedList loadedSkinList; - - 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(); - if (meshFilter != null && meshFilter.sharedMesh != 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(); - if (meshFilter != null && meshFilter.sharedMesh != 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()), 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() == null) - // component.gameObject.AddComponent(); - // } - } else { - var component = (Component)target; - if (component.GetComponent() == null) { - if (SpineInspectorUtility.CenteredButton(SkeletonUtilityButtonContent, 21, true, 200f)) - component.gameObject.AddComponent(); - } - } - } - - EditorGUILayout.Space(); - } - } - - if (EditorGUI.EndChangeCheck()) - SceneView.RepaintAll(); - } - } - - public static void SeparatorsField (SerializedProperty separatorSlotNames) { - bool multi = separatorSlotNames.serializedObject.isEditingMultipleObjects; - bool hasTerminalSlot = false; - if (!multi) { - var sr = separatorSlotNames.serializedObject.targetObject as ISkeletonComponent; - var skeleton = sr.Skeleton; - int lastSlot = skeleton.Slots.Count - 1; - if (skeleton != null) { - for (int i = 0, n = separatorSlotNames.arraySize; i < n; i++) { - int index = skeleton.FindSlotIndex(separatorSlotNames.GetArrayElementAtIndex(i).stringValue); - if (index == 0 || index == lastSlot) { - hasTerminalSlot = true; - break; - } - } - } - } - - string terminalSlotWarning = hasTerminalSlot ? " (!)" : ""; - - using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { - 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, SpineInspectorUtility.TempContent(separatorSlotNames.displayName + terminalSlotWarning, Icons.slotRoot, 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); - } - } - - public void OnSceneGUI () { - var skeletonRenderer = (SkeletonRenderer)target; - var skeleton = skeletonRenderer.skeleton; - var transform = skeletonRenderer.transform; - if (skeleton == null) return; - - SpineHandles.DrawBones(transform, skeleton); - } - - override public void OnInspectorGUI () { - //serializedObject.Update(); - bool multi = serializedObject.isEditingMultipleObjects; - DrawInspectorGUI(multi); - if (serializedObject.ApplyModifiedProperties() || SpineInspectorUtility.UndoRedoPerformed(Event.current)) { - if (!Application.isPlaying) { - if (multi) - foreach (var o in targets) - ((SkeletonRenderer)o).Initialize(true); - else - ((SkeletonRenderer)target).Initialize(true); - } - } - } - - } -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +#define NO_PREFAB_MESH + +using UnityEditor; +using System.Collections.Generic; +using UnityEngine; + +namespace Spine.Unity.Editor { + using Event = UnityEngine.Event; + using Icons = SpineEditorUtilities.Icons; + + [CustomEditor(typeof(SkeletonRenderer))] + [CanEditMultipleObjects] + public class SkeletonRendererInspector : UnityEditor.Editor { + public static bool advancedFoldout; + + protected SerializedProperty skeletonDataAsset, initialSkinName; + protected SerializedProperty initialFlipX, initialFlipY; + protected SerializedProperty singleSubmesh, separatorSlotNames, clearStateOnDisable, immutableTriangles; + protected SerializedProperty normals, tangents, meshes, zSpacing, pmaVertexColors, tintBlack; // MeshGenerator settings + protected SpineInspectorUtility.SerializedSortingProperties sortingProperties; + protected bool isInspectingPrefab; + + protected GUIContent SkeletonDataAssetLabel, SkeletonUtilityButtonContent; + protected GUIContent PMAVertexColorsLabel, ClearStateOnDisableLabel, ZSpacingLabel, MeshesLabel, ImmubleTrianglesLabel, TintBlackLabel, SingleSubmeshLabel; + protected GUIContent NormalsLabel, TangentsLabel; + const string ReloadButtonLabel = "Reload"; + + protected bool TargetIsValid { + get { + if (serializedObject.isEditingMultipleObjects) { + foreach (var o in targets) { + var component = (SkeletonRenderer)o; + if (!component.valid) + return false; + } + return true; + } else { + var component = (SkeletonRenderer)target; + return component.valid; + } + } + } + + protected virtual void OnEnable () { + isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab); + + SpineEditorUtilities.ConfirmInitialization(); + + // Labels + 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."); + ClearStateOnDisableLabel = new GUIContent("Clear State On Disable", "Use this if you are pooling or enabling/disabling your Spine GameObject."); + ZSpacingLabel = new GUIContent("Z Spacing", "A value other than 0 adds a space between each rendered attachment to prevent Z Fighting when using shaders that read or write to the depth buffer. Large values may cause unwanted parallax and spaces depending on camera setup."); + NormalsLabel = new GUIContent("Add Normals", "Use this if your shader requires vertex normals. A more efficient solution for 2D setups is to modify the shader to assume a single normal value for the whole mesh."); + TangentsLabel = new GUIContent("Solve Tangents", "Calculates the tangents per frame. Use this if you are using lit shaders (usually with normal maps) that require vertex tangents."); + TintBlackLabel = new GUIContent("Tint Black (!)", "Adds black tint vertex data to the mesh as UV2 and UV3. Black tinting requires that the shader interpret UV2 and UV3 as black tint colors for this effect to work. You may also use the default [Spine/Skeleton Tint Black] shader.\n\nIf you only need to tint the whole skeleton and not individual parts, the [Spine/Skeleton Tint] shader is recommended for better efficiency and changing/animating the _Black material property via MaterialPropertyBlock."); + SingleSubmeshLabel = new GUIContent("Use Single Submesh", "Simplifies submesh determination by assuming you are only using one Material and need only one submesh. This is will disable render separation and custom slot materials."); + + var so = this.serializedObject; + skeletonDataAsset = so.FindProperty("skeletonDataAsset"); + initialSkinName = so.FindProperty("initialSkinName"); + initialFlipX = so.FindProperty("initialFlipX"); + initialFlipY = so.FindProperty("initialFlipY"); + normals = so.FindProperty("addNormals"); + tangents = so.FindProperty("calculateTangents"); + meshes = so.FindProperty("renderMeshes"); + immutableTriangles = so.FindProperty("immutableTriangles"); + pmaVertexColors = so.FindProperty("pmaVertexColors"); + clearStateOnDisable = so.FindProperty("clearStateOnDisable"); + tintBlack = so.FindProperty("tintBlack"); + singleSubmesh = so.FindProperty("singleSubmesh"); + + separatorSlotNames = so.FindProperty("separatorSlotNames"); + separatorSlotNames.isExpanded = true; + + zSpacing = so.FindProperty("zSpacing"); + + SerializedObject rso = SpineInspectorUtility.GetRenderersSerializedObject(serializedObject); + sortingProperties = new SpineInspectorUtility.SerializedSortingProperties(rso); + } + + public static void ReapplySeparatorSlotNames (SkeletonRenderer skeletonRenderer) { + if (!skeletonRenderer.valid) return; + + var separatorSlots = skeletonRenderer.separatorSlots; + var separatorSlotNames = skeletonRenderer.separatorSlotNames; + var skeleton = skeletonRenderer.skeleton; + + separatorSlots.Clear(); + for (int i = 0, n = separatorSlotNames.Length; i < n; i++) { + var slot = skeleton.FindSlot(separatorSlotNames[i]); + if (slot != null) { + separatorSlots.Add(slot); + } else { + Debug.LogWarning(separatorSlotNames[i] + " is not a slot in " + skeletonRenderer.skeletonDataAsset.skeletonJSON.name); + } + } + } + + GUIContent[] skins; + ExposedList loadedSkinList; + + 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(); + if (meshFilter != null && meshFilter.sharedMesh != 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(); + if (meshFilter != null && meshFilter.sharedMesh != 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()), 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() == null) + // component.gameObject.AddComponent(); + // } + } else { + var component = (Component)target; + if (component.GetComponent() == null) { + if (SpineInspectorUtility.CenteredButton(SkeletonUtilityButtonContent, 21, true, 200f)) + component.gameObject.AddComponent(); + } + } + } + + EditorGUILayout.Space(); + } + } + + if (EditorGUI.EndChangeCheck()) + SceneView.RepaintAll(); + } + } + + public static void SeparatorsField (SerializedProperty separatorSlotNames) { + bool multi = separatorSlotNames.serializedObject.isEditingMultipleObjects; + bool hasTerminalSlot = false; + if (!multi) { + var sr = separatorSlotNames.serializedObject.targetObject as ISkeletonComponent; + var skeleton = sr.Skeleton; + int lastSlot = skeleton.Slots.Count - 1; + if (skeleton != null) { + for (int i = 0, n = separatorSlotNames.arraySize; i < n; i++) { + int index = skeleton.FindSlotIndex(separatorSlotNames.GetArrayElementAtIndex(i).stringValue); + if (index == 0 || index == lastSlot) { + hasTerminalSlot = true; + break; + } + } + } + } + + string terminalSlotWarning = hasTerminalSlot ? " (!)" : ""; + + using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { + 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, SpineInspectorUtility.TempContent(separatorSlotNames.displayName + terminalSlotWarning, Icons.slotRoot, 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); + } + } + + public void OnSceneGUI () { + var skeletonRenderer = (SkeletonRenderer)target; + var skeleton = skeletonRenderer.skeleton; + var transform = skeletonRenderer.transform; + if (skeleton == null) return; + + SpineHandles.DrawBones(transform, skeleton); + } + + override public void OnInspectorGUI () { + //serializedObject.Update(); + bool multi = serializedObject.isEditingMultipleObjects; + DrawInspectorGUI(multi); + if (serializedObject.ApplyModifiedProperties() || SpineInspectorUtility.UndoRedoPerformed(Event.current)) { + if (!Application.isPlaying) { + if (multi) + foreach (var o in targets) + ((SkeletonRenderer)o).Initialize(true); + else + ((SkeletonRenderer)target).Initialize(true); + } + } + } + + } +} diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonRendererInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonRendererInspector.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineAttributeDrawers.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineAttributeDrawers.cs diff --git a/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineAttributeDrawers.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineAttributeDrawers.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs index 444c96f88..a24e0c8f2 100644 --- a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs @@ -1,2029 +1,2029 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -#pragma warning disable 0219 - -// Original contribution by: Mitch Thompson - -#define SPINE_SKELETONANIMATOR -using UnityEngine; -using UnityEditor; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Linq; -using System.Reflection; -using Spine; - -namespace Spine.Unity.Editor { - using EventType = UnityEngine.EventType; - - // Analysis disable once ConvertToStaticType - [InitializeOnLoad] - public class SpineEditorUtilities : AssetPostprocessor { - - public static class Icons { - public static Texture2D skeleton; - public static Texture2D nullBone; - public static Texture2D bone; - public static Texture2D poseBones; - public static Texture2D boneNib; - public static Texture2D slot; - public static Texture2D slotRoot; - public static Texture2D skinPlaceholder; - public static Texture2D image; - public static Texture2D genericAttachment; - public static Texture2D boundingBox; - public static Texture2D point; - public static Texture2D mesh; - public static Texture2D weights; - public static Texture2D path; - public static Texture2D clipping; - public static Texture2D skin; - public static Texture2D skinsRoot; - public static Texture2D animation; - public static Texture2D animationRoot; - 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; - public static Texture2D subMeshRenderer; - public static Texture2D skeletonDataAssetIcon; - public static Texture2D info; - public static Texture2D unity; -// public static Texture2D controllerIcon; - - static Texture2D LoadIcon (string filename) { - return (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/" + filename); - } - - public static void Initialize () { - skeleton = LoadIcon("icon-skeleton.png"); - nullBone = LoadIcon("icon-null.png"); - bone = LoadIcon("icon-bone.png"); - poseBones = LoadIcon("icon-poseBones.png"); - boneNib = LoadIcon("icon-boneNib.png"); - slot = LoadIcon("icon-slot.png"); - slotRoot = LoadIcon("icon-slotRoot.png"); - skinPlaceholder = LoadIcon("icon-skinPlaceholder.png"); - - genericAttachment = LoadIcon("icon-attachment.png"); - image = LoadIcon("icon-image.png"); - boundingBox = LoadIcon("icon-boundingBox.png"); - point = LoadIcon("icon-point.png"); - mesh = LoadIcon("icon-mesh.png"); - weights = LoadIcon("icon-weights.png"); - path = LoadIcon("icon-path.png"); - clipping = LoadIcon("icon-clipping.png"); - - skin = LoadIcon("icon-skin.png"); - skinsRoot = LoadIcon("icon-skinsRoot.png"); - animation = LoadIcon("icon-animation.png"); - animationRoot = LoadIcon("icon-animationRoot.png"); - spine = LoadIcon("icon-spine.png"); - userEvent = LoadIcon("icon-event.png"); - constraintNib = LoadIcon("icon-constraintNib.png"); - - constraintRoot = LoadIcon("icon-constraints.png"); - constraintTransform = LoadIcon("icon-constraintTransform.png"); - constraintPath = LoadIcon("icon-constraintPath.png"); - constraintIK = LoadIcon("icon-constraintIK.png"); - - warning = LoadIcon("icon-warning.png"); - skeletonUtility = LoadIcon("icon-skeletonUtility.png"); - hingeChain = LoadIcon("icon-hingeChain.png"); - subMeshRenderer = LoadIcon("icon-subMeshRenderer.png"); - - skeletonDataAssetIcon = LoadIcon("SkeletonDataAsset Icon.png"); - - info = EditorGUIUtility.FindTexture("console.infoicon.sml"); - unity = EditorGUIUtility.FindTexture("SceneAsset Icon"); -// controllerIcon = EditorGUIUtility.FindTexture("AnimatorController Icon"); - } - - public static Texture2D GetAttachmentIcon (Attachment attachment) { - // Analysis disable once CanBeReplacedWithTryCastAndCheckForNull - if (attachment is RegionAttachment) - return Icons.image; - else if (attachment is MeshAttachment) - return ((MeshAttachment)attachment).IsWeighted() ? Icons.weights : Icons.mesh; - else if (attachment is BoundingBoxAttachment) - return Icons.boundingBox; - else if (attachment is PointAttachment) - return Icons.point; - else if (attachment is PathAttachment) - return Icons.path; - else if (attachment is ClippingAttachment) - return Icons.clipping; - else - return Icons.warning; - } - } - - public static string editorPath = ""; - public static string editorGUIPath = ""; - public static bool initialized; - - /// HACK: This list keeps the asset reference temporarily during importing. - /// - /// In cases of very large projects/sufficient RAM pressure, when AssetDatabase.SaveAssets is called, - /// Unity can mistakenly unload assets whose references are only on the stack. - /// This leads to MissingReferenceException and other errors. - static readonly List protectFromStackGarbageCollection = new List(); - static HashSet assetsImportedInWrongState = new HashSet(); - - #if SPINE_TK2D - const float DEFAULT_DEFAULT_SCALE = 1f; - #else - const float DEFAULT_DEFAULT_SCALE = 0.01f; - #endif - const string DEFAULT_SCALE_KEY = "SPINE_DEFAULT_SCALE"; - public static float defaultScale = DEFAULT_DEFAULT_SCALE; - - const float DEFAULT_DEFAULT_MIX = 0.2f; - const string DEFAULT_MIX_KEY = "SPINE_DEFAULT_MIX"; - public static float defaultMix = DEFAULT_DEFAULT_MIX; - - const string DEFAULT_DEFAULT_SHADER = "Spine/Skeleton"; - const string DEFAULT_SHADER_KEY = "SPINE_DEFAULT_SHADER"; - public static string defaultShader = DEFAULT_DEFAULT_SHADER; - - const float DEFAULT_DEFAULT_ZSPACING = 0f; - const string DEFAULT_ZSPACING_KEY = "SPINE_DEFAULT_ZSPACING"; - public static float defaultZSpacing = DEFAULT_DEFAULT_ZSPACING; - - const bool DEFAULT_SHOW_HIERARCHY_ICONS = true; - const string SHOW_HIERARCHY_ICONS_KEY = "SPINE_SHOW_HIERARCHY_ICONS"; - public static bool showHierarchyIcons = DEFAULT_SHOW_HIERARCHY_ICONS; - - const bool DEFAULT_SET_TEXTUREIMPORTER_SETTINGS = true; - const string SET_TEXTUREIMPORTER_SETTINGS_KEY = "SPINE_SET_TEXTUREIMPORTER_SETTINGS"; - public static bool setTextureImporterSettings = DEFAULT_SET_TEXTUREIMPORTER_SETTINGS; - - internal const float DEFAULT_MIPMAPBIAS = -0.5f; - - public const float DEFAULT_SCENE_ICONS_SCALE = 1f; - public const string SCENE_ICONS_SCALE_KEY = "SPINE_SCENE_ICONS_SCALE"; - - #region Initialization - static SpineEditorUtilities () { - Initialize(); - } - - static void LoadPreferences () { - defaultMix = EditorPrefs.GetFloat(DEFAULT_MIX_KEY, DEFAULT_DEFAULT_MIX); - defaultScale = EditorPrefs.GetFloat(DEFAULT_SCALE_KEY, DEFAULT_DEFAULT_SCALE); - defaultZSpacing = EditorPrefs.GetFloat(DEFAULT_ZSPACING_KEY, DEFAULT_DEFAULT_ZSPACING); - defaultShader = EditorPrefs.GetString(DEFAULT_SHADER_KEY, DEFAULT_DEFAULT_SHADER); - showHierarchyIcons = EditorPrefs.GetBool(SHOW_HIERARCHY_ICONS_KEY, DEFAULT_SHOW_HIERARCHY_ICONS); - setTextureImporterSettings = EditorPrefs.GetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, DEFAULT_SET_TEXTUREIMPORTER_SETTINGS); - SpineHandles.handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, DEFAULT_SCENE_ICONS_SCALE); - preferencesLoaded = true; - } - - static void Initialize () { - LoadPreferences(); - - DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath); - FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories); - editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets")); - editorGUIPath = editorPath + "/GUI"; - - Icons.Initialize(); - - // Drag and Drop - SceneView.onSceneGUIDelegate -= SceneViewDragAndDrop; - SceneView.onSceneGUIDelegate += SceneViewDragAndDrop; - EditorApplication.hierarchyWindowItemOnGUI -= SpineEditorHierarchyHandler.HierarchyDragAndDrop; - EditorApplication.hierarchyWindowItemOnGUI += SpineEditorHierarchyHandler.HierarchyDragAndDrop; - - // Hierarchy Icons - #if UNITY_2017_2_OR_NEWER - EditorApplication.playModeStateChanged -= SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged; - EditorApplication.playModeStateChanged += SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged; - SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode); - #else - EditorApplication.playmodeStateChanged -= SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged; - EditorApplication.playmodeStateChanged += SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged; - SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(); - #endif - - initialized = true; - } - - public static void ConfirmInitialization () { - if (!initialized || Icons.skeleton == null) - Initialize(); - } - #endregion - - #region Spine Preferences and Defaults - static bool preferencesLoaded = false; - - [PreferenceItem("Spine")] - static void PreferencesGUI () { - if (!preferencesLoaded) - LoadPreferences(); - - EditorGUI.BeginChangeCheck(); - showHierarchyIcons = EditorGUILayout.Toggle(new GUIContent("Show Hierarchy Icons", "Show relevant icons on GameObjects with Spine Components on them. Disable this if you have large, complex scenes."), showHierarchyIcons); - if (EditorGUI.EndChangeCheck()) { - EditorPrefs.SetBool(SHOW_HIERARCHY_ICONS_KEY, showHierarchyIcons); - #if UNITY_2017_2_OR_NEWER - SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode); - #else - SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(); - #endif - } - - EditorGUILayout.Separator(); - - EditorGUILayout.LabelField("Auto-Import Settings", EditorStyles.boldLabel); - - EditorGUI.BeginChangeCheck(); - defaultMix = EditorGUILayout.FloatField("Default Mix", defaultMix); - if (EditorGUI.EndChangeCheck()) - EditorPrefs.SetFloat(DEFAULT_MIX_KEY, defaultMix); - - EditorGUI.BeginChangeCheck(); - defaultScale = EditorGUILayout.FloatField("Default SkeletonData Scale", defaultScale); - if (EditorGUI.EndChangeCheck()) - EditorPrefs.SetFloat(DEFAULT_SCALE_KEY, defaultScale); - - EditorGUI.BeginChangeCheck(); - var shader = (EditorGUILayout.ObjectField("Default Shader", Shader.Find(defaultShader), typeof(Shader), false) as Shader); - defaultShader = shader != null ? shader.name : DEFAULT_DEFAULT_SHADER; - if (EditorGUI.EndChangeCheck()) - EditorPrefs.SetString(DEFAULT_SHADER_KEY, defaultShader); - - EditorGUI.BeginChangeCheck(); - setTextureImporterSettings = EditorGUILayout.Toggle(new GUIContent("Apply Atlas Texture Settings", "Apply the recommended settings for Texture Importers."), showHierarchyIcons); - if (EditorGUI.EndChangeCheck()) { - EditorPrefs.SetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, showHierarchyIcons); - } - - EditorGUILayout.Space(); - - EditorGUILayout.LabelField("Editor Instantiation", EditorStyles.boldLabel); - EditorGUI.BeginChangeCheck(); - defaultZSpacing = EditorGUILayout.Slider("Default Slot Z-Spacing", defaultZSpacing, -0.1f, 0f); - if (EditorGUI.EndChangeCheck()) - EditorPrefs.SetFloat(DEFAULT_ZSPACING_KEY, defaultZSpacing); - - - EditorGUILayout.Space(); - EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel); - EditorGUI.BeginChangeCheck(); - SpineHandles.handleScale = EditorGUILayout.Slider("Editor Bone Scale", SpineHandles.handleScale, 0.01f, 2f); - SpineHandles.handleScale = Mathf.Max(0.01f, SpineHandles.handleScale); - if (EditorGUI.EndChangeCheck()) { - EditorPrefs.SetFloat(SCENE_ICONS_SCALE_KEY, SpineHandles.handleScale); - SceneView.RepaintAll(); - } - - - GUILayout.Space(20); - EditorGUILayout.LabelField("3rd Party Settings", EditorStyles.boldLabel); - using (new GUILayout.HorizontalScope()) { - EditorGUILayout.PrefixLabel("Define TK2D"); - if (GUILayout.Button("Enable", GUILayout.Width(64))) - SpineTK2DEditorUtility.EnableTK2D(); - if (GUILayout.Button("Disable", GUILayout.Width(64))) - SpineTK2DEditorUtility.DisableTK2D(); - } - } - #endregion - - #region Drag and Drop Instantiation - public delegate Component InstantiateDelegate (SkeletonDataAsset skeletonDataAsset); - - public struct SpawnMenuData { - public Vector3 spawnPoint; - public SkeletonDataAsset skeletonDataAsset; - public InstantiateDelegate instantiateDelegate; - public bool isUI; - } - - public class SkeletonComponentSpawnType { - public string menuLabel; - public InstantiateDelegate instantiateDelegate; - public bool isUI; - } - - internal static readonly List additionalSpawnTypes = new List(); - - static void SceneViewDragAndDrop (SceneView sceneview) { - var current = UnityEngine.Event.current; - var references = DragAndDrop.objectReferences; - if (current.type == EventType.Layout) return; - - // Allow drag and drop of one SkeletonDataAsset. - if (references.Length == 1) { - var skeletonDataAsset = references[0] as SkeletonDataAsset; - if (skeletonDataAsset != null) { - var mousePos = current.mousePosition; - - 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.skeletonDataAssetIcon)); - Handles.EndGUI(); - - 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); - ShowInstantiateContextMenu(skeletonDataAsset, spawnPoint); - DragAndDrop.AcceptDrag(); - current.Use(); - } - } - } - } - } - - public static void ShowInstantiateContextMenu (SkeletonDataAsset skeletonDataAsset, Vector3 spawnPoint) { - var menu = new GenericMenu(); - - // SkeletonAnimation - menu.AddItem(new GUIContent("SkeletonAnimation"), false, HandleSkeletonComponentDrop, new SpawnMenuData { - skeletonDataAsset = skeletonDataAsset, - spawnPoint = spawnPoint, - instantiateDelegate = (data) => InstantiateSkeletonAnimation(data), - isUI = false - }); - - // SkeletonGraphic - var skeletonGraphicInspectorType = System.Type.GetType("Spine.Unity.Editor.SkeletonGraphicInspector"); - if (skeletonGraphicInspectorType != null) { - var graphicInstantiateDelegate = skeletonGraphicInspectorType.GetMethod("SpawnSkeletonGraphicFromDrop", BindingFlags.Static | BindingFlags.Public); - if (graphicInstantiateDelegate != null) - menu.AddItem(new GUIContent("SkeletonGraphic (UI)"), false, HandleSkeletonComponentDrop, new SpawnMenuData { - skeletonDataAsset = skeletonDataAsset, - spawnPoint = spawnPoint, - instantiateDelegate = System.Delegate.CreateDelegate(typeof(InstantiateDelegate), graphicInstantiateDelegate) as InstantiateDelegate, - isUI = true - }); - } - - #if SPINE_SKELETONANIMATOR - menu.AddSeparator(""); - // SkeletonAnimator - menu.AddItem(new GUIContent("SkeletonAnimator"), false, HandleSkeletonComponentDrop, new SpawnMenuData { - skeletonDataAsset = skeletonDataAsset, - spawnPoint = spawnPoint, - instantiateDelegate = (data) => InstantiateSkeletonAnimator(data) - }); - #endif - - menu.ShowAsContext(); - } - - public static void HandleSkeletonComponentDrop (object spawnMenuData) { - var data = (SpawnMenuData)spawnMenuData; - - 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; - - Component newSkeletonComponent = data.instantiateDelegate.Invoke(data.skeletonDataAsset); - GameObject newGameObject = newSkeletonComponent.gameObject; - Transform newTransform = newGameObject.transform; - - var activeGameObject = Selection.activeGameObject; - if (isUI && activeGameObject != null) - newTransform.SetParent(activeGameObject.transform, false); - - newTransform.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; - //EditorGUIUtility.PingObject(newGameObject); // Doesn't work when setting activeGameObject. - Undo.RegisterCreatedObjectUndo(newGameObject, "Create Spine GameObject"); - } - - /// - /// Rounds off vector components to a number of decimal digits. - /// - public static Vector3 RoundVector (Vector3 vector, int digits) { - vector.x = (float)System.Math.Round(vector.x, digits); - vector.y = (float)System.Math.Round(vector.y, digits); - vector.z = (float)System.Math.Round(vector.z, digits); - return vector; - } - - /// - /// 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 = plane.Raycast(ray, out distance); - return ray.GetPoint(distance); - } - #endregion - - #region Hierarchy - static class SpineEditorHierarchyHandler { - static Dictionary skeletonRendererTable = new Dictionary(); - static Dictionary skeletonUtilityBoneTable = new Dictionary(); - static Dictionary boundingBoxFollowerTable = new Dictionary(); - - #if UNITY_2017_2_OR_NEWER - internal static void HierarchyIconsOnPlaymodeStateChanged (PlayModeStateChange stateChange) { - #else - internal static void HierarchyIconsOnPlaymodeStateChanged () { - #endif - skeletonRendererTable.Clear(); - skeletonUtilityBoneTable.Clear(); - boundingBoxFollowerTable.Clear(); - - #if UNITY_2018 - EditorApplication.hierarchyChanged -= HierarchyIconsOnChanged; - #else - EditorApplication.hierarchyWindowChanged -= HierarchyIconsOnChanged; - #endif - EditorApplication.hierarchyWindowItemOnGUI -= HierarchyIconsOnGUI; - - if (!Application.isPlaying && showHierarchyIcons) { - #if UNITY_2018 - EditorApplication.hierarchyChanged += HierarchyIconsOnChanged; - #else - EditorApplication.hierarchyWindowChanged += HierarchyIconsOnChanged; - #endif - EditorApplication.hierarchyWindowItemOnGUI += HierarchyIconsOnGUI; - HierarchyIconsOnChanged(); - } - } - - internal static void HierarchyIconsOnChanged () { - skeletonRendererTable.Clear(); - skeletonUtilityBoneTable.Clear(); - boundingBoxFollowerTable.Clear(); - - SkeletonRenderer[] arr = Object.FindObjectsOfType(); - foreach (SkeletonRenderer r in arr) - skeletonRendererTable[r.gameObject.GetInstanceID()] = r.gameObject; - - SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType(); - foreach (SkeletonUtilityBone b in boneArr) - skeletonUtilityBoneTable[b.gameObject.GetInstanceID()] = b; - - BoundingBoxFollower[] bbfArr = Object.FindObjectsOfType(); - foreach (BoundingBoxFollower bbf in bbfArr) - boundingBoxFollowerTable[bbf.gameObject.GetInstanceID()] = bbf; - } - - internal static void HierarchyIconsOnGUI (int instanceId, Rect selectionRect) { - Rect r = new Rect(selectionRect); - if (skeletonRendererTable.ContainsKey(instanceId)) { - r.x = r.width - 15; - r.width = 15; - GUI.Label(r, Icons.spine); - } else if (skeletonUtilityBoneTable.ContainsKey(instanceId)) { - r.x -= 26; - if (skeletonUtilityBoneTable[instanceId] != null) { - if (skeletonUtilityBoneTable[instanceId].transform.childCount == 0) - r.x += 13; - r.y += 2; - r.width = 13; - r.height = 13; - if (skeletonUtilityBoneTable[instanceId].mode == SkeletonUtilityBone.Mode.Follow) - GUI.DrawTexture(r, Icons.bone); - else - GUI.DrawTexture(r, Icons.poseBones); - } - } else if (boundingBoxFollowerTable.ContainsKey(instanceId)) { - r.x -= 26; - if (boundingBoxFollowerTable[instanceId] != null) { - if (boundingBoxFollowerTable[instanceId].transform.childCount == 0) - r.x += 13; - r.y += 2; - r.width = 13; - r.height = 13; - GUI.DrawTexture(r, Icons.boundingBox); - } - } - } - - internal static void HierarchyDragAndDrop (int instanceId, Rect selectionRect) { - // HACK: Uses EditorApplication.hierarchyWindowItemOnGUI. - // Only works when there is at least one item in the scene. - var current = UnityEngine.Event.current; - var eventType = current.type; - bool isDraggingEvent = eventType == EventType.DragUpdated; - bool isDropEvent = eventType == EventType.DragPerform; - if (isDraggingEvent || isDropEvent) { - var mouseOverWindow = EditorWindow.mouseOverWindow; - if (mouseOverWindow != null) { - - // One, existing, valid SkeletonDataAsset - var references = DragAndDrop.objectReferences; - if (references.Length == 1) { - var skeletonDataAsset = references[0] as SkeletonDataAsset; - if (skeletonDataAsset != null && skeletonDataAsset.GetSkeletonData(true) != null) { - - // Allow drag-and-dropping anywhere in the Hierarchy Window. - // HACK: string-compare because we can't get its type via reflection. - const string HierarchyWindow = "UnityEditor.SceneHierarchyWindow"; - if (HierarchyWindow.Equals(mouseOverWindow.GetType().ToString(), System.StringComparison.Ordinal)) { - if (isDraggingEvent) { - DragAndDrop.visualMode = DragAndDropVisualMode.Copy; - current.Use(); - } else if (isDropEvent) { - ShowInstantiateContextMenu(skeletonDataAsset, Vector3.zero); - DragAndDrop.AcceptDrag(); - current.Use(); - return; - } - } - - } - } - } - } - - } - } - #endregion - - #region Auto-Import Entry Point - static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) { - if (imported.Length == 0) - return; - - // In case user used "Assets -> Reimport All", during the import process, - // asset database is not initialized until some point. During that period, - // all attempts to load any assets using API (i.e. AssetDatabase.LoadAssetAtPath) - // will return null, and as result, assets won't be loaded even if they actually exists, - // which may lead to numerous importing errors. - // This situation also happens if Library folder is deleted from the project, which is a pretty - // common case, since when using version control systems, the Library folder must be excluded. - // - // So to avoid this, in case asset database is not available, we delay loading the assets - // until next time. - // - // Unity *always* reimports some internal assets after the process is done, so this method - // is always called once again in a state when asset database is available. - // - // Checking whether AssetDatabase is initialized is done by attempting to load - // a known "marker" asset that should always be available. Failing to load this asset - // means that AssetDatabase is not initialized. - assetsImportedInWrongState.UnionWith(imported); - if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) { - string[] combinedAssets = assetsImportedInWrongState.ToArray(); - assetsImportedInWrongState.Clear(); - ImportSpineContent(combinedAssets); - } - } - - public static void ImportSpineContent (string[] imported, bool reimport = false) { - var atlasPaths = new List(); - var imagePaths = new List(); - var skeletonPaths = new List(); - - foreach (string str in imported) { - string extension = Path.GetExtension(str).ToLower(); - switch (extension) { - case ".txt": - if (str.EndsWith(".atlas.txt", System.StringComparison.Ordinal)) - atlasPaths.Add(str); - break; - case ".png": - case ".jpg": - imagePaths.Add(str); - break; - case ".json": - var jsonAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(str, typeof(TextAsset)); - if (jsonAsset != null && SkeletonDataFileValidator.IsSpineData(jsonAsset)) - skeletonPaths.Add(str); - break; - case ".bytes": - if (str.ToLower().EndsWith(".skel.bytes", System.StringComparison.Ordinal)) { - if (SkeletonDataFileValidator.IsSpineData((TextAsset)AssetDatabase.LoadAssetAtPath(str, typeof(TextAsset)))) - skeletonPaths.Add(str); - } - break; - } - } - - // Import atlases first. - var atlases = new List(); - foreach (string ap in atlasPaths) { - TextAsset atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(ap, typeof(TextAsset)); - AtlasAsset atlas = IngestSpineAtlas(atlasText); - atlases.Add(atlas); - } - - // Import skeletons and match them with atlases. - bool abortSkeletonImport = false; - foreach (string sp in skeletonPaths) { - if (!reimport && SkeletonDataFileValidator.CheckForValidSkeletonData(sp)) { - ReloadSkeletonData(sp); - continue; - } - - string dir = Path.GetDirectoryName(sp); - - #if SPINE_TK2D - IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, null); - #else - var localAtlases = FindAtlasesAtPath(dir); - var requiredPaths = GetRequiredAtlasRegions(sp); - var atlasMatch = GetMatchingAtlas(requiredPaths, localAtlases); - if (atlasMatch != null || requiredPaths.Count == 0) { - IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, atlasMatch); - } else { - bool resolved = false; - while (!resolved) { - - string filename = Path.GetFileNameWithoutExtension(sp); - int result = EditorUtility.DisplayDialogComplex( - string.Format("AtlasAsset for \"{0}\"", filename), - string.Format("Could not automatically set the AtlasAsset for \"{0}\". You may set it manually.", filename), - "Choose AtlasAssets...", "Skip this", "Stop importing all" - ); - - switch (result) { - case -1: - //Debug.Log("Select Atlas"); - AtlasAsset selectedAtlas = GetAtlasDialog(Path.GetDirectoryName(sp)); - if (selectedAtlas != null) { - localAtlases.Clear(); - localAtlases.Add(selectedAtlas); - atlasMatch = GetMatchingAtlas(requiredPaths, localAtlases); - if (atlasMatch != null) { - resolved = true; - IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, atlasMatch); - } - } - break; - case 0: // Choose AtlasAssets... - var atlasList = MultiAtlasDialog(requiredPaths, Path.GetDirectoryName(sp), Path.GetFileNameWithoutExtension(sp)); - if (atlasList != null) - IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, atlasList.ToArray()); - - resolved = true; - break; - case 1: // Skip - Debug.Log("Skipped importing: " + Path.GetFileName(sp)); - resolved = true; - break; - case 2: // Stop importing all - abortSkeletonImport = true; - resolved = true; - break; - } - } - } - - if (abortSkeletonImport) - break; - #endif - } - // Any post processing of images - } - - static void ReloadSkeletonData (string skeletonJSONPath) { - string dir = Path.GetDirectoryName(skeletonJSONPath); - TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset)); - DirectoryInfo dirInfo = new DirectoryInfo(dir); - FileInfo[] files = dirInfo.GetFiles("*.asset"); - - foreach (var f in files) { - string localPath = dir + "/" + f.Name; - var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object)); - var skeletonDataAsset = obj as SkeletonDataAsset; - if (skeletonDataAsset != null) { - if (skeletonDataAsset.skeletonJSON == textAsset) { - if (Selection.activeObject == skeletonDataAsset) - Selection.activeObject = null; - - Debug.LogFormat("Changes to '{0}' detected. Clearing SkeletonDataAsset: {1}", skeletonJSONPath, localPath); - skeletonDataAsset.Clear(); - - string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skeletonDataAsset)); - string lastHash = EditorPrefs.GetString(guid + "_hash"); - - // For some weird reason sometimes Unity loses the internal Object pointer, - // and as a result, all comparisons with null returns true. - // But the C# wrapper is still alive, so we can "restore" the object - // by reloading it from its Instance ID. - AtlasAsset[] skeletonDataAtlasAssets = skeletonDataAsset.atlasAssets; - if (skeletonDataAtlasAssets != null) { - for (int i = 0; i < skeletonDataAtlasAssets.Length; i++) { - if (!ReferenceEquals(null, skeletonDataAtlasAssets[i]) && - skeletonDataAtlasAssets[i].Equals(null) && - skeletonDataAtlasAssets[i].GetInstanceID() != 0 - ) { - skeletonDataAtlasAssets[i] = EditorUtility.InstanceIDToObject(skeletonDataAtlasAssets[i].GetInstanceID()) as AtlasAsset; - } - } - } - - SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true); - string currentHash = skeletonData != null ? skeletonData.Hash : null; - - #if SPINE_SKELETONANIMATOR - if (currentHash == null || lastHash != currentHash) - UpdateMecanimClips(skeletonDataAsset); - #endif - - // if (currentHash == null || lastHash != currentHash) - // Do any upkeep on synchronized assets - - if (currentHash != null) - EditorPrefs.SetString(guid + "_hash", currentHash); - } - } - } - } - #endregion - - #region Match SkeletonData with Atlases - static readonly AttachmentType[] AtlasTypes = { AttachmentType.Region, AttachmentType.Linkedmesh, AttachmentType.Mesh }; - - static List MultiAtlasDialog (List requiredPaths, string initialDirectory, string filename = "") { - List atlasAssets = new List(); - bool resolved = false; - string lastAtlasPath = initialDirectory; - while (!resolved) { - - // Build dialog box message. - var missingRegions = new List(requiredPaths); - var dialogText = new StringBuilder(); - { - dialogText.AppendLine(string.Format("SkeletonDataAsset for \"{0}\"", filename)); - dialogText.AppendLine("has missing regions."); - dialogText.AppendLine(); - dialogText.AppendLine("Current Atlases:"); - - if (atlasAssets.Count == 0) - dialogText.AppendLine("\t--none--"); - - for (int i = 0; i < atlasAssets.Count; i++) - dialogText.AppendLine("\t" + atlasAssets[i].name); - - dialogText.AppendLine(); - dialogText.AppendLine("Missing Regions:"); - - foreach (var atlasAsset in atlasAssets) { - var atlas = atlasAsset.GetAtlas(); - for (int i = 0; i < missingRegions.Count; i++) { - if (atlas.FindRegion(missingRegions[i]) != null) { - missingRegions.RemoveAt(i); - i--; - } - } - } - - int n = missingRegions.Count; - if (n == 0) break; - - const int MaxListLength = 15; - for (int i = 0; (i < n && i < MaxListLength); i++) - dialogText.AppendLine("\t" + missingRegions[i]); - - if (n > MaxListLength) dialogText.AppendLine(string.Format("\t... {0} more...", n - MaxListLength)); - } - - // Show dialog box. - int result = EditorUtility.DisplayDialogComplex( - "SkeletonDataAsset has missing Atlas.", - dialogText.ToString(), - "Browse...", "Import anyway", "Cancel" - ); - - switch (result) { - case 0: // Browse... - AtlasAsset selectedAtlasAsset = GetAtlasDialog(lastAtlasPath); - if (selectedAtlasAsset != null) { - var atlas = selectedAtlasAsset.GetAtlas(); - bool hasValidRegion = false; - foreach (string str in missingRegions) { - if (atlas.FindRegion(str) != null) { - hasValidRegion = true; - break; - } - } - atlasAssets.Add(selectedAtlasAsset); - } - break; - case 1: // Import anyway - resolved = true; - break; - case 2: // Cancel - atlasAssets = null; - resolved = true; - break; - } - } - - return atlasAssets; - } - - static AtlasAsset GetAtlasDialog (string dirPath) { - string path = EditorUtility.OpenFilePanel("Select AtlasAsset...", dirPath, "asset"); - if (path == "") return null; // Canceled or closed by user. - - int subLen = Application.dataPath.Length - 6; - string assetRelativePath = path.Substring(subLen, path.Length - subLen).Replace("\\", "/"); - - Object obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAsset)); - - if (obj == null || obj.GetType() != typeof(AtlasAsset)) - return null; - - return (AtlasAsset)obj; - } - - static void AddRequiredAtlasRegionsFromBinary (string skeletonDataPath, List requiredPaths) { - SkeletonBinary binary = new SkeletonBinary(new AtlasRequirementLoader(requiredPaths)); - TextAsset data = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset)); - MemoryStream input = new MemoryStream(data.bytes); - binary.ReadSkeletonData(input); - binary = null; - } - - public static List GetRequiredAtlasRegions (string skeletonDataPath) { - List requiredPaths = new List(); - - if (skeletonDataPath.Contains(".skel")) { - AddRequiredAtlasRegionsFromBinary(skeletonDataPath, requiredPaths); - return requiredPaths; - } - - TextAsset spineJson = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset)); - - StringReader reader = new StringReader(spineJson.text); - var root = Json.Deserialize(reader) as Dictionary; - - if (!root.ContainsKey("skins")) - return requiredPaths; - - foreach (KeyValuePair entry in (Dictionary)root["skins"]) { - foreach (KeyValuePair slotEntry in (Dictionary)entry.Value) { - - foreach (KeyValuePair attachmentEntry in ((Dictionary)slotEntry.Value)) { - var data = ((Dictionary)attachmentEntry.Value); - - // Ignore non-atlas-requiring types. - if (data.ContainsKey("type")) { - AttachmentType attachmentType; - string typeString = (string)data["type"]; - try { - attachmentType = (AttachmentType)System.Enum.Parse(typeof(AttachmentType), typeString, true); - } catch (System.ArgumentException e) { - // For more info, visit: http://esotericsoftware.com/forum/Spine-editor-and-runtime-version-management-6534 - Debug.LogWarning(string.Format("Unidentified Attachment type: \"{0}\". Skeleton may have been exported from an incompatible Spine version.", typeString)); - throw e; - } - - if (!AtlasTypes.Contains(attachmentType)) - continue; - } - - if (data.ContainsKey("path")) - requiredPaths.Add((string)data["path"]); - else if (data.ContainsKey("name")) - requiredPaths.Add((string)data["name"]); - else - requiredPaths.Add(attachmentEntry.Key); - } - } - } - - return requiredPaths; - } - - static AtlasAsset GetMatchingAtlas (List requiredPaths, List atlasAssets) { - AtlasAsset atlasAssetMatch = null; - - foreach (AtlasAsset a in atlasAssets) { - Atlas atlas = a.GetAtlas(); - bool failed = false; - foreach (string regionPath in requiredPaths) { - if (atlas.FindRegion(regionPath) == null) { - failed = true; - break; - } - } - - if (!failed) { - atlasAssetMatch = a; - break; - } - } - - return atlasAssetMatch; - } - - public class AtlasRequirementLoader : AttachmentLoader { - List requirementList; - - public AtlasRequirementLoader (List requirementList) { - this.requirementList = requirementList; - } - - public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) { - requirementList.Add(path); - return new RegionAttachment(name); - } - - public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) { - requirementList.Add(path); - return new MeshAttachment(name); - } - - 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); - } - } - #endregion - - #region Import Atlases - static List FindAtlasesAtPath (string path) { - List arr = new List(); - DirectoryInfo dir = new DirectoryInfo(path); - FileInfo[] assetInfoArr = dir.GetFiles("*.asset"); - - int subLen = Application.dataPath.Length - 6; - foreach (var f in assetInfoArr) { - string assetRelativePath = f.FullName.Substring(subLen, f.FullName.Length - subLen).Replace("\\", "/"); - Object obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAsset)); - if (obj != null) - arr.Add(obj as AtlasAsset); - } - - return arr; - } - - static AtlasAsset IngestSpineAtlas (TextAsset atlasText) { - if (atlasText == null) { - Debug.LogWarning("Atlas source cannot be null!"); - return null; - } - - string primaryName = Path.GetFileNameWithoutExtension(atlasText.name).Replace(".atlas", ""); - string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(atlasText)); - - string atlasPath = assetPath + "/" + primaryName + "_Atlas.asset"; - - AtlasAsset atlasAsset = (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset)); - - List vestigialMaterials = new List(); - - if (atlasAsset == null) - atlasAsset = AtlasAsset.CreateInstance(); - else { - foreach (Material m in atlasAsset.materials) - vestigialMaterials.Add(m); - } - - protectFromStackGarbageCollection.Add(atlasAsset); - atlasAsset.atlasFile = atlasText; - - //strip CR - string atlasStr = atlasText.text; - atlasStr = atlasStr.Replace("\r", ""); - - string[] atlasLines = atlasStr.Split('\n'); - List pageFiles = new List(); - for (int i = 0; i < atlasLines.Length - 1; i++) { - if (atlasLines[i].Trim().Length == 0) - pageFiles.Add(atlasLines[i + 1].Trim()); - } - - var populatingMaterials = new List(pageFiles.Count);//atlasAsset.materials = new Material[pageFiles.Count]; - - for (int i = 0; i < pageFiles.Count; i++) { - string texturePath = assetPath + "/" + pageFiles[i]; - Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)); - - if (setTextureImporterSettings) { - TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath); - if (texImporter == null) { - Debug.LogWarning(string.Format("{0} ::: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath)); - continue; - } - - texImporter.textureCompression = TextureImporterCompression.Uncompressed; - texImporter.alphaSource = TextureImporterAlphaSource.FromInput; - texImporter.mipmapEnabled = false; - texImporter.alphaIsTransparency = false; // Prevent the texture importer from applying bleed to the transparent parts for PMA. - texImporter.spriteImportMode = SpriteImportMode.None; - texImporter.maxTextureSize = 2048; - - EditorUtility.SetDirty(texImporter); - AssetDatabase.ImportAsset(texturePath); - AssetDatabase.SaveAssets(); - } - - string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]); - - //because this looks silly - if (pageName == primaryName && pageFiles.Count == 1) - pageName = "Material"; - - string materialPath = assetPath + "/" + primaryName + "_" + pageName + ".mat"; - Material mat = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)); - - if (mat == null) { - mat = new Material(Shader.Find(defaultShader)); - AssetDatabase.CreateAsset(mat, materialPath); - } else { - vestigialMaterials.Remove(mat); - } - - mat.mainTexture = texture; - EditorUtility.SetDirty(mat); - AssetDatabase.SaveAssets(); - - populatingMaterials.Add(mat); //atlasAsset.materials[i] = mat; - } - - atlasAsset.materials = populatingMaterials.ToArray(); - - for (int i = 0; i < vestigialMaterials.Count; i++) - AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(vestigialMaterials[i])); - - if (AssetDatabase.GetAssetPath(atlasAsset) == "") - AssetDatabase.CreateAsset(atlasAsset, atlasPath); - else - atlasAsset.Clear(); - - EditorUtility.SetDirty(atlasAsset); - AssetDatabase.SaveAssets(); - - if (pageFiles.Count != atlasAsset.materials.Length) - Debug.LogWarning(string.Format("{0} ::: Not all atlas pages were imported. If you rename your image files, please make sure you also edit the filenames specified in the atlas file.", atlasAsset.name)); - else - Debug.Log(string.Format("{0} ::: Imported with {1} material", atlasAsset.name, atlasAsset.materials.Length)); - - // Iterate regions and bake marked. - Atlas atlas = atlasAsset.GetAtlas(); - FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic); - List regions = (List)field.GetValue(atlas); - string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset); - string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath); - string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name); - - bool hasBakedRegions = false; - for (int i = 0; i < regions.Count; i++) { - AtlasRegion region = regions[i]; - string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeName(region.name) + ".prefab").Replace("\\", "/"); - GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject)); - if (prefab != null) { - BakeRegion(atlasAsset, region, false); - hasBakedRegions = true; - } - } - - if (hasBakedRegions) { - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - } - - protectFromStackGarbageCollection.Remove(atlasAsset); - return (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset)); - } - #endregion - - #region Bake Atlas Region - public static GameObject BakeRegion (AtlasAsset atlasAsset, AtlasRegion region, bool autoSave = true) { - Atlas atlas = atlasAsset.GetAtlas(); - string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset); - string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath); - string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name); - string bakedPrefabPath = Path.Combine(bakedDirPath, GetPathSafeName(region.name) + ".prefab").Replace("\\", "/"); - - GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject)); - GameObject root; - Mesh mesh; - bool isNewPrefab = false; - - if (!Directory.Exists(bakedDirPath)) - Directory.CreateDirectory(bakedDirPath); - - if (prefab == null) { - root = new GameObject("temp", typeof(MeshFilter), typeof(MeshRenderer)); - prefab = PrefabUtility.CreatePrefab(bakedPrefabPath, root); - isNewPrefab = true; - Object.DestroyImmediate(root); - } - - mesh = (Mesh)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(Mesh)); - - Material mat = null; - mesh = atlasAsset.GenerateMesh(region.name, mesh, out mat); - if (isNewPrefab) { - AssetDatabase.AddObjectToAsset(mesh, prefab); - prefab.GetComponent().sharedMesh = mesh; - } - - EditorUtility.SetDirty(mesh); - EditorUtility.SetDirty(prefab); - - if (autoSave) { - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - } - - prefab.GetComponent().sharedMaterial = mat; - - return prefab; - } - #endregion - - #region Import SkeletonData (json or binary) - public const string SkeletonDataSuffix = "_SkeletonData"; - static SkeletonDataAsset IngestSpineProject (TextAsset spineJson, params AtlasAsset[] atlasAssets) { - string primaryName = Path.GetFileNameWithoutExtension(spineJson.name); - string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson)); - string filePath = assetPath + "/" + primaryName + SkeletonDataSuffix + ".asset"; - - #if SPINE_TK2D - if (spineJson != null) { - SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset)); - if (skeletonDataAsset == null) { - skeletonDataAsset = SkeletonDataAsset.CreateInstance(); - skeletonDataAsset.skeletonJSON = spineJson; - skeletonDataAsset.fromAnimation = new string[0]; - skeletonDataAsset.toAnimation = new string[0]; - skeletonDataAsset.duration = new float[0]; - skeletonDataAsset.defaultMix = defaultMix; - skeletonDataAsset.scale = defaultScale; - - AssetDatabase.CreateAsset(skeletonDataAsset, filePath); - AssetDatabase.SaveAssets(); - } else { - skeletonDataAsset.Clear(); - skeletonDataAsset.GetSkeletonData(true); - } - - return skeletonDataAsset; - } else { - EditorUtility.DisplayDialog("Error!", "Tried to ingest null Spine data.", "OK"); - return null; - } - - #else - if (spineJson != null && atlasAssets != null) { - SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset)); - if (skeletonDataAsset == null) { - skeletonDataAsset = ScriptableObject.CreateInstance(); { - skeletonDataAsset.atlasAssets = atlasAssets; - skeletonDataAsset.skeletonJSON = spineJson; - skeletonDataAsset.defaultMix = defaultMix; - skeletonDataAsset.scale = defaultScale; - } - - AssetDatabase.CreateAsset(skeletonDataAsset, filePath); - AssetDatabase.SaveAssets(); - } else { - skeletonDataAsset.atlasAssets = atlasAssets; - skeletonDataAsset.Clear(); - skeletonDataAsset.GetSkeletonData(true); - } - - return skeletonDataAsset; - } else { - EditorUtility.DisplayDialog("Error!", "Must specify both Spine JSON and AtlasAsset array", "OK"); - return null; - } - #endif - } - #endregion - - #region SkeletonDataFileValidator - internal static class SkeletonDataFileValidator { - static int[][] compatibleBinaryVersions = { new[] { 3, 6, 0 }, new[] { 3, 5, 0 } }; - static int[][] compatibleJsonVersions = { new[] { 3, 6, 0 }, new[] { 3, 7, 0 }, new[] { 3, 5, 0 } }; - //static bool isFixVersionRequired = false; - - public static bool CheckForValidSkeletonData (string skeletonJSONPath) { - string dir = Path.GetDirectoryName(skeletonJSONPath); - TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset)); - DirectoryInfo dirInfo = new DirectoryInfo(dir); - FileInfo[] files = dirInfo.GetFiles("*.asset"); - - foreach (var path in files) { - string localPath = dir + "/" + path.Name; - var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object)); - var skeletonDataAsset = obj as SkeletonDataAsset; - if (skeletonDataAsset != null && skeletonDataAsset.skeletonJSON == textAsset) - return true; - } - - return false; - } - - public static bool IsSpineData (TextAsset asset) { - if (asset == null) - return false; - - bool isSpineData = false; - string rawVersion = null; - - int[][] compatibleVersions; - if (asset.name.Contains(".skel")) { - try { - rawVersion = SkeletonBinary.GetVersionString(new MemoryStream(asset.bytes)); - isSpineData = !(string.IsNullOrEmpty(rawVersion)); - compatibleVersions = compatibleBinaryVersions; - } catch (System.Exception e) { - Debug.LogErrorFormat("Failed to read '{0}'. It is likely not a binary Spine SkeletonData file.\n{1}", asset.name, e); - return false; - } - } else { - object obj = Json.Deserialize(new StringReader(asset.text)); - if (obj == null) { - Debug.LogErrorFormat("'{0}' is not valid JSON.", asset.name); - return false; - } - - var root = obj as Dictionary; - if (root == null) { - Debug.LogError("Parser returned an incorrect type."); - return false; - } - - isSpineData = root.ContainsKey("skeleton"); - if (isSpineData) { - var skeletonInfo = (Dictionary)root["skeleton"]; - object jv; - skeletonInfo.TryGetValue("spine", out jv); - rawVersion = jv as string; - } - - compatibleVersions = compatibleJsonVersions; - } - - // Version warning - if (isSpineData) { - string primaryRuntimeVersionDebugString = compatibleVersions[0][0] + "." + compatibleVersions[0][1]; - - if (string.IsNullOrEmpty(rawVersion)) { - Debug.LogWarningFormat("Skeleton '{0}' has no version information. It may be incompatible with your runtime version: spine-unity v{1}", asset.name, primaryRuntimeVersionDebugString); - } else { - string[] versionSplit = rawVersion.Split('.'); - bool match = false; - foreach (var version in compatibleVersions) { - bool primaryMatch = version[0] == int.Parse(versionSplit[0]); - bool secondaryMatch = version[1] == int.Parse(versionSplit[1]); - - // if (isFixVersionRequired) secondaryMatch &= version[2] <= int.Parse(jsonVersionSplit[2]); - - if (primaryMatch && secondaryMatch) { - match = true; - break; - } - } - - if (!match) - Debug.LogWarningFormat("Skeleton '{0}' (exported with Spine {1}) may be incompatible with your runtime version: spine-unity v{2}", asset.name, rawVersion, primaryRuntimeVersionDebugString); - } - } - - return isSpineData; - } - } - - #endregion - - #region SkeletonAnimation Menu - public static void IngestAdvancedRenderSettings (SkeletonRenderer skeletonRenderer) { - const string PMAShaderQuery = "Spine/Skeleton"; - const string TintBlackShaderQuery = "Tint Black"; - - if (skeletonRenderer == null) return; - var skeletonDataAsset = skeletonRenderer.skeletonDataAsset; - if (skeletonDataAsset == null) return; - - bool pmaVertexColors = false; - bool tintBlack = false; - foreach (AtlasAsset atlasAsset in skeletonDataAsset.atlasAssets) { - if (!pmaVertexColors) { - foreach (Material m in atlasAsset.materials) { - if (m.shader.name.Contains(PMAShaderQuery)) { - pmaVertexColors = true; - break; - } - } - } - - if (!tintBlack) { - foreach (Material m in atlasAsset.materials) { - if (m.shader.name.Contains(TintBlackShaderQuery)) { - tintBlack = true; - break; - } - } - } - } - - skeletonRenderer.pmaVertexColors = pmaVertexColors; - skeletonRenderer.tintBlack = tintBlack; - } - - public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, string skinName, bool destroyInvalid = true) { - var skeletonData = skeletonDataAsset.GetSkeletonData(true); - var skin = skeletonData != null ? skeletonData.FindSkin(skinName) : null; - return InstantiateSkeletonAnimation(skeletonDataAsset, skin, destroyInvalid); - } - - public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, Skin skin = null, bool destroyInvalid = true) { - SkeletonData data = skeletonDataAsset.GetSkeletonData(true); - - if (data == null) { - for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) { - string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]); - skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset)); - } - data = skeletonDataAsset.GetSkeletonData(false); - } - - if (data == null) { - Debug.LogWarning("InstantiateSkeletonAnimation tried to instantiate a skeleton from an invalid SkeletonDataAsset."); - return null; - } - - string spineGameObjectName = string.Format("Spine GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", "")); - GameObject go = new GameObject(spineGameObjectName, typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation)); - SkeletonAnimation newSkeletonAnimation = go.GetComponent(); - newSkeletonAnimation.skeletonDataAsset = skeletonDataAsset; - IngestAdvancedRenderSettings(newSkeletonAnimation); - - try { - newSkeletonAnimation.Initialize(false); - } catch (System.Exception e) { - if (destroyInvalid) { - Debug.LogWarning("Editor-instantiated SkeletonAnimation threw an Exception. Destroying GameObject to prevent orphaned GameObject."); - GameObject.DestroyImmediate(go); - } - throw e; - } - - // Set Defaults - bool noSkins = data.DefaultSkin == null && (data.Skins == null || data.Skins.Count == 0); // Support attachmentless/skinless SkeletonData. - skin = skin ?? data.DefaultSkin ?? (noSkins ? null : data.Skins.Items[0]); - if (skin != null) { - newSkeletonAnimation.initialSkinName = skin.Name; - newSkeletonAnimation.skeleton.SetSkin(skin); - } - - newSkeletonAnimation.zSpacing = defaultZSpacing; - - newSkeletonAnimation.skeleton.Update(0); - newSkeletonAnimation.state.Update(0); - newSkeletonAnimation.state.Apply(newSkeletonAnimation.skeleton); - newSkeletonAnimation.skeleton.UpdateWorldTransform(); - - return newSkeletonAnimation; - } - #endregion - - #region SkeletonAnimator - #if SPINE_SKELETONANIMATOR - static void UpdateMecanimClips (SkeletonDataAsset skeletonDataAsset) { - if (skeletonDataAsset.controller == null) - return; - - SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset); - } - - public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, string skinName) { - return InstantiateSkeletonAnimator(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName)); - } - - public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, Skin skin = null) { - string spineGameObjectName = string.Format("Spine Mecanim GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", "")); - GameObject go = new GameObject(spineGameObjectName, typeof(MeshFilter), typeof(MeshRenderer), typeof(Animator), typeof(SkeletonAnimator)); - - if (skeletonDataAsset.controller == null) { - SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset); - Debug.Log(string.Format("Mecanim controller was automatically generated and assigned for {0}", skeletonDataAsset.name)); - } - - go.GetComponent().runtimeAnimatorController = skeletonDataAsset.controller; - - SkeletonAnimator anim = go.GetComponent(); - anim.skeletonDataAsset = skeletonDataAsset; - IngestAdvancedRenderSettings(anim); - - SkeletonData data = skeletonDataAsset.GetSkeletonData(true); - if (data == null) { - for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) { - string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]); - skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset)); - } - data = skeletonDataAsset.GetSkeletonData(true); - } - - // Set defaults - skin = skin ?? data.DefaultSkin ?? data.Skins.Items[0]; - anim.zSpacing = defaultZSpacing; - - anim.Initialize(false); - anim.skeleton.SetSkin(skin); - anim.initialSkinName = skin.Name; - - anim.skeleton.Update(0); - anim.skeleton.UpdateWorldTransform(); - anim.LateUpdate(); - - return anim; - } -#endif - #endregion - - #region SpineTK2DEditorUtility - internal static class SpineTK2DEditorUtility { - const string SPINE_TK2D_DEFINE = "SPINE_TK2D"; - - static bool IsInvalidGroup (BuildTargetGroup group) { - int gi = (int)group; - return - gi == 15 || gi == 16 - || - group == BuildTargetGroup.Unknown; - } - - internal static void EnableTK2D () { - bool added = false; - foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) { - if (IsInvalidGroup(group)) - continue; - - string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group); - if (!defines.Contains(SPINE_TK2D_DEFINE)) { - added = true; - if (defines.EndsWith(";", System.StringComparison.Ordinal)) - defines = defines + SPINE_TK2D_DEFINE; - else - defines = defines + ";" + SPINE_TK2D_DEFINE; - - PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines); - } - } - - if (added) { - Debug.LogWarning("Setting Scripting Define Symbol " + SPINE_TK2D_DEFINE); - } else { - Debug.LogWarning("Already Set Scripting Define Symbol " + SPINE_TK2D_DEFINE); - } - } - - - internal static void DisableTK2D () { - bool removed = false; - foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) { - if (IsInvalidGroup(group)) - continue; - - string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group); - if (defines.Contains(SPINE_TK2D_DEFINE)) { - removed = true; - if (defines.Contains(SPINE_TK2D_DEFINE + ";")) - defines = defines.Replace(SPINE_TK2D_DEFINE + ";", ""); - else - defines = defines.Replace(SPINE_TK2D_DEFINE, ""); - - PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines); - } - } - - if (removed) { - Debug.LogWarning("Removing Scripting Define Symbol " + SPINE_TK2D_DEFINE); - } else { - Debug.LogWarning("Already Removed Scripting Define Symbol " + SPINE_TK2D_DEFINE); - } - } - } - #endregion - - public static string GetPathSafeName (string name) { - foreach (char c in System.IO.Path.GetInvalidFileNameChars()) { // Doesn't handle more obscure file name limitations. - name = name.Replace(c, '_'); - } - return name; - } - } - - public static class SpineHandles { - internal static float handleScale = 1f; - public static Color BoneColor { get { return new Color(0.8f, 0.8f, 0.8f, 0.4f); } } - public static Color PathColor { get { return new Color(254/255f, 127/255f, 0); } } - public static Color TransformContraintColor { get { return new Color(170/255f, 226/255f, 35/255f); } } - public static Color IkColor { get { return new Color(228/255f,90/255f,43/255f); } } - public static Color PointColor { get { return new Color(1f, 1f, 0f, 1f); } } - - static Vector3[] _boneMeshVerts = { - new Vector3(0, 0, 0), - new Vector3(0.1f, 0.1f, 0), - new Vector3(1, 0, 0), - new Vector3(0.1f, -0.1f, 0) - }; - static Mesh _boneMesh; - public static Mesh BoneMesh { - get { - if (_boneMesh == null) { - _boneMesh = new Mesh { - vertices = _boneMeshVerts, - uv = new Vector2[4], - triangles = new [] { 0, 1, 2, 2, 3, 0 } - }; - _boneMesh.RecalculateBounds(); - _boneMesh.RecalculateNormals(); - } - return _boneMesh; - } - } - - static Mesh _arrowheadMesh; - public static Mesh ArrowheadMesh { - get { - if (_arrowheadMesh == null) { - _arrowheadMesh = new Mesh { - vertices = new [] { - new Vector3(0, 0), - new Vector3(-0.1f, 0.05f), - new Vector3(-0.1f, -0.05f) - }, - uv = new Vector2[3], - triangles = new [] { 0, 1, 2 } - }; - _arrowheadMesh.RecalculateBounds(); - _arrowheadMesh.RecalculateNormals(); - } - return _arrowheadMesh; - } - } - - static Material _boneMaterial; - static Material BoneMaterial { - get { - if (_boneMaterial == null) { - _boneMaterial = new Material(Shader.Find("Hidden/Spine/Bones")); - _boneMaterial.SetColor("_Color", SpineHandles.BoneColor); - } - - return _boneMaterial; - } - } - public static Material GetBoneMaterial () { - BoneMaterial.SetColor("_Color", SpineHandles.BoneColor); - return BoneMaterial; - } - - public static Material GetBoneMaterial (Color color) { - BoneMaterial.SetColor("_Color", color); - return BoneMaterial; - } - - static Material _ikMaterial; - public static Material IKMaterial { - get { - if (_ikMaterial == null) { - _ikMaterial = new Material(Shader.Find("Hidden/Spine/Bones")); - _ikMaterial.SetColor("_Color", SpineHandles.IkColor); - } - return _ikMaterial; - } - } - - static GUIStyle _boneNameStyle; - public static GUIStyle BoneNameStyle { - get { - if (_boneNameStyle == null) { - _boneNameStyle = new GUIStyle(EditorStyles.whiteMiniLabel) { - alignment = TextAnchor.MiddleCenter, - stretchWidth = true, - padding = new RectOffset(0, 0, 0, 0), - contentOffset = new Vector2(-5f, 0f) - }; - } - return _boneNameStyle; - } - } - - static GUIStyle _pathNameStyle; - public static GUIStyle PathNameStyle { - get { - if (_pathNameStyle == null) { - _pathNameStyle = new GUIStyle(SpineHandles.BoneNameStyle); - _pathNameStyle.normal.textColor = SpineHandles.PathColor; - } - return _pathNameStyle; - } - } - - static GUIStyle _pointNameStyle; - public static GUIStyle PointNameStyle { - get { - if (_pointNameStyle == null) { - _pointNameStyle = new GUIStyle(SpineHandles.BoneNameStyle); - _pointNameStyle.normal.textColor = SpineHandles.PointColor; - } - return _pointNameStyle; - } - } - - public static void DrawBoneNames (Transform transform, Skeleton skeleton, float positionScale = 1f) { - GUIStyle style = BoneNameStyle; - foreach (Bone b in skeleton.Bones) { - var pos = new Vector3(b.WorldX * positionScale, b.WorldY * positionScale, 0) + (new Vector3(b.A, b.C) * (b.Data.Length * 0.5f)); - pos = transform.TransformPoint(pos); - Handles.Label(pos, b.Data.Name, style); - } - } - - public static void DrawBones (Transform transform, Skeleton skeleton, float positionScale = 1f) { - float boneScale = 1.8f; // Draw the root bone largest; - DrawCrosshairs2D(skeleton.Bones.Items[0].GetWorldPosition(transform), 0.08f, positionScale); - - foreach (Bone b in skeleton.Bones) { - DrawBone(transform, b, boneScale, positionScale); - boneScale = 1f; - } - } - - static Vector3[] _boneWireBuffer = new Vector3[5]; - static Vector3[] GetBoneWireBuffer (Matrix4x4 m) { - for (int i = 0, n = _boneMeshVerts.Length; i < n; i++) - _boneWireBuffer[i] = m.MultiplyPoint(_boneMeshVerts[i]); - - _boneWireBuffer[4] = _boneWireBuffer[0]; // closed polygon. - return _boneWireBuffer; - } - public static void DrawBoneWireframe (Transform transform, Bone b, Color color, float skeletonRenderScale = 1f) { - Handles.color = color; - var pos = new Vector3(b.WorldX * skeletonRenderScale, b.WorldY * skeletonRenderScale, 0); - float length = b.Data.Length; - - if (length > 0) { - Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); - Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale; - const float my = 1.5f; - scale.y *= (SpineHandles.handleScale + 1) * 0.5f; - scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale); - Handles.DrawPolyLine(GetBoneWireBuffer(transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale))); - var wp = transform.TransformPoint(pos); - DrawBoneCircle(wp, color, transform.forward, skeletonRenderScale); - } else { - var wp = transform.TransformPoint(pos); - DrawBoneCircle(wp, color, transform.forward, skeletonRenderScale); - } - } - - public static void DrawBone (Transform transform, Bone b, float boneScale, float skeletonRenderScale = 1f) { - var pos = new Vector3(b.WorldX * skeletonRenderScale, b.WorldY * skeletonRenderScale, 0); - float length = b.Data.Length; - if (length > 0) { - Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); - Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale; - const float my = 1.5f; - scale.y *= (SpineHandles.handleScale + 1f) * 0.5f; - scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale); - SpineHandles.GetBoneMaterial().SetPass(0); - Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale)); - } else { - var wp = transform.TransformPoint(pos); - DrawBoneCircle(wp, SpineHandles.BoneColor, transform.forward, boneScale * skeletonRenderScale); - } - } - - public static void DrawBone (Transform transform, Bone b, float boneScale, Color color, float skeletonRenderScale = 1f) { - var pos = new Vector3(b.WorldX * skeletonRenderScale, b.WorldY * skeletonRenderScale, 0); - float length = b.Data.Length; - if (length > 0) { - Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); - Vector3 scale = Vector3.one * length * b.WorldScaleX; - const float my = 1.5f; - scale.y *= (SpineHandles.handleScale + 1f) * 0.5f; - scale.y = Mathf.Clamp(scale.x, -my, my); - SpineHandles.GetBoneMaterial(color).SetPass(0); - Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale)); - } else { - var wp = transform.TransformPoint(pos); - DrawBoneCircle(wp, color, transform.forward, boneScale * skeletonRenderScale); - } - } - - public static void DrawPaths (Transform transform, Skeleton skeleton) { - foreach (Slot s in skeleton.DrawOrder) { - var p = s.Attachment as PathAttachment; - if (p != null) SpineHandles.DrawPath(s, p, transform, true); - } - } - - static float[] pathVertexBuffer; - public static void DrawPath (Slot s, PathAttachment p, Transform t, bool includeName) { - int worldVerticesLength = p.WorldVerticesLength; - - if (pathVertexBuffer == null || pathVertexBuffer.Length < worldVerticesLength) - pathVertexBuffer = new float[worldVerticesLength]; - - float[] pv = pathVertexBuffer; - p.ComputeWorldVertices(s, pv); - - var ocolor = Handles.color; - Handles.color = SpineHandles.PathColor; - - Matrix4x4 m = t.localToWorldMatrix; - const int step = 6; - int n = worldVerticesLength - step; - Vector3 p0, p1, p2, p3; - for (int i = 2; i < n; i += step) { - p0 = m.MultiplyPoint(new Vector3(pv[i], pv[i+1])); - p1 = m.MultiplyPoint(new Vector3(pv[i+2], pv[i+3])); - p2 = m.MultiplyPoint(new Vector3(pv[i+4], pv[i+5])); - p3 = m.MultiplyPoint(new Vector3(pv[i+6], pv[i+7])); - DrawCubicBezier(p0, p1, p2, p3); - } - - n += step; - if (p.Closed) { - p0 = m.MultiplyPoint(new Vector3(pv[n - 4], pv[n - 3])); - p1 = m.MultiplyPoint(new Vector3(pv[n - 2], pv[n - 1])); - p2 = m.MultiplyPoint(new Vector3(pv[0], pv[1])); - p3 = m.MultiplyPoint(new Vector3(pv[2], pv[3])); - DrawCubicBezier(p0, p1, p2, p3); - } - - const float endCapSize = 0.05f; - Vector3 firstPoint = m.MultiplyPoint(new Vector3(pv[2], pv[3])); - SpineHandles.DrawDot(firstPoint, endCapSize); - - //if (!p.Closed) SpineHandles.DrawDot(m.MultiplyPoint(new Vector3(pv[n - 4], pv[n - 3])), endCapSize); - if (includeName) Handles.Label(firstPoint + new Vector3(0,0.1f), p.Name, PathNameStyle); - - Handles.color = ocolor; - } - - public static void DrawDot (Vector3 position, float size) { - Handles.DotHandleCap(0, position, Quaternion.identity, size * HandleUtility.GetHandleSize(position), EventType.Ignore); //Handles.DotCap(0, position, Quaternion.identity, size * HandleUtility.GetHandleSize(position)); - } - - public static void DrawBoundingBoxes (Transform transform, Skeleton skeleton) { - foreach (var slot in skeleton.Slots) { - var bba = slot.Attachment as BoundingBoxAttachment; - if (bba != null) SpineHandles.DrawBoundingBox(slot, bba, transform); - } - } - - public static void DrawBoundingBox (Slot slot, BoundingBoxAttachment box, Transform t) { - if (box.Vertices.Length <= 2) return; // Handle cases where user creates a BoundingBoxAttachment but doesn't actually define it. - - var worldVerts = new float[box.WorldVerticesLength]; - box.ComputeWorldVertices(slot, worldVerts); - - Handles.color = Color.green; - Vector3 lastVert = Vector3.zero; - Vector3 vert = Vector3.zero; - Vector3 firstVert = t.TransformPoint(new Vector3(worldVerts[0], worldVerts[1], 0)); - for (int i = 0; i < worldVerts.Length; i += 2) { - vert.x = worldVerts[i]; - vert.y = worldVerts[i + 1]; - vert.z = 0; - - vert = t.TransformPoint(vert); - - if (i > 0) - Handles.DrawLine(lastVert, vert); - - lastVert = vert; - } - - Handles.DrawLine(lastVert, firstVert); - } - - public static void DrawPointAttachment (Bone bone, PointAttachment pointAttachment, Transform skeletonTransform) { - if (bone == null) return; - if (pointAttachment == null) return; - - Vector2 localPos; - pointAttachment.ComputeWorldPosition(bone, out localPos.x, out localPos.y); - float localRotation = pointAttachment.ComputeWorldRotation(bone); - Matrix4x4 m = Matrix4x4.TRS(localPos, Quaternion.Euler(0, 0, localRotation), Vector3.one) * Matrix4x4.TRS(Vector3.right * 0.25f, Quaternion.identity, Vector3.one); - - DrawBoneCircle(skeletonTransform.TransformPoint(localPos), SpineHandles.PointColor, Vector3.back, 1.3f); - DrawArrowhead(skeletonTransform.localToWorldMatrix * m); - } - - public static void DrawConstraints (Transform transform, Skeleton skeleton, float skeletonRenderScale = 1f) { - Vector3 targetPos; - Vector3 pos; - bool active; - Color handleColor; - const float Thickness = 4f; - Vector3 normal = transform.forward; - - // Transform Constraints - handleColor = SpineHandles.TransformContraintColor; - foreach (var tc in skeleton.TransformConstraints) { - var targetBone = tc.Target; - targetPos = targetBone.GetWorldPosition(transform, skeletonRenderScale); - - if (tc.TranslateMix > 0) { - if (tc.TranslateMix != 1f) { - Handles.color = handleColor; - foreach (var b in tc.Bones) { - pos = b.GetWorldPosition(transform, skeletonRenderScale); - Handles.DrawDottedLine(targetPos, pos, Thickness); - } - } - SpineHandles.DrawBoneCircle(targetPos, handleColor, normal, 1.3f * skeletonRenderScale); - Handles.color = handleColor; - SpineHandles.DrawCrosshairs(targetPos, 0.2f, targetBone.A, targetBone.B, targetBone.C, targetBone.D, transform, skeletonRenderScale); - } - } - - // IK Constraints - handleColor = SpineHandles.IkColor; - foreach (var ikc in skeleton.IkConstraints) { - Bone targetBone = ikc.Target; - targetPos = targetBone.GetWorldPosition(transform, skeletonRenderScale); - var bones = ikc.Bones; - active = ikc.Mix > 0; - if (active) { - pos = bones.Items[0].GetWorldPosition(transform, skeletonRenderScale); - switch (bones.Count) { - case 1: { - Handles.color = handleColor; - Handles.DrawLine(targetPos, pos); - SpineHandles.DrawBoneCircle(targetPos, handleColor, normal); - var m = bones.Items[0].GetMatrix4x4(); - m.m03 = targetBone.WorldX * skeletonRenderScale; - m.m13 = targetBone.WorldY * skeletonRenderScale; - SpineHandles.DrawArrowhead(transform.localToWorldMatrix * m); - break; - } - case 2: { - Bone childBone = bones.Items[1]; - Vector3 child = childBone.GetWorldPosition(transform, skeletonRenderScale); - Handles.color = handleColor; - Handles.DrawLine(child, pos); - Handles.DrawLine(targetPos, child); - SpineHandles.DrawBoneCircle(pos, handleColor, normal, 0.5f); - SpineHandles.DrawBoneCircle(child, handleColor, normal, 0.5f); - SpineHandles.DrawBoneCircle(targetPos, handleColor, normal); - var m = childBone.GetMatrix4x4(); - m.m03 = targetBone.WorldX * skeletonRenderScale; - m.m13 = targetBone.WorldY * skeletonRenderScale; - SpineHandles.DrawArrowhead(transform.localToWorldMatrix * m); - break; - } - } - } - //Handles.Label(targetPos, ikc.Data.Name, SpineHandles.BoneNameStyle); - } - - // Path Constraints - handleColor = SpineHandles.PathColor; - foreach (var pc in skeleton.PathConstraints) { - active = pc.TranslateMix > 0; - if (active) - foreach (var b in pc.Bones) - SpineHandles.DrawBoneCircle(b.GetWorldPosition(transform, skeletonRenderScale), handleColor, normal, 1f * skeletonRenderScale); - } - } - - static void DrawCrosshairs2D (Vector3 position, float scale, float skeletonRenderScale = 1f) { - scale *= SpineHandles.handleScale * skeletonRenderScale; - Handles.DrawLine(position + new Vector3(-scale, 0), position + new Vector3(scale, 0)); - Handles.DrawLine(position + new Vector3(0, -scale), position + new Vector3(0, scale)); - } - - static void DrawCrosshairs (Vector3 position, float scale, float a, float b, float c, float d, Transform transform, float skeletonRenderScale = 1f) { - scale *= SpineHandles.handleScale * skeletonRenderScale; - - var xOffset = (Vector3)(new Vector2(a, c).normalized * scale); - var yOffset = (Vector3)(new Vector2(b, d).normalized * scale); - xOffset = transform.TransformDirection(xOffset); - yOffset = transform.TransformDirection(yOffset); - - Handles.DrawLine(position + xOffset, position - xOffset); - Handles.DrawLine(position + yOffset, position - yOffset); - } - - static void DrawArrowhead2D (Vector3 pos, float localRotation, float scale = 1f) { - scale *= SpineHandles.handleScale; - - SpineHandles.IKMaterial.SetPass(0); - Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, Matrix4x4.TRS(pos, Quaternion.Euler(0, 0, localRotation), new Vector3(scale, scale, scale))); - } - - static void DrawArrowhead (Vector3 pos, Quaternion worldQuaternion) { - Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, pos, worldQuaternion, 0); - } - - static void DrawArrowhead (Matrix4x4 m) { - float s = SpineHandles.handleScale; - m.m00 *= s; - m.m01 *= s; - m.m02 *= s; - m.m10 *= s; - m.m11 *= s; - m.m12 *= s; - m.m20 *= s; - m.m21 *= s; - m.m22 *= s; - - SpineHandles.IKMaterial.SetPass(0); - Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, m); - } - - static void DrawBoneCircle (Vector3 pos, Color outlineColor, Vector3 normal, float scale = 1f) { - scale *= SpineHandles.handleScale; - - Color o = Handles.color; - Handles.color = outlineColor; - float firstScale = 0.08f * scale; - Handles.DrawSolidDisc(pos, normal, firstScale); - const float Thickness = 0.03f; - float secondScale = firstScale - (Thickness * SpineHandles.handleScale * scale); - - if (secondScale > 0f) { - Handles.color = new Color(0.3f, 0.3f, 0.3f, 0.5f); - Handles.DrawSolidDisc(pos, normal, secondScale); - } - - Handles.color = o; - } - - internal static void DrawCubicBezier (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) { - Handles.DrawBezier(p0, p3, p1, p2, Handles.color, Texture2D.whiteTexture, 2f); - // const float dotSize = 0.01f; - // Quaternion q = Quaternion.identity; - // Handles.DotCap(0, p0, q, dotSize); - // Handles.DotCap(0, p1, q, dotSize); - // Handles.DotCap(0, p2, q, dotSize); - // Handles.DotCap(0, p3, q, dotSize); - // Handles.DrawLine(p0, p1); - // Handles.DrawLine(p3, p2); - } - } - -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +#pragma warning disable 0219 + +// Original contribution by: Mitch Thompson + +#define SPINE_SKELETONANIMATOR +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.Reflection; +using Spine; + +namespace Spine.Unity.Editor { + using EventType = UnityEngine.EventType; + + // Analysis disable once ConvertToStaticType + [InitializeOnLoad] + public class SpineEditorUtilities : AssetPostprocessor { + + public static class Icons { + public static Texture2D skeleton; + public static Texture2D nullBone; + public static Texture2D bone; + public static Texture2D poseBones; + public static Texture2D boneNib; + public static Texture2D slot; + public static Texture2D slotRoot; + public static Texture2D skinPlaceholder; + public static Texture2D image; + public static Texture2D genericAttachment; + public static Texture2D boundingBox; + public static Texture2D point; + public static Texture2D mesh; + public static Texture2D weights; + public static Texture2D path; + public static Texture2D clipping; + public static Texture2D skin; + public static Texture2D skinsRoot; + public static Texture2D animation; + public static Texture2D animationRoot; + 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; + public static Texture2D subMeshRenderer; + public static Texture2D skeletonDataAssetIcon; + public static Texture2D info; + public static Texture2D unity; +// public static Texture2D controllerIcon; + + static Texture2D LoadIcon (string filename) { + return (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/" + filename); + } + + public static void Initialize () { + skeleton = LoadIcon("icon-skeleton.png"); + nullBone = LoadIcon("icon-null.png"); + bone = LoadIcon("icon-bone.png"); + poseBones = LoadIcon("icon-poseBones.png"); + boneNib = LoadIcon("icon-boneNib.png"); + slot = LoadIcon("icon-slot.png"); + slotRoot = LoadIcon("icon-slotRoot.png"); + skinPlaceholder = LoadIcon("icon-skinPlaceholder.png"); + + genericAttachment = LoadIcon("icon-attachment.png"); + image = LoadIcon("icon-image.png"); + boundingBox = LoadIcon("icon-boundingBox.png"); + point = LoadIcon("icon-point.png"); + mesh = LoadIcon("icon-mesh.png"); + weights = LoadIcon("icon-weights.png"); + path = LoadIcon("icon-path.png"); + clipping = LoadIcon("icon-clipping.png"); + + skin = LoadIcon("icon-skin.png"); + skinsRoot = LoadIcon("icon-skinsRoot.png"); + animation = LoadIcon("icon-animation.png"); + animationRoot = LoadIcon("icon-animationRoot.png"); + spine = LoadIcon("icon-spine.png"); + userEvent = LoadIcon("icon-event.png"); + constraintNib = LoadIcon("icon-constraintNib.png"); + + constraintRoot = LoadIcon("icon-constraints.png"); + constraintTransform = LoadIcon("icon-constraintTransform.png"); + constraintPath = LoadIcon("icon-constraintPath.png"); + constraintIK = LoadIcon("icon-constraintIK.png"); + + warning = LoadIcon("icon-warning.png"); + skeletonUtility = LoadIcon("icon-skeletonUtility.png"); + hingeChain = LoadIcon("icon-hingeChain.png"); + subMeshRenderer = LoadIcon("icon-subMeshRenderer.png"); + + skeletonDataAssetIcon = LoadIcon("SkeletonDataAsset Icon.png"); + + info = EditorGUIUtility.FindTexture("console.infoicon.sml"); + unity = EditorGUIUtility.FindTexture("SceneAsset Icon"); +// controllerIcon = EditorGUIUtility.FindTexture("AnimatorController Icon"); + } + + public static Texture2D GetAttachmentIcon (Attachment attachment) { + // Analysis disable once CanBeReplacedWithTryCastAndCheckForNull + if (attachment is RegionAttachment) + return Icons.image; + else if (attachment is MeshAttachment) + return ((MeshAttachment)attachment).IsWeighted() ? Icons.weights : Icons.mesh; + else if (attachment is BoundingBoxAttachment) + return Icons.boundingBox; + else if (attachment is PointAttachment) + return Icons.point; + else if (attachment is PathAttachment) + return Icons.path; + else if (attachment is ClippingAttachment) + return Icons.clipping; + else + return Icons.warning; + } + } + + public static string editorPath = ""; + public static string editorGUIPath = ""; + public static bool initialized; + + /// HACK: This list keeps the asset reference temporarily during importing. + /// + /// In cases of very large projects/sufficient RAM pressure, when AssetDatabase.SaveAssets is called, + /// Unity can mistakenly unload assets whose references are only on the stack. + /// This leads to MissingReferenceException and other errors. + static readonly List protectFromStackGarbageCollection = new List(); + static HashSet assetsImportedInWrongState = new HashSet(); + + #if SPINE_TK2D + const float DEFAULT_DEFAULT_SCALE = 1f; + #else + const float DEFAULT_DEFAULT_SCALE = 0.01f; + #endif + const string DEFAULT_SCALE_KEY = "SPINE_DEFAULT_SCALE"; + public static float defaultScale = DEFAULT_DEFAULT_SCALE; + + const float DEFAULT_DEFAULT_MIX = 0.2f; + const string DEFAULT_MIX_KEY = "SPINE_DEFAULT_MIX"; + public static float defaultMix = DEFAULT_DEFAULT_MIX; + + const string DEFAULT_DEFAULT_SHADER = "Spine/Skeleton"; + const string DEFAULT_SHADER_KEY = "SPINE_DEFAULT_SHADER"; + public static string defaultShader = DEFAULT_DEFAULT_SHADER; + + const float DEFAULT_DEFAULT_ZSPACING = 0f; + const string DEFAULT_ZSPACING_KEY = "SPINE_DEFAULT_ZSPACING"; + public static float defaultZSpacing = DEFAULT_DEFAULT_ZSPACING; + + const bool DEFAULT_SHOW_HIERARCHY_ICONS = true; + const string SHOW_HIERARCHY_ICONS_KEY = "SPINE_SHOW_HIERARCHY_ICONS"; + public static bool showHierarchyIcons = DEFAULT_SHOW_HIERARCHY_ICONS; + + const bool DEFAULT_SET_TEXTUREIMPORTER_SETTINGS = true; + const string SET_TEXTUREIMPORTER_SETTINGS_KEY = "SPINE_SET_TEXTUREIMPORTER_SETTINGS"; + public static bool setTextureImporterSettings = DEFAULT_SET_TEXTUREIMPORTER_SETTINGS; + + internal const float DEFAULT_MIPMAPBIAS = -0.5f; + + public const float DEFAULT_SCENE_ICONS_SCALE = 1f; + public const string SCENE_ICONS_SCALE_KEY = "SPINE_SCENE_ICONS_SCALE"; + + #region Initialization + static SpineEditorUtilities () { + Initialize(); + } + + static void LoadPreferences () { + defaultMix = EditorPrefs.GetFloat(DEFAULT_MIX_KEY, DEFAULT_DEFAULT_MIX); + defaultScale = EditorPrefs.GetFloat(DEFAULT_SCALE_KEY, DEFAULT_DEFAULT_SCALE); + defaultZSpacing = EditorPrefs.GetFloat(DEFAULT_ZSPACING_KEY, DEFAULT_DEFAULT_ZSPACING); + defaultShader = EditorPrefs.GetString(DEFAULT_SHADER_KEY, DEFAULT_DEFAULT_SHADER); + showHierarchyIcons = EditorPrefs.GetBool(SHOW_HIERARCHY_ICONS_KEY, DEFAULT_SHOW_HIERARCHY_ICONS); + setTextureImporterSettings = EditorPrefs.GetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, DEFAULT_SET_TEXTUREIMPORTER_SETTINGS); + SpineHandles.handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, DEFAULT_SCENE_ICONS_SCALE); + preferencesLoaded = true; + } + + static void Initialize () { + LoadPreferences(); + + DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath); + FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories); + editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets")); + editorGUIPath = editorPath + "/GUI"; + + Icons.Initialize(); + + // Drag and Drop + SceneView.onSceneGUIDelegate -= SceneViewDragAndDrop; + SceneView.onSceneGUIDelegate += SceneViewDragAndDrop; + EditorApplication.hierarchyWindowItemOnGUI -= SpineEditorHierarchyHandler.HierarchyDragAndDrop; + EditorApplication.hierarchyWindowItemOnGUI += SpineEditorHierarchyHandler.HierarchyDragAndDrop; + + // Hierarchy Icons + #if UNITY_2017_2_OR_NEWER + EditorApplication.playModeStateChanged -= SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged; + EditorApplication.playModeStateChanged += SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged; + SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode); + #else + EditorApplication.playmodeStateChanged -= SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged; + EditorApplication.playmodeStateChanged += SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged; + SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(); + #endif + + initialized = true; + } + + public static void ConfirmInitialization () { + if (!initialized || Icons.skeleton == null) + Initialize(); + } + #endregion + + #region Spine Preferences and Defaults + static bool preferencesLoaded = false; + + [PreferenceItem("Spine")] + static void PreferencesGUI () { + if (!preferencesLoaded) + LoadPreferences(); + + EditorGUI.BeginChangeCheck(); + showHierarchyIcons = EditorGUILayout.Toggle(new GUIContent("Show Hierarchy Icons", "Show relevant icons on GameObjects with Spine Components on them. Disable this if you have large, complex scenes."), showHierarchyIcons); + if (EditorGUI.EndChangeCheck()) { + EditorPrefs.SetBool(SHOW_HIERARCHY_ICONS_KEY, showHierarchyIcons); + #if UNITY_2017_2_OR_NEWER + SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode); + #else + SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(); + #endif + } + + EditorGUILayout.Separator(); + + EditorGUILayout.LabelField("Auto-Import Settings", EditorStyles.boldLabel); + + EditorGUI.BeginChangeCheck(); + defaultMix = EditorGUILayout.FloatField("Default Mix", defaultMix); + if (EditorGUI.EndChangeCheck()) + EditorPrefs.SetFloat(DEFAULT_MIX_KEY, defaultMix); + + EditorGUI.BeginChangeCheck(); + defaultScale = EditorGUILayout.FloatField("Default SkeletonData Scale", defaultScale); + if (EditorGUI.EndChangeCheck()) + EditorPrefs.SetFloat(DEFAULT_SCALE_KEY, defaultScale); + + EditorGUI.BeginChangeCheck(); + var shader = (EditorGUILayout.ObjectField("Default Shader", Shader.Find(defaultShader), typeof(Shader), false) as Shader); + defaultShader = shader != null ? shader.name : DEFAULT_DEFAULT_SHADER; + if (EditorGUI.EndChangeCheck()) + EditorPrefs.SetString(DEFAULT_SHADER_KEY, defaultShader); + + EditorGUI.BeginChangeCheck(); + setTextureImporterSettings = EditorGUILayout.Toggle(new GUIContent("Apply Atlas Texture Settings", "Apply the recommended settings for Texture Importers."), showHierarchyIcons); + if (EditorGUI.EndChangeCheck()) { + EditorPrefs.SetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, showHierarchyIcons); + } + + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Editor Instantiation", EditorStyles.boldLabel); + EditorGUI.BeginChangeCheck(); + defaultZSpacing = EditorGUILayout.Slider("Default Slot Z-Spacing", defaultZSpacing, -0.1f, 0f); + if (EditorGUI.EndChangeCheck()) + EditorPrefs.SetFloat(DEFAULT_ZSPACING_KEY, defaultZSpacing); + + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel); + EditorGUI.BeginChangeCheck(); + SpineHandles.handleScale = EditorGUILayout.Slider("Editor Bone Scale", SpineHandles.handleScale, 0.01f, 2f); + SpineHandles.handleScale = Mathf.Max(0.01f, SpineHandles.handleScale); + if (EditorGUI.EndChangeCheck()) { + EditorPrefs.SetFloat(SCENE_ICONS_SCALE_KEY, SpineHandles.handleScale); + SceneView.RepaintAll(); + } + + + GUILayout.Space(20); + EditorGUILayout.LabelField("3rd Party Settings", EditorStyles.boldLabel); + using (new GUILayout.HorizontalScope()) { + EditorGUILayout.PrefixLabel("Define TK2D"); + if (GUILayout.Button("Enable", GUILayout.Width(64))) + SpineTK2DEditorUtility.EnableTK2D(); + if (GUILayout.Button("Disable", GUILayout.Width(64))) + SpineTK2DEditorUtility.DisableTK2D(); + } + } + #endregion + + #region Drag and Drop Instantiation + public delegate Component InstantiateDelegate (SkeletonDataAsset skeletonDataAsset); + + public struct SpawnMenuData { + public Vector3 spawnPoint; + public SkeletonDataAsset skeletonDataAsset; + public InstantiateDelegate instantiateDelegate; + public bool isUI; + } + + public class SkeletonComponentSpawnType { + public string menuLabel; + public InstantiateDelegate instantiateDelegate; + public bool isUI; + } + + internal static readonly List additionalSpawnTypes = new List(); + + static void SceneViewDragAndDrop (SceneView sceneview) { + var current = UnityEngine.Event.current; + var references = DragAndDrop.objectReferences; + if (current.type == EventType.Layout) return; + + // Allow drag and drop of one SkeletonDataAsset. + if (references.Length == 1) { + var skeletonDataAsset = references[0] as SkeletonDataAsset; + if (skeletonDataAsset != null) { + var mousePos = current.mousePosition; + + 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.skeletonDataAssetIcon)); + Handles.EndGUI(); + + 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); + ShowInstantiateContextMenu(skeletonDataAsset, spawnPoint); + DragAndDrop.AcceptDrag(); + current.Use(); + } + } + } + } + } + + public static void ShowInstantiateContextMenu (SkeletonDataAsset skeletonDataAsset, Vector3 spawnPoint) { + var menu = new GenericMenu(); + + // SkeletonAnimation + menu.AddItem(new GUIContent("SkeletonAnimation"), false, HandleSkeletonComponentDrop, new SpawnMenuData { + skeletonDataAsset = skeletonDataAsset, + spawnPoint = spawnPoint, + instantiateDelegate = (data) => InstantiateSkeletonAnimation(data), + isUI = false + }); + + // SkeletonGraphic + var skeletonGraphicInspectorType = System.Type.GetType("Spine.Unity.Editor.SkeletonGraphicInspector"); + if (skeletonGraphicInspectorType != null) { + var graphicInstantiateDelegate = skeletonGraphicInspectorType.GetMethod("SpawnSkeletonGraphicFromDrop", BindingFlags.Static | BindingFlags.Public); + if (graphicInstantiateDelegate != null) + menu.AddItem(new GUIContent("SkeletonGraphic (UI)"), false, HandleSkeletonComponentDrop, new SpawnMenuData { + skeletonDataAsset = skeletonDataAsset, + spawnPoint = spawnPoint, + instantiateDelegate = System.Delegate.CreateDelegate(typeof(InstantiateDelegate), graphicInstantiateDelegate) as InstantiateDelegate, + isUI = true + }); + } + + #if SPINE_SKELETONANIMATOR + menu.AddSeparator(""); + // SkeletonAnimator + menu.AddItem(new GUIContent("SkeletonAnimator"), false, HandleSkeletonComponentDrop, new SpawnMenuData { + skeletonDataAsset = skeletonDataAsset, + spawnPoint = spawnPoint, + instantiateDelegate = (data) => InstantiateSkeletonAnimator(data) + }); + #endif + + menu.ShowAsContext(); + } + + public static void HandleSkeletonComponentDrop (object spawnMenuData) { + var data = (SpawnMenuData)spawnMenuData; + + 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; + + Component newSkeletonComponent = data.instantiateDelegate.Invoke(data.skeletonDataAsset); + GameObject newGameObject = newSkeletonComponent.gameObject; + Transform newTransform = newGameObject.transform; + + var activeGameObject = Selection.activeGameObject; + if (isUI && activeGameObject != null) + newTransform.SetParent(activeGameObject.transform, false); + + newTransform.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; + //EditorGUIUtility.PingObject(newGameObject); // Doesn't work when setting activeGameObject. + Undo.RegisterCreatedObjectUndo(newGameObject, "Create Spine GameObject"); + } + + /// + /// Rounds off vector components to a number of decimal digits. + /// + public static Vector3 RoundVector (Vector3 vector, int digits) { + vector.x = (float)System.Math.Round(vector.x, digits); + vector.y = (float)System.Math.Round(vector.y, digits); + vector.z = (float)System.Math.Round(vector.z, digits); + return vector; + } + + /// + /// 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 = plane.Raycast(ray, out distance); + return ray.GetPoint(distance); + } + #endregion + + #region Hierarchy + static class SpineEditorHierarchyHandler { + static Dictionary skeletonRendererTable = new Dictionary(); + static Dictionary skeletonUtilityBoneTable = new Dictionary(); + static Dictionary boundingBoxFollowerTable = new Dictionary(); + + #if UNITY_2017_2_OR_NEWER + internal static void HierarchyIconsOnPlaymodeStateChanged (PlayModeStateChange stateChange) { + #else + internal static void HierarchyIconsOnPlaymodeStateChanged () { + #endif + skeletonRendererTable.Clear(); + skeletonUtilityBoneTable.Clear(); + boundingBoxFollowerTable.Clear(); + + #if UNITY_2018 + EditorApplication.hierarchyChanged -= HierarchyIconsOnChanged; + #else + EditorApplication.hierarchyWindowChanged -= HierarchyIconsOnChanged; + #endif + EditorApplication.hierarchyWindowItemOnGUI -= HierarchyIconsOnGUI; + + if (!Application.isPlaying && showHierarchyIcons) { + #if UNITY_2018 + EditorApplication.hierarchyChanged += HierarchyIconsOnChanged; + #else + EditorApplication.hierarchyWindowChanged += HierarchyIconsOnChanged; + #endif + EditorApplication.hierarchyWindowItemOnGUI += HierarchyIconsOnGUI; + HierarchyIconsOnChanged(); + } + } + + internal static void HierarchyIconsOnChanged () { + skeletonRendererTable.Clear(); + skeletonUtilityBoneTable.Clear(); + boundingBoxFollowerTable.Clear(); + + SkeletonRenderer[] arr = Object.FindObjectsOfType(); + foreach (SkeletonRenderer r in arr) + skeletonRendererTable[r.gameObject.GetInstanceID()] = r.gameObject; + + SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType(); + foreach (SkeletonUtilityBone b in boneArr) + skeletonUtilityBoneTable[b.gameObject.GetInstanceID()] = b; + + BoundingBoxFollower[] bbfArr = Object.FindObjectsOfType(); + foreach (BoundingBoxFollower bbf in bbfArr) + boundingBoxFollowerTable[bbf.gameObject.GetInstanceID()] = bbf; + } + + internal static void HierarchyIconsOnGUI (int instanceId, Rect selectionRect) { + Rect r = new Rect(selectionRect); + if (skeletonRendererTable.ContainsKey(instanceId)) { + r.x = r.width - 15; + r.width = 15; + GUI.Label(r, Icons.spine); + } else if (skeletonUtilityBoneTable.ContainsKey(instanceId)) { + r.x -= 26; + if (skeletonUtilityBoneTable[instanceId] != null) { + if (skeletonUtilityBoneTable[instanceId].transform.childCount == 0) + r.x += 13; + r.y += 2; + r.width = 13; + r.height = 13; + if (skeletonUtilityBoneTable[instanceId].mode == SkeletonUtilityBone.Mode.Follow) + GUI.DrawTexture(r, Icons.bone); + else + GUI.DrawTexture(r, Icons.poseBones); + } + } else if (boundingBoxFollowerTable.ContainsKey(instanceId)) { + r.x -= 26; + if (boundingBoxFollowerTable[instanceId] != null) { + if (boundingBoxFollowerTable[instanceId].transform.childCount == 0) + r.x += 13; + r.y += 2; + r.width = 13; + r.height = 13; + GUI.DrawTexture(r, Icons.boundingBox); + } + } + } + + internal static void HierarchyDragAndDrop (int instanceId, Rect selectionRect) { + // HACK: Uses EditorApplication.hierarchyWindowItemOnGUI. + // Only works when there is at least one item in the scene. + var current = UnityEngine.Event.current; + var eventType = current.type; + bool isDraggingEvent = eventType == EventType.DragUpdated; + bool isDropEvent = eventType == EventType.DragPerform; + if (isDraggingEvent || isDropEvent) { + var mouseOverWindow = EditorWindow.mouseOverWindow; + if (mouseOverWindow != null) { + + // One, existing, valid SkeletonDataAsset + var references = DragAndDrop.objectReferences; + if (references.Length == 1) { + var skeletonDataAsset = references[0] as SkeletonDataAsset; + if (skeletonDataAsset != null && skeletonDataAsset.GetSkeletonData(true) != null) { + + // Allow drag-and-dropping anywhere in the Hierarchy Window. + // HACK: string-compare because we can't get its type via reflection. + const string HierarchyWindow = "UnityEditor.SceneHierarchyWindow"; + if (HierarchyWindow.Equals(mouseOverWindow.GetType().ToString(), System.StringComparison.Ordinal)) { + if (isDraggingEvent) { + DragAndDrop.visualMode = DragAndDropVisualMode.Copy; + current.Use(); + } else if (isDropEvent) { + ShowInstantiateContextMenu(skeletonDataAsset, Vector3.zero); + DragAndDrop.AcceptDrag(); + current.Use(); + return; + } + } + + } + } + } + } + + } + } + #endregion + + #region Auto-Import Entry Point + static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) { + if (imported.Length == 0) + return; + + // In case user used "Assets -> Reimport All", during the import process, + // asset database is not initialized until some point. During that period, + // all attempts to load any assets using API (i.e. AssetDatabase.LoadAssetAtPath) + // will return null, and as result, assets won't be loaded even if they actually exists, + // which may lead to numerous importing errors. + // This situation also happens if Library folder is deleted from the project, which is a pretty + // common case, since when using version control systems, the Library folder must be excluded. + // + // So to avoid this, in case asset database is not available, we delay loading the assets + // until next time. + // + // Unity *always* reimports some internal assets after the process is done, so this method + // is always called once again in a state when asset database is available. + // + // Checking whether AssetDatabase is initialized is done by attempting to load + // a known "marker" asset that should always be available. Failing to load this asset + // means that AssetDatabase is not initialized. + assetsImportedInWrongState.UnionWith(imported); + if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) { + string[] combinedAssets = assetsImportedInWrongState.ToArray(); + assetsImportedInWrongState.Clear(); + ImportSpineContent(combinedAssets); + } + } + + public static void ImportSpineContent (string[] imported, bool reimport = false) { + var atlasPaths = new List(); + var imagePaths = new List(); + var skeletonPaths = new List(); + + foreach (string str in imported) { + string extension = Path.GetExtension(str).ToLower(); + switch (extension) { + case ".txt": + if (str.EndsWith(".atlas.txt", System.StringComparison.Ordinal)) + atlasPaths.Add(str); + break; + case ".png": + case ".jpg": + imagePaths.Add(str); + break; + case ".json": + var jsonAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(str, typeof(TextAsset)); + if (jsonAsset != null && SkeletonDataFileValidator.IsSpineData(jsonAsset)) + skeletonPaths.Add(str); + break; + case ".bytes": + if (str.ToLower().EndsWith(".skel.bytes", System.StringComparison.Ordinal)) { + if (SkeletonDataFileValidator.IsSpineData((TextAsset)AssetDatabase.LoadAssetAtPath(str, typeof(TextAsset)))) + skeletonPaths.Add(str); + } + break; + } + } + + // Import atlases first. + var atlases = new List(); + foreach (string ap in atlasPaths) { + TextAsset atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(ap, typeof(TextAsset)); + AtlasAsset atlas = IngestSpineAtlas(atlasText); + atlases.Add(atlas); + } + + // Import skeletons and match them with atlases. + bool abortSkeletonImport = false; + foreach (string sp in skeletonPaths) { + if (!reimport && SkeletonDataFileValidator.CheckForValidSkeletonData(sp)) { + ReloadSkeletonData(sp); + continue; + } + + string dir = Path.GetDirectoryName(sp); + + #if SPINE_TK2D + IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, null); + #else + var localAtlases = FindAtlasesAtPath(dir); + var requiredPaths = GetRequiredAtlasRegions(sp); + var atlasMatch = GetMatchingAtlas(requiredPaths, localAtlases); + if (atlasMatch != null || requiredPaths.Count == 0) { + IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, atlasMatch); + } else { + bool resolved = false; + while (!resolved) { + + string filename = Path.GetFileNameWithoutExtension(sp); + int result = EditorUtility.DisplayDialogComplex( + string.Format("AtlasAsset for \"{0}\"", filename), + string.Format("Could not automatically set the AtlasAsset for \"{0}\". You may set it manually.", filename), + "Choose AtlasAssets...", "Skip this", "Stop importing all" + ); + + switch (result) { + case -1: + //Debug.Log("Select Atlas"); + AtlasAsset selectedAtlas = GetAtlasDialog(Path.GetDirectoryName(sp)); + if (selectedAtlas != null) { + localAtlases.Clear(); + localAtlases.Add(selectedAtlas); + atlasMatch = GetMatchingAtlas(requiredPaths, localAtlases); + if (atlasMatch != null) { + resolved = true; + IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, atlasMatch); + } + } + break; + case 0: // Choose AtlasAssets... + var atlasList = MultiAtlasDialog(requiredPaths, Path.GetDirectoryName(sp), Path.GetFileNameWithoutExtension(sp)); + if (atlasList != null) + IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, atlasList.ToArray()); + + resolved = true; + break; + case 1: // Skip + Debug.Log("Skipped importing: " + Path.GetFileName(sp)); + resolved = true; + break; + case 2: // Stop importing all + abortSkeletonImport = true; + resolved = true; + break; + } + } + } + + if (abortSkeletonImport) + break; + #endif + } + // Any post processing of images + } + + static void ReloadSkeletonData (string skeletonJSONPath) { + string dir = Path.GetDirectoryName(skeletonJSONPath); + TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset)); + DirectoryInfo dirInfo = new DirectoryInfo(dir); + FileInfo[] files = dirInfo.GetFiles("*.asset"); + + foreach (var f in files) { + string localPath = dir + "/" + f.Name; + var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object)); + var skeletonDataAsset = obj as SkeletonDataAsset; + if (skeletonDataAsset != null) { + if (skeletonDataAsset.skeletonJSON == textAsset) { + if (Selection.activeObject == skeletonDataAsset) + Selection.activeObject = null; + + Debug.LogFormat("Changes to '{0}' detected. Clearing SkeletonDataAsset: {1}", skeletonJSONPath, localPath); + skeletonDataAsset.Clear(); + + string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skeletonDataAsset)); + string lastHash = EditorPrefs.GetString(guid + "_hash"); + + // For some weird reason sometimes Unity loses the internal Object pointer, + // and as a result, all comparisons with null returns true. + // But the C# wrapper is still alive, so we can "restore" the object + // by reloading it from its Instance ID. + AtlasAsset[] skeletonDataAtlasAssets = skeletonDataAsset.atlasAssets; + if (skeletonDataAtlasAssets != null) { + for (int i = 0; i < skeletonDataAtlasAssets.Length; i++) { + if (!ReferenceEquals(null, skeletonDataAtlasAssets[i]) && + skeletonDataAtlasAssets[i].Equals(null) && + skeletonDataAtlasAssets[i].GetInstanceID() != 0 + ) { + skeletonDataAtlasAssets[i] = EditorUtility.InstanceIDToObject(skeletonDataAtlasAssets[i].GetInstanceID()) as AtlasAsset; + } + } + } + + SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true); + string currentHash = skeletonData != null ? skeletonData.Hash : null; + + #if SPINE_SKELETONANIMATOR + if (currentHash == null || lastHash != currentHash) + UpdateMecanimClips(skeletonDataAsset); + #endif + + // if (currentHash == null || lastHash != currentHash) + // Do any upkeep on synchronized assets + + if (currentHash != null) + EditorPrefs.SetString(guid + "_hash", currentHash); + } + } + } + } + #endregion + + #region Match SkeletonData with Atlases + static readonly AttachmentType[] AtlasTypes = { AttachmentType.Region, AttachmentType.Linkedmesh, AttachmentType.Mesh }; + + static List MultiAtlasDialog (List requiredPaths, string initialDirectory, string filename = "") { + List atlasAssets = new List(); + bool resolved = false; + string lastAtlasPath = initialDirectory; + while (!resolved) { + + // Build dialog box message. + var missingRegions = new List(requiredPaths); + var dialogText = new StringBuilder(); + { + dialogText.AppendLine(string.Format("SkeletonDataAsset for \"{0}\"", filename)); + dialogText.AppendLine("has missing regions."); + dialogText.AppendLine(); + dialogText.AppendLine("Current Atlases:"); + + if (atlasAssets.Count == 0) + dialogText.AppendLine("\t--none--"); + + for (int i = 0; i < atlasAssets.Count; i++) + dialogText.AppendLine("\t" + atlasAssets[i].name); + + dialogText.AppendLine(); + dialogText.AppendLine("Missing Regions:"); + + foreach (var atlasAsset in atlasAssets) { + var atlas = atlasAsset.GetAtlas(); + for (int i = 0; i < missingRegions.Count; i++) { + if (atlas.FindRegion(missingRegions[i]) != null) { + missingRegions.RemoveAt(i); + i--; + } + } + } + + int n = missingRegions.Count; + if (n == 0) break; + + const int MaxListLength = 15; + for (int i = 0; (i < n && i < MaxListLength); i++) + dialogText.AppendLine("\t" + missingRegions[i]); + + if (n > MaxListLength) dialogText.AppendLine(string.Format("\t... {0} more...", n - MaxListLength)); + } + + // Show dialog box. + int result = EditorUtility.DisplayDialogComplex( + "SkeletonDataAsset has missing Atlas.", + dialogText.ToString(), + "Browse...", "Import anyway", "Cancel" + ); + + switch (result) { + case 0: // Browse... + AtlasAsset selectedAtlasAsset = GetAtlasDialog(lastAtlasPath); + if (selectedAtlasAsset != null) { + var atlas = selectedAtlasAsset.GetAtlas(); + bool hasValidRegion = false; + foreach (string str in missingRegions) { + if (atlas.FindRegion(str) != null) { + hasValidRegion = true; + break; + } + } + atlasAssets.Add(selectedAtlasAsset); + } + break; + case 1: // Import anyway + resolved = true; + break; + case 2: // Cancel + atlasAssets = null; + resolved = true; + break; + } + } + + return atlasAssets; + } + + static AtlasAsset GetAtlasDialog (string dirPath) { + string path = EditorUtility.OpenFilePanel("Select AtlasAsset...", dirPath, "asset"); + if (path == "") return null; // Canceled or closed by user. + + int subLen = Application.dataPath.Length - 6; + string assetRelativePath = path.Substring(subLen, path.Length - subLen).Replace("\\", "/"); + + Object obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAsset)); + + if (obj == null || obj.GetType() != typeof(AtlasAsset)) + return null; + + return (AtlasAsset)obj; + } + + static void AddRequiredAtlasRegionsFromBinary (string skeletonDataPath, List requiredPaths) { + SkeletonBinary binary = new SkeletonBinary(new AtlasRequirementLoader(requiredPaths)); + TextAsset data = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset)); + MemoryStream input = new MemoryStream(data.bytes); + binary.ReadSkeletonData(input); + binary = null; + } + + public static List GetRequiredAtlasRegions (string skeletonDataPath) { + List requiredPaths = new List(); + + if (skeletonDataPath.Contains(".skel")) { + AddRequiredAtlasRegionsFromBinary(skeletonDataPath, requiredPaths); + return requiredPaths; + } + + TextAsset spineJson = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonDataPath, typeof(TextAsset)); + + StringReader reader = new StringReader(spineJson.text); + var root = Json.Deserialize(reader) as Dictionary; + + if (!root.ContainsKey("skins")) + return requiredPaths; + + foreach (KeyValuePair entry in (Dictionary)root["skins"]) { + foreach (KeyValuePair slotEntry in (Dictionary)entry.Value) { + + foreach (KeyValuePair attachmentEntry in ((Dictionary)slotEntry.Value)) { + var data = ((Dictionary)attachmentEntry.Value); + + // Ignore non-atlas-requiring types. + if (data.ContainsKey("type")) { + AttachmentType attachmentType; + string typeString = (string)data["type"]; + try { + attachmentType = (AttachmentType)System.Enum.Parse(typeof(AttachmentType), typeString, true); + } catch (System.ArgumentException e) { + // For more info, visit: http://esotericsoftware.com/forum/Spine-editor-and-runtime-version-management-6534 + Debug.LogWarning(string.Format("Unidentified Attachment type: \"{0}\". Skeleton may have been exported from an incompatible Spine version.", typeString)); + throw e; + } + + if (!AtlasTypes.Contains(attachmentType)) + continue; + } + + if (data.ContainsKey("path")) + requiredPaths.Add((string)data["path"]); + else if (data.ContainsKey("name")) + requiredPaths.Add((string)data["name"]); + else + requiredPaths.Add(attachmentEntry.Key); + } + } + } + + return requiredPaths; + } + + static AtlasAsset GetMatchingAtlas (List requiredPaths, List atlasAssets) { + AtlasAsset atlasAssetMatch = null; + + foreach (AtlasAsset a in atlasAssets) { + Atlas atlas = a.GetAtlas(); + bool failed = false; + foreach (string regionPath in requiredPaths) { + if (atlas.FindRegion(regionPath) == null) { + failed = true; + break; + } + } + + if (!failed) { + atlasAssetMatch = a; + break; + } + } + + return atlasAssetMatch; + } + + public class AtlasRequirementLoader : AttachmentLoader { + List requirementList; + + public AtlasRequirementLoader (List requirementList) { + this.requirementList = requirementList; + } + + public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) { + requirementList.Add(path); + return new RegionAttachment(name); + } + + public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) { + requirementList.Add(path); + return new MeshAttachment(name); + } + + 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); + } + } + #endregion + + #region Import Atlases + static List FindAtlasesAtPath (string path) { + List arr = new List(); + DirectoryInfo dir = new DirectoryInfo(path); + FileInfo[] assetInfoArr = dir.GetFiles("*.asset"); + + int subLen = Application.dataPath.Length - 6; + foreach (var f in assetInfoArr) { + string assetRelativePath = f.FullName.Substring(subLen, f.FullName.Length - subLen).Replace("\\", "/"); + Object obj = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(AtlasAsset)); + if (obj != null) + arr.Add(obj as AtlasAsset); + } + + return arr; + } + + static AtlasAsset IngestSpineAtlas (TextAsset atlasText) { + if (atlasText == null) { + Debug.LogWarning("Atlas source cannot be null!"); + return null; + } + + string primaryName = Path.GetFileNameWithoutExtension(atlasText.name).Replace(".atlas", ""); + string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(atlasText)); + + string atlasPath = assetPath + "/" + primaryName + "_Atlas.asset"; + + AtlasAsset atlasAsset = (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset)); + + List vestigialMaterials = new List(); + + if (atlasAsset == null) + atlasAsset = AtlasAsset.CreateInstance(); + else { + foreach (Material m in atlasAsset.materials) + vestigialMaterials.Add(m); + } + + protectFromStackGarbageCollection.Add(atlasAsset); + atlasAsset.atlasFile = atlasText; + + //strip CR + string atlasStr = atlasText.text; + atlasStr = atlasStr.Replace("\r", ""); + + string[] atlasLines = atlasStr.Split('\n'); + List pageFiles = new List(); + for (int i = 0; i < atlasLines.Length - 1; i++) { + if (atlasLines[i].Trim().Length == 0) + pageFiles.Add(atlasLines[i + 1].Trim()); + } + + var populatingMaterials = new List(pageFiles.Count);//atlasAsset.materials = new Material[pageFiles.Count]; + + for (int i = 0; i < pageFiles.Count; i++) { + string texturePath = assetPath + "/" + pageFiles[i]; + Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)); + + if (setTextureImporterSettings) { + TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath); + if (texImporter == null) { + Debug.LogWarning(string.Format("{0} ::: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath)); + continue; + } + + texImporter.textureCompression = TextureImporterCompression.Uncompressed; + texImporter.alphaSource = TextureImporterAlphaSource.FromInput; + texImporter.mipmapEnabled = false; + texImporter.alphaIsTransparency = false; // Prevent the texture importer from applying bleed to the transparent parts for PMA. + texImporter.spriteImportMode = SpriteImportMode.None; + texImporter.maxTextureSize = 2048; + + EditorUtility.SetDirty(texImporter); + AssetDatabase.ImportAsset(texturePath); + AssetDatabase.SaveAssets(); + } + + string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]); + + //because this looks silly + if (pageName == primaryName && pageFiles.Count == 1) + pageName = "Material"; + + string materialPath = assetPath + "/" + primaryName + "_" + pageName + ".mat"; + Material mat = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)); + + if (mat == null) { + mat = new Material(Shader.Find(defaultShader)); + AssetDatabase.CreateAsset(mat, materialPath); + } else { + vestigialMaterials.Remove(mat); + } + + mat.mainTexture = texture; + EditorUtility.SetDirty(mat); + AssetDatabase.SaveAssets(); + + populatingMaterials.Add(mat); //atlasAsset.materials[i] = mat; + } + + atlasAsset.materials = populatingMaterials.ToArray(); + + for (int i = 0; i < vestigialMaterials.Count; i++) + AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(vestigialMaterials[i])); + + if (AssetDatabase.GetAssetPath(atlasAsset) == "") + AssetDatabase.CreateAsset(atlasAsset, atlasPath); + else + atlasAsset.Clear(); + + EditorUtility.SetDirty(atlasAsset); + AssetDatabase.SaveAssets(); + + if (pageFiles.Count != atlasAsset.materials.Length) + Debug.LogWarning(string.Format("{0} ::: Not all atlas pages were imported. If you rename your image files, please make sure you also edit the filenames specified in the atlas file.", atlasAsset.name)); + else + Debug.Log(string.Format("{0} ::: Imported with {1} material", atlasAsset.name, atlasAsset.materials.Length)); + + // Iterate regions and bake marked. + Atlas atlas = atlasAsset.GetAtlas(); + FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic); + List regions = (List)field.GetValue(atlas); + string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset); + string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath); + string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name); + + bool hasBakedRegions = false; + for (int i = 0; i < regions.Count; i++) { + AtlasRegion region = regions[i]; + string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeName(region.name) + ".prefab").Replace("\\", "/"); + GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject)); + if (prefab != null) { + BakeRegion(atlasAsset, region, false); + hasBakedRegions = true; + } + } + + if (hasBakedRegions) { + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + } + + protectFromStackGarbageCollection.Remove(atlasAsset); + return (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset)); + } + #endregion + + #region Bake Atlas Region + public static GameObject BakeRegion (AtlasAsset atlasAsset, AtlasRegion region, bool autoSave = true) { + Atlas atlas = atlasAsset.GetAtlas(); + string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset); + string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath); + string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name); + string bakedPrefabPath = Path.Combine(bakedDirPath, GetPathSafeName(region.name) + ".prefab").Replace("\\", "/"); + + GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject)); + GameObject root; + Mesh mesh; + bool isNewPrefab = false; + + if (!Directory.Exists(bakedDirPath)) + Directory.CreateDirectory(bakedDirPath); + + if (prefab == null) { + root = new GameObject("temp", typeof(MeshFilter), typeof(MeshRenderer)); + prefab = PrefabUtility.CreatePrefab(bakedPrefabPath, root); + isNewPrefab = true; + Object.DestroyImmediate(root); + } + + mesh = (Mesh)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(Mesh)); + + Material mat = null; + mesh = atlasAsset.GenerateMesh(region.name, mesh, out mat); + if (isNewPrefab) { + AssetDatabase.AddObjectToAsset(mesh, prefab); + prefab.GetComponent().sharedMesh = mesh; + } + + EditorUtility.SetDirty(mesh); + EditorUtility.SetDirty(prefab); + + if (autoSave) { + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + } + + prefab.GetComponent().sharedMaterial = mat; + + return prefab; + } + #endregion + + #region Import SkeletonData (json or binary) + public const string SkeletonDataSuffix = "_SkeletonData"; + static SkeletonDataAsset IngestSpineProject (TextAsset spineJson, params AtlasAsset[] atlasAssets) { + string primaryName = Path.GetFileNameWithoutExtension(spineJson.name); + string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson)); + string filePath = assetPath + "/" + primaryName + SkeletonDataSuffix + ".asset"; + + #if SPINE_TK2D + if (spineJson != null) { + SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset)); + if (skeletonDataAsset == null) { + skeletonDataAsset = SkeletonDataAsset.CreateInstance(); + skeletonDataAsset.skeletonJSON = spineJson; + skeletonDataAsset.fromAnimation = new string[0]; + skeletonDataAsset.toAnimation = new string[0]; + skeletonDataAsset.duration = new float[0]; + skeletonDataAsset.defaultMix = defaultMix; + skeletonDataAsset.scale = defaultScale; + + AssetDatabase.CreateAsset(skeletonDataAsset, filePath); + AssetDatabase.SaveAssets(); + } else { + skeletonDataAsset.Clear(); + skeletonDataAsset.GetSkeletonData(true); + } + + return skeletonDataAsset; + } else { + EditorUtility.DisplayDialog("Error!", "Tried to ingest null Spine data.", "OK"); + return null; + } + + #else + if (spineJson != null && atlasAssets != null) { + SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset)); + if (skeletonDataAsset == null) { + skeletonDataAsset = ScriptableObject.CreateInstance(); { + skeletonDataAsset.atlasAssets = atlasAssets; + skeletonDataAsset.skeletonJSON = spineJson; + skeletonDataAsset.defaultMix = defaultMix; + skeletonDataAsset.scale = defaultScale; + } + + AssetDatabase.CreateAsset(skeletonDataAsset, filePath); + AssetDatabase.SaveAssets(); + } else { + skeletonDataAsset.atlasAssets = atlasAssets; + skeletonDataAsset.Clear(); + skeletonDataAsset.GetSkeletonData(true); + } + + return skeletonDataAsset; + } else { + EditorUtility.DisplayDialog("Error!", "Must specify both Spine JSON and AtlasAsset array", "OK"); + return null; + } + #endif + } + #endregion + + #region SkeletonDataFileValidator + internal static class SkeletonDataFileValidator { + static int[][] compatibleBinaryVersions = { new[] { 3, 6, 0 }, new[] { 3, 5, 0 } }; + static int[][] compatibleJsonVersions = { new[] { 3, 6, 0 }, new[] { 3, 7, 0 }, new[] { 3, 5, 0 } }; + //static bool isFixVersionRequired = false; + + public static bool CheckForValidSkeletonData (string skeletonJSONPath) { + string dir = Path.GetDirectoryName(skeletonJSONPath); + TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset)); + DirectoryInfo dirInfo = new DirectoryInfo(dir); + FileInfo[] files = dirInfo.GetFiles("*.asset"); + + foreach (var path in files) { + string localPath = dir + "/" + path.Name; + var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object)); + var skeletonDataAsset = obj as SkeletonDataAsset; + if (skeletonDataAsset != null && skeletonDataAsset.skeletonJSON == textAsset) + return true; + } + + return false; + } + + public static bool IsSpineData (TextAsset asset) { + if (asset == null) + return false; + + bool isSpineData = false; + string rawVersion = null; + + int[][] compatibleVersions; + if (asset.name.Contains(".skel")) { + try { + rawVersion = SkeletonBinary.GetVersionString(new MemoryStream(asset.bytes)); + isSpineData = !(string.IsNullOrEmpty(rawVersion)); + compatibleVersions = compatibleBinaryVersions; + } catch (System.Exception e) { + Debug.LogErrorFormat("Failed to read '{0}'. It is likely not a binary Spine SkeletonData file.\n{1}", asset.name, e); + return false; + } + } else { + object obj = Json.Deserialize(new StringReader(asset.text)); + if (obj == null) { + Debug.LogErrorFormat("'{0}' is not valid JSON.", asset.name); + return false; + } + + var root = obj as Dictionary; + if (root == null) { + Debug.LogError("Parser returned an incorrect type."); + return false; + } + + isSpineData = root.ContainsKey("skeleton"); + if (isSpineData) { + var skeletonInfo = (Dictionary)root["skeleton"]; + object jv; + skeletonInfo.TryGetValue("spine", out jv); + rawVersion = jv as string; + } + + compatibleVersions = compatibleJsonVersions; + } + + // Version warning + if (isSpineData) { + string primaryRuntimeVersionDebugString = compatibleVersions[0][0] + "." + compatibleVersions[0][1]; + + if (string.IsNullOrEmpty(rawVersion)) { + Debug.LogWarningFormat("Skeleton '{0}' has no version information. It may be incompatible with your runtime version: spine-unity v{1}", asset.name, primaryRuntimeVersionDebugString); + } else { + string[] versionSplit = rawVersion.Split('.'); + bool match = false; + foreach (var version in compatibleVersions) { + bool primaryMatch = version[0] == int.Parse(versionSplit[0]); + bool secondaryMatch = version[1] == int.Parse(versionSplit[1]); + + // if (isFixVersionRequired) secondaryMatch &= version[2] <= int.Parse(jsonVersionSplit[2]); + + if (primaryMatch && secondaryMatch) { + match = true; + break; + } + } + + if (!match) + Debug.LogWarningFormat("Skeleton '{0}' (exported with Spine {1}) may be incompatible with your runtime version: spine-unity v{2}", asset.name, rawVersion, primaryRuntimeVersionDebugString); + } + } + + return isSpineData; + } + } + + #endregion + + #region SkeletonAnimation Menu + public static void IngestAdvancedRenderSettings (SkeletonRenderer skeletonRenderer) { + const string PMAShaderQuery = "Spine/Skeleton"; + const string TintBlackShaderQuery = "Tint Black"; + + if (skeletonRenderer == null) return; + var skeletonDataAsset = skeletonRenderer.skeletonDataAsset; + if (skeletonDataAsset == null) return; + + bool pmaVertexColors = false; + bool tintBlack = false; + foreach (AtlasAsset atlasAsset in skeletonDataAsset.atlasAssets) { + if (!pmaVertexColors) { + foreach (Material m in atlasAsset.materials) { + if (m.shader.name.Contains(PMAShaderQuery)) { + pmaVertexColors = true; + break; + } + } + } + + if (!tintBlack) { + foreach (Material m in atlasAsset.materials) { + if (m.shader.name.Contains(TintBlackShaderQuery)) { + tintBlack = true; + break; + } + } + } + } + + skeletonRenderer.pmaVertexColors = pmaVertexColors; + skeletonRenderer.tintBlack = tintBlack; + } + + public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, string skinName, bool destroyInvalid = true) { + var skeletonData = skeletonDataAsset.GetSkeletonData(true); + var skin = skeletonData != null ? skeletonData.FindSkin(skinName) : null; + return InstantiateSkeletonAnimation(skeletonDataAsset, skin, destroyInvalid); + } + + public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, Skin skin = null, bool destroyInvalid = true) { + SkeletonData data = skeletonDataAsset.GetSkeletonData(true); + + if (data == null) { + for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) { + string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]); + skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset)); + } + data = skeletonDataAsset.GetSkeletonData(false); + } + + if (data == null) { + Debug.LogWarning("InstantiateSkeletonAnimation tried to instantiate a skeleton from an invalid SkeletonDataAsset."); + return null; + } + + string spineGameObjectName = string.Format("Spine GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", "")); + GameObject go = new GameObject(spineGameObjectName, typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation)); + SkeletonAnimation newSkeletonAnimation = go.GetComponent(); + newSkeletonAnimation.skeletonDataAsset = skeletonDataAsset; + IngestAdvancedRenderSettings(newSkeletonAnimation); + + try { + newSkeletonAnimation.Initialize(false); + } catch (System.Exception e) { + if (destroyInvalid) { + Debug.LogWarning("Editor-instantiated SkeletonAnimation threw an Exception. Destroying GameObject to prevent orphaned GameObject."); + GameObject.DestroyImmediate(go); + } + throw e; + } + + // Set Defaults + bool noSkins = data.DefaultSkin == null && (data.Skins == null || data.Skins.Count == 0); // Support attachmentless/skinless SkeletonData. + skin = skin ?? data.DefaultSkin ?? (noSkins ? null : data.Skins.Items[0]); + if (skin != null) { + newSkeletonAnimation.initialSkinName = skin.Name; + newSkeletonAnimation.skeleton.SetSkin(skin); + } + + newSkeletonAnimation.zSpacing = defaultZSpacing; + + newSkeletonAnimation.skeleton.Update(0); + newSkeletonAnimation.state.Update(0); + newSkeletonAnimation.state.Apply(newSkeletonAnimation.skeleton); + newSkeletonAnimation.skeleton.UpdateWorldTransform(); + + return newSkeletonAnimation; + } + #endregion + + #region SkeletonAnimator + #if SPINE_SKELETONANIMATOR + static void UpdateMecanimClips (SkeletonDataAsset skeletonDataAsset) { + if (skeletonDataAsset.controller == null) + return; + + SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset); + } + + public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, string skinName) { + return InstantiateSkeletonAnimator(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName)); + } + + public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, Skin skin = null) { + string spineGameObjectName = string.Format("Spine Mecanim GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", "")); + GameObject go = new GameObject(spineGameObjectName, typeof(MeshFilter), typeof(MeshRenderer), typeof(Animator), typeof(SkeletonAnimator)); + + if (skeletonDataAsset.controller == null) { + SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset); + Debug.Log(string.Format("Mecanim controller was automatically generated and assigned for {0}", skeletonDataAsset.name)); + } + + go.GetComponent().runtimeAnimatorController = skeletonDataAsset.controller; + + SkeletonAnimator anim = go.GetComponent(); + anim.skeletonDataAsset = skeletonDataAsset; + IngestAdvancedRenderSettings(anim); + + SkeletonData data = skeletonDataAsset.GetSkeletonData(true); + if (data == null) { + for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) { + string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]); + skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset)); + } + data = skeletonDataAsset.GetSkeletonData(true); + } + + // Set defaults + skin = skin ?? data.DefaultSkin ?? data.Skins.Items[0]; + anim.zSpacing = defaultZSpacing; + + anim.Initialize(false); + anim.skeleton.SetSkin(skin); + anim.initialSkinName = skin.Name; + + anim.skeleton.Update(0); + anim.skeleton.UpdateWorldTransform(); + anim.LateUpdate(); + + return anim; + } +#endif + #endregion + + #region SpineTK2DEditorUtility + internal static class SpineTK2DEditorUtility { + const string SPINE_TK2D_DEFINE = "SPINE_TK2D"; + + static bool IsInvalidGroup (BuildTargetGroup group) { + int gi = (int)group; + return + gi == 15 || gi == 16 + || + group == BuildTargetGroup.Unknown; + } + + internal static void EnableTK2D () { + bool added = false; + foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) { + if (IsInvalidGroup(group)) + continue; + + string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group); + if (!defines.Contains(SPINE_TK2D_DEFINE)) { + added = true; + if (defines.EndsWith(";", System.StringComparison.Ordinal)) + defines = defines + SPINE_TK2D_DEFINE; + else + defines = defines + ";" + SPINE_TK2D_DEFINE; + + PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines); + } + } + + if (added) { + Debug.LogWarning("Setting Scripting Define Symbol " + SPINE_TK2D_DEFINE); + } else { + Debug.LogWarning("Already Set Scripting Define Symbol " + SPINE_TK2D_DEFINE); + } + } + + + internal static void DisableTK2D () { + bool removed = false; + foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) { + if (IsInvalidGroup(group)) + continue; + + string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group); + if (defines.Contains(SPINE_TK2D_DEFINE)) { + removed = true; + if (defines.Contains(SPINE_TK2D_DEFINE + ";")) + defines = defines.Replace(SPINE_TK2D_DEFINE + ";", ""); + else + defines = defines.Replace(SPINE_TK2D_DEFINE, ""); + + PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines); + } + } + + if (removed) { + Debug.LogWarning("Removing Scripting Define Symbol " + SPINE_TK2D_DEFINE); + } else { + Debug.LogWarning("Already Removed Scripting Define Symbol " + SPINE_TK2D_DEFINE); + } + } + } + #endregion + + public static string GetPathSafeName (string name) { + foreach (char c in System.IO.Path.GetInvalidFileNameChars()) { // Doesn't handle more obscure file name limitations. + name = name.Replace(c, '_'); + } + return name; + } + } + + public static class SpineHandles { + internal static float handleScale = 1f; + public static Color BoneColor { get { return new Color(0.8f, 0.8f, 0.8f, 0.4f); } } + public static Color PathColor { get { return new Color(254/255f, 127/255f, 0); } } + public static Color TransformContraintColor { get { return new Color(170/255f, 226/255f, 35/255f); } } + public static Color IkColor { get { return new Color(228/255f,90/255f,43/255f); } } + public static Color PointColor { get { return new Color(1f, 1f, 0f, 1f); } } + + static Vector3[] _boneMeshVerts = { + new Vector3(0, 0, 0), + new Vector3(0.1f, 0.1f, 0), + new Vector3(1, 0, 0), + new Vector3(0.1f, -0.1f, 0) + }; + static Mesh _boneMesh; + public static Mesh BoneMesh { + get { + if (_boneMesh == null) { + _boneMesh = new Mesh { + vertices = _boneMeshVerts, + uv = new Vector2[4], + triangles = new [] { 0, 1, 2, 2, 3, 0 } + }; + _boneMesh.RecalculateBounds(); + _boneMesh.RecalculateNormals(); + } + return _boneMesh; + } + } + + static Mesh _arrowheadMesh; + public static Mesh ArrowheadMesh { + get { + if (_arrowheadMesh == null) { + _arrowheadMesh = new Mesh { + vertices = new [] { + new Vector3(0, 0), + new Vector3(-0.1f, 0.05f), + new Vector3(-0.1f, -0.05f) + }, + uv = new Vector2[3], + triangles = new [] { 0, 1, 2 } + }; + _arrowheadMesh.RecalculateBounds(); + _arrowheadMesh.RecalculateNormals(); + } + return _arrowheadMesh; + } + } + + static Material _boneMaterial; + static Material BoneMaterial { + get { + if (_boneMaterial == null) { + _boneMaterial = new Material(Shader.Find("Hidden/Spine/Bones")); + _boneMaterial.SetColor("_Color", SpineHandles.BoneColor); + } + + return _boneMaterial; + } + } + public static Material GetBoneMaterial () { + BoneMaterial.SetColor("_Color", SpineHandles.BoneColor); + return BoneMaterial; + } + + public static Material GetBoneMaterial (Color color) { + BoneMaterial.SetColor("_Color", color); + return BoneMaterial; + } + + static Material _ikMaterial; + public static Material IKMaterial { + get { + if (_ikMaterial == null) { + _ikMaterial = new Material(Shader.Find("Hidden/Spine/Bones")); + _ikMaterial.SetColor("_Color", SpineHandles.IkColor); + } + return _ikMaterial; + } + } + + static GUIStyle _boneNameStyle; + public static GUIStyle BoneNameStyle { + get { + if (_boneNameStyle == null) { + _boneNameStyle = new GUIStyle(EditorStyles.whiteMiniLabel) { + alignment = TextAnchor.MiddleCenter, + stretchWidth = true, + padding = new RectOffset(0, 0, 0, 0), + contentOffset = new Vector2(-5f, 0f) + }; + } + return _boneNameStyle; + } + } + + static GUIStyle _pathNameStyle; + public static GUIStyle PathNameStyle { + get { + if (_pathNameStyle == null) { + _pathNameStyle = new GUIStyle(SpineHandles.BoneNameStyle); + _pathNameStyle.normal.textColor = SpineHandles.PathColor; + } + return _pathNameStyle; + } + } + + static GUIStyle _pointNameStyle; + public static GUIStyle PointNameStyle { + get { + if (_pointNameStyle == null) { + _pointNameStyle = new GUIStyle(SpineHandles.BoneNameStyle); + _pointNameStyle.normal.textColor = SpineHandles.PointColor; + } + return _pointNameStyle; + } + } + + public static void DrawBoneNames (Transform transform, Skeleton skeleton, float positionScale = 1f) { + GUIStyle style = BoneNameStyle; + foreach (Bone b in skeleton.Bones) { + var pos = new Vector3(b.WorldX * positionScale, b.WorldY * positionScale, 0) + (new Vector3(b.A, b.C) * (b.Data.Length * 0.5f)); + pos = transform.TransformPoint(pos); + Handles.Label(pos, b.Data.Name, style); + } + } + + public static void DrawBones (Transform transform, Skeleton skeleton, float positionScale = 1f) { + float boneScale = 1.8f; // Draw the root bone largest; + DrawCrosshairs2D(skeleton.Bones.Items[0].GetWorldPosition(transform), 0.08f, positionScale); + + foreach (Bone b in skeleton.Bones) { + DrawBone(transform, b, boneScale, positionScale); + boneScale = 1f; + } + } + + static Vector3[] _boneWireBuffer = new Vector3[5]; + static Vector3[] GetBoneWireBuffer (Matrix4x4 m) { + for (int i = 0, n = _boneMeshVerts.Length; i < n; i++) + _boneWireBuffer[i] = m.MultiplyPoint(_boneMeshVerts[i]); + + _boneWireBuffer[4] = _boneWireBuffer[0]; // closed polygon. + return _boneWireBuffer; + } + public static void DrawBoneWireframe (Transform transform, Bone b, Color color, float skeletonRenderScale = 1f) { + Handles.color = color; + var pos = new Vector3(b.WorldX * skeletonRenderScale, b.WorldY * skeletonRenderScale, 0); + float length = b.Data.Length; + + if (length > 0) { + Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); + Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale; + const float my = 1.5f; + scale.y *= (SpineHandles.handleScale + 1) * 0.5f; + scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale); + Handles.DrawPolyLine(GetBoneWireBuffer(transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale))); + var wp = transform.TransformPoint(pos); + DrawBoneCircle(wp, color, transform.forward, skeletonRenderScale); + } else { + var wp = transform.TransformPoint(pos); + DrawBoneCircle(wp, color, transform.forward, skeletonRenderScale); + } + } + + public static void DrawBone (Transform transform, Bone b, float boneScale, float skeletonRenderScale = 1f) { + var pos = new Vector3(b.WorldX * skeletonRenderScale, b.WorldY * skeletonRenderScale, 0); + float length = b.Data.Length; + if (length > 0) { + Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); + Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale; + const float my = 1.5f; + scale.y *= (SpineHandles.handleScale + 1f) * 0.5f; + scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale); + SpineHandles.GetBoneMaterial().SetPass(0); + Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale)); + } else { + var wp = transform.TransformPoint(pos); + DrawBoneCircle(wp, SpineHandles.BoneColor, transform.forward, boneScale * skeletonRenderScale); + } + } + + public static void DrawBone (Transform transform, Bone b, float boneScale, Color color, float skeletonRenderScale = 1f) { + var pos = new Vector3(b.WorldX * skeletonRenderScale, b.WorldY * skeletonRenderScale, 0); + float length = b.Data.Length; + if (length > 0) { + Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); + Vector3 scale = Vector3.one * length * b.WorldScaleX; + const float my = 1.5f; + scale.y *= (SpineHandles.handleScale + 1f) * 0.5f; + scale.y = Mathf.Clamp(scale.x, -my, my); + SpineHandles.GetBoneMaterial(color).SetPass(0); + Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale)); + } else { + var wp = transform.TransformPoint(pos); + DrawBoneCircle(wp, color, transform.forward, boneScale * skeletonRenderScale); + } + } + + public static void DrawPaths (Transform transform, Skeleton skeleton) { + foreach (Slot s in skeleton.DrawOrder) { + var p = s.Attachment as PathAttachment; + if (p != null) SpineHandles.DrawPath(s, p, transform, true); + } + } + + static float[] pathVertexBuffer; + public static void DrawPath (Slot s, PathAttachment p, Transform t, bool includeName) { + int worldVerticesLength = p.WorldVerticesLength; + + if (pathVertexBuffer == null || pathVertexBuffer.Length < worldVerticesLength) + pathVertexBuffer = new float[worldVerticesLength]; + + float[] pv = pathVertexBuffer; + p.ComputeWorldVertices(s, pv); + + var ocolor = Handles.color; + Handles.color = SpineHandles.PathColor; + + Matrix4x4 m = t.localToWorldMatrix; + const int step = 6; + int n = worldVerticesLength - step; + Vector3 p0, p1, p2, p3; + for (int i = 2; i < n; i += step) { + p0 = m.MultiplyPoint(new Vector3(pv[i], pv[i+1])); + p1 = m.MultiplyPoint(new Vector3(pv[i+2], pv[i+3])); + p2 = m.MultiplyPoint(new Vector3(pv[i+4], pv[i+5])); + p3 = m.MultiplyPoint(new Vector3(pv[i+6], pv[i+7])); + DrawCubicBezier(p0, p1, p2, p3); + } + + n += step; + if (p.Closed) { + p0 = m.MultiplyPoint(new Vector3(pv[n - 4], pv[n - 3])); + p1 = m.MultiplyPoint(new Vector3(pv[n - 2], pv[n - 1])); + p2 = m.MultiplyPoint(new Vector3(pv[0], pv[1])); + p3 = m.MultiplyPoint(new Vector3(pv[2], pv[3])); + DrawCubicBezier(p0, p1, p2, p3); + } + + const float endCapSize = 0.05f; + Vector3 firstPoint = m.MultiplyPoint(new Vector3(pv[2], pv[3])); + SpineHandles.DrawDot(firstPoint, endCapSize); + + //if (!p.Closed) SpineHandles.DrawDot(m.MultiplyPoint(new Vector3(pv[n - 4], pv[n - 3])), endCapSize); + if (includeName) Handles.Label(firstPoint + new Vector3(0,0.1f), p.Name, PathNameStyle); + + Handles.color = ocolor; + } + + public static void DrawDot (Vector3 position, float size) { + Handles.DotHandleCap(0, position, Quaternion.identity, size * HandleUtility.GetHandleSize(position), EventType.Ignore); //Handles.DotCap(0, position, Quaternion.identity, size * HandleUtility.GetHandleSize(position)); + } + + public static void DrawBoundingBoxes (Transform transform, Skeleton skeleton) { + foreach (var slot in skeleton.Slots) { + var bba = slot.Attachment as BoundingBoxAttachment; + if (bba != null) SpineHandles.DrawBoundingBox(slot, bba, transform); + } + } + + public static void DrawBoundingBox (Slot slot, BoundingBoxAttachment box, Transform t) { + if (box.Vertices.Length <= 2) return; // Handle cases where user creates a BoundingBoxAttachment but doesn't actually define it. + + var worldVerts = new float[box.WorldVerticesLength]; + box.ComputeWorldVertices(slot, worldVerts); + + Handles.color = Color.green; + Vector3 lastVert = Vector3.zero; + Vector3 vert = Vector3.zero; + Vector3 firstVert = t.TransformPoint(new Vector3(worldVerts[0], worldVerts[1], 0)); + for (int i = 0; i < worldVerts.Length; i += 2) { + vert.x = worldVerts[i]; + vert.y = worldVerts[i + 1]; + vert.z = 0; + + vert = t.TransformPoint(vert); + + if (i > 0) + Handles.DrawLine(lastVert, vert); + + lastVert = vert; + } + + Handles.DrawLine(lastVert, firstVert); + } + + public static void DrawPointAttachment (Bone bone, PointAttachment pointAttachment, Transform skeletonTransform) { + if (bone == null) return; + if (pointAttachment == null) return; + + Vector2 localPos; + pointAttachment.ComputeWorldPosition(bone, out localPos.x, out localPos.y); + float localRotation = pointAttachment.ComputeWorldRotation(bone); + Matrix4x4 m = Matrix4x4.TRS(localPos, Quaternion.Euler(0, 0, localRotation), Vector3.one) * Matrix4x4.TRS(Vector3.right * 0.25f, Quaternion.identity, Vector3.one); + + DrawBoneCircle(skeletonTransform.TransformPoint(localPos), SpineHandles.PointColor, Vector3.back, 1.3f); + DrawArrowhead(skeletonTransform.localToWorldMatrix * m); + } + + public static void DrawConstraints (Transform transform, Skeleton skeleton, float skeletonRenderScale = 1f) { + Vector3 targetPos; + Vector3 pos; + bool active; + Color handleColor; + const float Thickness = 4f; + Vector3 normal = transform.forward; + + // Transform Constraints + handleColor = SpineHandles.TransformContraintColor; + foreach (var tc in skeleton.TransformConstraints) { + var targetBone = tc.Target; + targetPos = targetBone.GetWorldPosition(transform, skeletonRenderScale); + + if (tc.TranslateMix > 0) { + if (tc.TranslateMix != 1f) { + Handles.color = handleColor; + foreach (var b in tc.Bones) { + pos = b.GetWorldPosition(transform, skeletonRenderScale); + Handles.DrawDottedLine(targetPos, pos, Thickness); + } + } + SpineHandles.DrawBoneCircle(targetPos, handleColor, normal, 1.3f * skeletonRenderScale); + Handles.color = handleColor; + SpineHandles.DrawCrosshairs(targetPos, 0.2f, targetBone.A, targetBone.B, targetBone.C, targetBone.D, transform, skeletonRenderScale); + } + } + + // IK Constraints + handleColor = SpineHandles.IkColor; + foreach (var ikc in skeleton.IkConstraints) { + Bone targetBone = ikc.Target; + targetPos = targetBone.GetWorldPosition(transform, skeletonRenderScale); + var bones = ikc.Bones; + active = ikc.Mix > 0; + if (active) { + pos = bones.Items[0].GetWorldPosition(transform, skeletonRenderScale); + switch (bones.Count) { + case 1: { + Handles.color = handleColor; + Handles.DrawLine(targetPos, pos); + SpineHandles.DrawBoneCircle(targetPos, handleColor, normal); + var m = bones.Items[0].GetMatrix4x4(); + m.m03 = targetBone.WorldX * skeletonRenderScale; + m.m13 = targetBone.WorldY * skeletonRenderScale; + SpineHandles.DrawArrowhead(transform.localToWorldMatrix * m); + break; + } + case 2: { + Bone childBone = bones.Items[1]; + Vector3 child = childBone.GetWorldPosition(transform, skeletonRenderScale); + Handles.color = handleColor; + Handles.DrawLine(child, pos); + Handles.DrawLine(targetPos, child); + SpineHandles.DrawBoneCircle(pos, handleColor, normal, 0.5f); + SpineHandles.DrawBoneCircle(child, handleColor, normal, 0.5f); + SpineHandles.DrawBoneCircle(targetPos, handleColor, normal); + var m = childBone.GetMatrix4x4(); + m.m03 = targetBone.WorldX * skeletonRenderScale; + m.m13 = targetBone.WorldY * skeletonRenderScale; + SpineHandles.DrawArrowhead(transform.localToWorldMatrix * m); + break; + } + } + } + //Handles.Label(targetPos, ikc.Data.Name, SpineHandles.BoneNameStyle); + } + + // Path Constraints + handleColor = SpineHandles.PathColor; + foreach (var pc in skeleton.PathConstraints) { + active = pc.TranslateMix > 0; + if (active) + foreach (var b in pc.Bones) + SpineHandles.DrawBoneCircle(b.GetWorldPosition(transform, skeletonRenderScale), handleColor, normal, 1f * skeletonRenderScale); + } + } + + static void DrawCrosshairs2D (Vector3 position, float scale, float skeletonRenderScale = 1f) { + scale *= SpineHandles.handleScale * skeletonRenderScale; + Handles.DrawLine(position + new Vector3(-scale, 0), position + new Vector3(scale, 0)); + Handles.DrawLine(position + new Vector3(0, -scale), position + new Vector3(0, scale)); + } + + static void DrawCrosshairs (Vector3 position, float scale, float a, float b, float c, float d, Transform transform, float skeletonRenderScale = 1f) { + scale *= SpineHandles.handleScale * skeletonRenderScale; + + var xOffset = (Vector3)(new Vector2(a, c).normalized * scale); + var yOffset = (Vector3)(new Vector2(b, d).normalized * scale); + xOffset = transform.TransformDirection(xOffset); + yOffset = transform.TransformDirection(yOffset); + + Handles.DrawLine(position + xOffset, position - xOffset); + Handles.DrawLine(position + yOffset, position - yOffset); + } + + static void DrawArrowhead2D (Vector3 pos, float localRotation, float scale = 1f) { + scale *= SpineHandles.handleScale; + + SpineHandles.IKMaterial.SetPass(0); + Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, Matrix4x4.TRS(pos, Quaternion.Euler(0, 0, localRotation), new Vector3(scale, scale, scale))); + } + + static void DrawArrowhead (Vector3 pos, Quaternion worldQuaternion) { + Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, pos, worldQuaternion, 0); + } + + static void DrawArrowhead (Matrix4x4 m) { + float s = SpineHandles.handleScale; + m.m00 *= s; + m.m01 *= s; + m.m02 *= s; + m.m10 *= s; + m.m11 *= s; + m.m12 *= s; + m.m20 *= s; + m.m21 *= s; + m.m22 *= s; + + SpineHandles.IKMaterial.SetPass(0); + Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, m); + } + + static void DrawBoneCircle (Vector3 pos, Color outlineColor, Vector3 normal, float scale = 1f) { + scale *= SpineHandles.handleScale; + + Color o = Handles.color; + Handles.color = outlineColor; + float firstScale = 0.08f * scale; + Handles.DrawSolidDisc(pos, normal, firstScale); + const float Thickness = 0.03f; + float secondScale = firstScale - (Thickness * SpineHandles.handleScale * scale); + + if (secondScale > 0f) { + Handles.color = new Color(0.3f, 0.3f, 0.3f, 0.5f); + Handles.DrawSolidDisc(pos, normal, secondScale); + } + + Handles.color = o; + } + + internal static void DrawCubicBezier (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) { + Handles.DrawBezier(p0, p3, p1, p2, Handles.color, Texture2D.whiteTexture, 2f); + // const float dotSize = 0.01f; + // Quaternion q = Quaternion.identity; + // Handles.DotCap(0, p0, q, dotSize); + // Handles.DotCap(0, p1, q, dotSize); + // Handles.DotCap(0, p2, q, dotSize); + // Handles.DotCap(0, p3, q, dotSize); + // Handles.DrawLine(p0, p1); + // Handles.DrawLine(p3, p2); + } + } + +} diff --git a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/SpineInspectorUtility.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineInspectorUtility.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Editor/SpineInspectorUtility.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineInspectorUtility.cs index 13d41b681..4dee79d9f 100644 --- a/spine-unity/Assets/spine-unity/Editor/SpineInspectorUtility.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineInspectorUtility.cs @@ -1,345 +1,345 @@ -/****************************************************************************** - * 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 UnityEngine; -using UnityEditor; -using System.Collections.Generic; -using System.Reflection; - -namespace Spine.Unity.Editor { - public static class SpineInspectorUtility { - - public static string Pluralize (int n, string singular, string plural) { - return n + " " + (n == 1 ? singular : plural); - } - - public static string PluralThenS (int n) { - return n == 1 ? "" : "s"; - } - - public static string EmDash { - get { return "\u2014"; } - } - - static GUIContent tempContent; - internal static GUIContent TempContent (string text, Texture2D image = null, string tooltip = null) { - if (tempContent == null) tempContent = new GUIContent(); - tempContent.text = text; - tempContent.image = image; - tempContent.tooltip = tooltip; - return tempContent; - } - - public static void PropertyFieldWideLabel (SerializedProperty property, GUIContent label = null, float minimumLabelWidth = 150) { - EditorGUIUtility.labelWidth = minimumLabelWidth; - EditorGUILayout.PropertyField(property, label ?? TempContent(property.displayName, null, property.tooltip)); - EditorGUIUtility.labelWidth = 0; // Resets to default - } - - public static void PropertyFieldFitLabel (SerializedProperty property, GUIContent label = null, float extraSpace = 5f) { - label = label ?? TempContent(property.displayName, null, property.tooltip); - float width = GUI.skin.label.CalcSize(TempContent(label.text)).x + extraSpace; - if (label.image != null) - width += EditorGUIUtility.singleLineHeight; - PropertyFieldWideLabel(property, label, width); - } - - public static bool UndoRedoPerformed (UnityEngine.Event current) { - return current.type == EventType.ValidateCommand && current.commandName == "UndoRedoPerformed"; - } - - public static Texture2D UnityIcon() { - return EditorGUIUtility.ObjectContent(null, typeof(T)).image as Texture2D; - } - - public static Texture2D UnityIcon(System.Type type) { - return EditorGUIUtility.ObjectContent(null, type).image as Texture2D; - } - - #region SerializedProperty Helpers - public static SerializedProperty FindBaseOrSiblingProperty (this SerializedProperty property, string propertyName) { - if (string.IsNullOrEmpty(propertyName)) return null; - - SerializedProperty relativeProperty = property.serializedObject.FindProperty(propertyName); // baseProperty - - // If base property is not found, look for the sibling property. - if (relativeProperty == null) { - string propertyPath = property.propertyPath; - int localPathLength = property.name.Length; - - string newPropertyPath = propertyPath.Remove(propertyPath.Length - localPathLength, localPathLength) + propertyName; - relativeProperty = property.serializedObject.FindProperty(newPropertyPath); - - // If a direct sibling property was not found, try to find the sibling of the array. - if (relativeProperty == null && property.isArray) { - int propertyPathLength = propertyPath.Length; - - int dotCount = 0; - const int SiblingOfListDotCount = 3; - for (int i = 1; i < propertyPathLength; i++) { - if (propertyPath[propertyPathLength - i] == '.') { - dotCount++; - if (dotCount >= SiblingOfListDotCount) { - localPathLength = i - 1; - break; - } - } - } - - newPropertyPath = propertyPath.Remove(propertyPath.Length - localPathLength, localPathLength) + propertyName; - relativeProperty = property.serializedObject.FindProperty(newPropertyPath); - } - } - - return relativeProperty; - } - #endregion - - #region Layout Scopes - static GUIStyle grayMiniLabel; - public static GUIStyle GrayMiniLabel { - get { - if (grayMiniLabel == null) { - grayMiniLabel = new GUIStyle(EditorStyles.centeredGreyMiniLabel); - grayMiniLabel.alignment = TextAnchor.UpperLeft; - } - return grayMiniLabel; - } - } - - public class LabelWidthScope : System.IDisposable { - public LabelWidthScope (float minimumLabelWidth = 190f) { - EditorGUIUtility.labelWidth = minimumLabelWidth; - } - - public void Dispose () { - EditorGUIUtility.labelWidth = 0f; - } - } - - public class IndentScope : System.IDisposable { - public IndentScope () { EditorGUI.indentLevel++; } - public void Dispose () { EditorGUI.indentLevel--; } - } - - public class BoxScope : System.IDisposable { - readonly bool indent; - - static GUIStyle boxScopeStyle; - public static GUIStyle BoxScopeStyle { - get { - if (boxScopeStyle == null) { - boxScopeStyle = new GUIStyle(EditorStyles.helpBox); - RectOffset p = boxScopeStyle.padding; // RectOffset is a class - p.right += 6; - p.top += 1; - p.left += 3; - } - - return boxScopeStyle; - } - } - - public BoxScope (bool indent = true) { - this.indent = indent; - EditorGUILayout.BeginVertical(BoxScopeStyle); - if (indent) EditorGUI.indentLevel++; - } - - public void Dispose () { - if (indent) EditorGUI.indentLevel--; - EditorGUILayout.EndVertical(); - } - } - #endregion - - #region Button - const float CenterButtonMaxWidth = 270f; - const float CenterButtonHeight = 35f; - static GUIStyle spineButtonStyle; - static GUIStyle SpineButtonStyle { - get { - if (spineButtonStyle == null) { - spineButtonStyle = new GUIStyle(GUI.skin.button); - spineButtonStyle.name = "Spine Button"; - spineButtonStyle.padding = new RectOffset(10, 10, 10, 10); - } - return spineButtonStyle; - } - } - - 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(maxWidth), GUILayout.Height(CenterButtonHeight)); - EditorGUILayout.Space(); - } - EditorGUILayout.Space(); - return clicked; - } else { - return GUILayout.Button(label, GUILayout.MaxWidth(CenterButtonMaxWidth), GUILayout.Height(CenterButtonHeight)); - } - } - - 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(maxWidth), GUILayout.Height(CenterButtonHeight)); - EditorGUILayout.Space(); - } - EditorGUILayout.Space(); - return clicked; - } else { - return GUILayout.Button(content, GUILayout.MaxWidth(CenterButtonMaxWidth), GUILayout.Height(CenterButtonHeight)); - } - } - - 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(maxWidth), GUILayout.Height(height)); - EditorGUILayout.Space(); - } - EditorGUILayout.Space(); - return clicked; - } else { - return GUILayout.Button(content, GUILayout.MaxWidth(maxWidth), GUILayout.Height(height)); - } - } - #endregion - - #region Multi-Editing Helpers - public static bool TargetsUseSameData (SerializedObject so) { - if (so.isEditingMultipleObjects) { - int n = so.targetObjects.Length; - var first = so.targetObjects[0] as IHasSkeletonDataAsset; - for (int i = 1; i < n; i++) { - var sr = so.targetObjects[i] as IHasSkeletonDataAsset; - if (sr != null && sr.SkeletonDataAsset != first.SkeletonDataAsset) - return false; - } - } - return true; - } - - public static SerializedObject GetRenderersSerializedObject (SerializedObject serializedObject) { - if (serializedObject.isEditingMultipleObjects) { - var renderers = new List(); - foreach (var o in serializedObject.targetObjects) { - var component = o as Component; - if (component != null) { - var renderer = component.GetComponent(); - if (renderer != null) - renderers.Add(renderer); - } - } - return new SerializedObject(renderers.ToArray()); - } else { - var component = serializedObject.targetObject as Component; - if (component != null) { - var renderer = component.GetComponent(); - if (renderer != null) - return new SerializedObject(renderer); - } - } - - return null; - } - #endregion - - #region Sorting Layer Field Helpers - static readonly GUIContent SortingLayerLabel = new GUIContent("Sorting Layer", "MeshRenderer.sortingLayerID"); - static readonly GUIContent OrderInLayerLabel = new GUIContent("Order in Layer", "MeshRenderer.sortingOrder"); - - static MethodInfo m_SortingLayerFieldMethod; - static MethodInfo SortingLayerFieldMethod { - get { - if (m_SortingLayerFieldMethod == null) - m_SortingLayerFieldMethod = typeof(EditorGUILayout).GetMethod("SortingLayerField", BindingFlags.Static | BindingFlags.NonPublic, null, new [] { typeof(GUIContent), typeof(SerializedProperty), typeof(GUIStyle) }, null); - - return m_SortingLayerFieldMethod; - } - } - - public struct SerializedSortingProperties { - public SerializedObject renderer; - public SerializedProperty sortingLayerID; - public SerializedProperty sortingOrder; - - public SerializedSortingProperties (Renderer r) : this(new SerializedObject(r)) {} - public SerializedSortingProperties (Object[] renderers) : this(new SerializedObject(renderers)) {} - - /// - /// Initializes a new instance of the - /// struct. - /// - /// SerializedObject of the renderer. Use - /// to easily generate this. - public SerializedSortingProperties (SerializedObject rendererSerializedObject) { - renderer = rendererSerializedObject; - sortingLayerID = renderer.FindProperty("m_SortingLayerID"); - sortingOrder = renderer.FindProperty("m_SortingOrder"); - } - - public void ApplyModifiedProperties () { - renderer.ApplyModifiedProperties(); - - // SetDirty - if (renderer.isEditingMultipleObjects) - foreach (var o in renderer.targetObjects) - EditorUtility.SetDirty(o); - else - EditorUtility.SetDirty(renderer.targetObject); - } - } - - public static void SortingPropertyFields (SerializedSortingProperties prop, bool applyModifiedProperties) { - if (applyModifiedProperties) - EditorGUI.BeginChangeCheck(); - - if (SpineInspectorUtility.SortingLayerFieldMethod != null && prop.sortingLayerID != null) - SpineInspectorUtility.SortingLayerFieldMethod.Invoke(null, new object[] { SortingLayerLabel, prop.sortingLayerID, EditorStyles.popup } ); - else - EditorGUILayout.PropertyField(prop.sortingLayerID); - - EditorGUILayout.PropertyField(prop.sortingOrder, OrderInLayerLabel); - - if (applyModifiedProperties && EditorGUI.EndChangeCheck()) - prop.ApplyModifiedProperties(); - } - #endregion - } -} +/****************************************************************************** + * 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 UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.Reflection; + +namespace Spine.Unity.Editor { + public static class SpineInspectorUtility { + + public static string Pluralize (int n, string singular, string plural) { + return n + " " + (n == 1 ? singular : plural); + } + + public static string PluralThenS (int n) { + return n == 1 ? "" : "s"; + } + + public static string EmDash { + get { return "\u2014"; } + } + + static GUIContent tempContent; + internal static GUIContent TempContent (string text, Texture2D image = null, string tooltip = null) { + if (tempContent == null) tempContent = new GUIContent(); + tempContent.text = text; + tempContent.image = image; + tempContent.tooltip = tooltip; + return tempContent; + } + + public static void PropertyFieldWideLabel (SerializedProperty property, GUIContent label = null, float minimumLabelWidth = 150) { + EditorGUIUtility.labelWidth = minimumLabelWidth; + EditorGUILayout.PropertyField(property, label ?? TempContent(property.displayName, null, property.tooltip)); + EditorGUIUtility.labelWidth = 0; // Resets to default + } + + public static void PropertyFieldFitLabel (SerializedProperty property, GUIContent label = null, float extraSpace = 5f) { + label = label ?? TempContent(property.displayName, null, property.tooltip); + float width = GUI.skin.label.CalcSize(TempContent(label.text)).x + extraSpace; + if (label.image != null) + width += EditorGUIUtility.singleLineHeight; + PropertyFieldWideLabel(property, label, width); + } + + public static bool UndoRedoPerformed (UnityEngine.Event current) { + return current.type == EventType.ValidateCommand && current.commandName == "UndoRedoPerformed"; + } + + public static Texture2D UnityIcon() { + return EditorGUIUtility.ObjectContent(null, typeof(T)).image as Texture2D; + } + + public static Texture2D UnityIcon(System.Type type) { + return EditorGUIUtility.ObjectContent(null, type).image as Texture2D; + } + + #region SerializedProperty Helpers + public static SerializedProperty FindBaseOrSiblingProperty (this SerializedProperty property, string propertyName) { + if (string.IsNullOrEmpty(propertyName)) return null; + + SerializedProperty relativeProperty = property.serializedObject.FindProperty(propertyName); // baseProperty + + // If base property is not found, look for the sibling property. + if (relativeProperty == null) { + string propertyPath = property.propertyPath; + int localPathLength = property.name.Length; + + string newPropertyPath = propertyPath.Remove(propertyPath.Length - localPathLength, localPathLength) + propertyName; + relativeProperty = property.serializedObject.FindProperty(newPropertyPath); + + // If a direct sibling property was not found, try to find the sibling of the array. + if (relativeProperty == null && property.isArray) { + int propertyPathLength = propertyPath.Length; + + int dotCount = 0; + const int SiblingOfListDotCount = 3; + for (int i = 1; i < propertyPathLength; i++) { + if (propertyPath[propertyPathLength - i] == '.') { + dotCount++; + if (dotCount >= SiblingOfListDotCount) { + localPathLength = i - 1; + break; + } + } + } + + newPropertyPath = propertyPath.Remove(propertyPath.Length - localPathLength, localPathLength) + propertyName; + relativeProperty = property.serializedObject.FindProperty(newPropertyPath); + } + } + + return relativeProperty; + } + #endregion + + #region Layout Scopes + static GUIStyle grayMiniLabel; + public static GUIStyle GrayMiniLabel { + get { + if (grayMiniLabel == null) { + grayMiniLabel = new GUIStyle(EditorStyles.centeredGreyMiniLabel); + grayMiniLabel.alignment = TextAnchor.UpperLeft; + } + return grayMiniLabel; + } + } + + public class LabelWidthScope : System.IDisposable { + public LabelWidthScope (float minimumLabelWidth = 190f) { + EditorGUIUtility.labelWidth = minimumLabelWidth; + } + + public void Dispose () { + EditorGUIUtility.labelWidth = 0f; + } + } + + public class IndentScope : System.IDisposable { + public IndentScope () { EditorGUI.indentLevel++; } + public void Dispose () { EditorGUI.indentLevel--; } + } + + public class BoxScope : System.IDisposable { + readonly bool indent; + + static GUIStyle boxScopeStyle; + public static GUIStyle BoxScopeStyle { + get { + if (boxScopeStyle == null) { + boxScopeStyle = new GUIStyle(EditorStyles.helpBox); + RectOffset p = boxScopeStyle.padding; // RectOffset is a class + p.right += 6; + p.top += 1; + p.left += 3; + } + + return boxScopeStyle; + } + } + + public BoxScope (bool indent = true) { + this.indent = indent; + EditorGUILayout.BeginVertical(BoxScopeStyle); + if (indent) EditorGUI.indentLevel++; + } + + public void Dispose () { + if (indent) EditorGUI.indentLevel--; + EditorGUILayout.EndVertical(); + } + } + #endregion + + #region Button + const float CenterButtonMaxWidth = 270f; + const float CenterButtonHeight = 35f; + static GUIStyle spineButtonStyle; + static GUIStyle SpineButtonStyle { + get { + if (spineButtonStyle == null) { + spineButtonStyle = new GUIStyle(GUI.skin.button); + spineButtonStyle.name = "Spine Button"; + spineButtonStyle.padding = new RectOffset(10, 10, 10, 10); + } + return spineButtonStyle; + } + } + + 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(maxWidth), GUILayout.Height(CenterButtonHeight)); + EditorGUILayout.Space(); + } + EditorGUILayout.Space(); + return clicked; + } else { + return GUILayout.Button(label, GUILayout.MaxWidth(CenterButtonMaxWidth), GUILayout.Height(CenterButtonHeight)); + } + } + + 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(maxWidth), GUILayout.Height(CenterButtonHeight)); + EditorGUILayout.Space(); + } + EditorGUILayout.Space(); + return clicked; + } else { + return GUILayout.Button(content, GUILayout.MaxWidth(CenterButtonMaxWidth), GUILayout.Height(CenterButtonHeight)); + } + } + + 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(maxWidth), GUILayout.Height(height)); + EditorGUILayout.Space(); + } + EditorGUILayout.Space(); + return clicked; + } else { + return GUILayout.Button(content, GUILayout.MaxWidth(maxWidth), GUILayout.Height(height)); + } + } + #endregion + + #region Multi-Editing Helpers + public static bool TargetsUseSameData (SerializedObject so) { + if (so.isEditingMultipleObjects) { + int n = so.targetObjects.Length; + var first = so.targetObjects[0] as IHasSkeletonDataAsset; + for (int i = 1; i < n; i++) { + var sr = so.targetObjects[i] as IHasSkeletonDataAsset; + if (sr != null && sr.SkeletonDataAsset != first.SkeletonDataAsset) + return false; + } + } + return true; + } + + public static SerializedObject GetRenderersSerializedObject (SerializedObject serializedObject) { + if (serializedObject.isEditingMultipleObjects) { + var renderers = new List(); + foreach (var o in serializedObject.targetObjects) { + var component = o as Component; + if (component != null) { + var renderer = component.GetComponent(); + if (renderer != null) + renderers.Add(renderer); + } + } + return new SerializedObject(renderers.ToArray()); + } else { + var component = serializedObject.targetObject as Component; + if (component != null) { + var renderer = component.GetComponent(); + if (renderer != null) + return new SerializedObject(renderer); + } + } + + return null; + } + #endregion + + #region Sorting Layer Field Helpers + static readonly GUIContent SortingLayerLabel = new GUIContent("Sorting Layer", "MeshRenderer.sortingLayerID"); + static readonly GUIContent OrderInLayerLabel = new GUIContent("Order in Layer", "MeshRenderer.sortingOrder"); + + static MethodInfo m_SortingLayerFieldMethod; + static MethodInfo SortingLayerFieldMethod { + get { + if (m_SortingLayerFieldMethod == null) + m_SortingLayerFieldMethod = typeof(EditorGUILayout).GetMethod("SortingLayerField", BindingFlags.Static | BindingFlags.NonPublic, null, new [] { typeof(GUIContent), typeof(SerializedProperty), typeof(GUIStyle) }, null); + + return m_SortingLayerFieldMethod; + } + } + + public struct SerializedSortingProperties { + public SerializedObject renderer; + public SerializedProperty sortingLayerID; + public SerializedProperty sortingOrder; + + public SerializedSortingProperties (Renderer r) : this(new SerializedObject(r)) {} + public SerializedSortingProperties (Object[] renderers) : this(new SerializedObject(renderers)) {} + + /// + /// Initializes a new instance of the + /// struct. + /// + /// SerializedObject of the renderer. Use + /// to easily generate this. + public SerializedSortingProperties (SerializedObject rendererSerializedObject) { + renderer = rendererSerializedObject; + sortingLayerID = renderer.FindProperty("m_SortingLayerID"); + sortingOrder = renderer.FindProperty("m_SortingOrder"); + } + + public void ApplyModifiedProperties () { + renderer.ApplyModifiedProperties(); + + // SetDirty + if (renderer.isEditingMultipleObjects) + foreach (var o in renderer.targetObjects) + EditorUtility.SetDirty(o); + else + EditorUtility.SetDirty(renderer.targetObject); + } + } + + public static void SortingPropertyFields (SerializedSortingProperties prop, bool applyModifiedProperties) { + if (applyModifiedProperties) + EditorGUI.BeginChangeCheck(); + + if (SpineInspectorUtility.SortingLayerFieldMethod != null && prop.sortingLayerID != null) + SpineInspectorUtility.SortingLayerFieldMethod.Invoke(null, new object[] { SortingLayerLabel, prop.sortingLayerID, EditorStyles.popup } ); + else + EditorGUILayout.PropertyField(prop.sortingLayerID); + + EditorGUILayout.PropertyField(prop.sortingOrder, OrderInLayerLabel); + + if (applyModifiedProperties && EditorGUI.EndChangeCheck()) + prop.ApplyModifiedProperties(); + } + #endregion + } +} diff --git a/spine-unity/Assets/spine-unity/Editor/SpineInspectorUtility.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineInspectorUtility.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/SpineInspectorUtility.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineInspectorUtility.cs.meta diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Modules.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules.meta new file mode 100644 index 000000000..51ffc9e55 --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ef0ff8deb3a288646a1dd7243a918196 +folderAsset: yes +timeCreated: 1527569389 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Modules/BoundingBoxFollower.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/BoundingBoxFollower.meta new file mode 100644 index 000000000..f8a738b09 --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/BoundingBoxFollower.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6351693f94cbf774182d4b3f2a756a43 +folderAsset: yes +timeCreated: 1527569401 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/Editor.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/BoundingBoxFollower/Editor.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/Editor.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/BoundingBoxFollower/Editor.meta diff --git a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/Editor/BoundingBoxFollowerInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/BoundingBoxFollower/Editor/BoundingBoxFollowerInspector.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/Editor/BoundingBoxFollowerInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/BoundingBoxFollower/Editor/BoundingBoxFollowerInspector.cs index f1ecd2ea1..94f1e3536 100644 --- a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/Editor/BoundingBoxFollowerInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/BoundingBoxFollower/Editor/BoundingBoxFollowerInspector.cs @@ -1,206 +1,206 @@ -/****************************************************************************** - * 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 UnityEngine; -using UnityEditor; - -namespace Spine.Unity.Editor { - using Event = UnityEngine.Event; - using Icons = SpineEditorUtilities.Icons; - - [CustomEditor(typeof(BoundingBoxFollower))] - public class BoundingBoxFollowerInspector : UnityEditor.Editor { - SerializedProperty skeletonRenderer, slotName, isTrigger, clearStateOnDisable; - BoundingBoxFollower follower; - bool rebuildRequired = false; - bool addBoneFollower = false; - bool sceneRepaintRequired = false; - bool debugIsExpanded; - - GUIContent addBoneFollowerLabel; - GUIContent AddBoneFollowerLabel { - get { - if (addBoneFollowerLabel == null) addBoneFollowerLabel = new GUIContent("Add Bone Follower", Icons.bone); - return addBoneFollowerLabel; - } - } - - void OnEnable () { - skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); - slotName = serializedObject.FindProperty("slotName"); - isTrigger = serializedObject.FindProperty("isTrigger"); - clearStateOnDisable = serializedObject.FindProperty("clearStateOnDisable"); - follower = (BoundingBoxFollower)target; - } - - public override void OnInspectorGUI () { - bool isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab); - - // Try to auto-assign SkeletonRenderer field. - if (skeletonRenderer.objectReferenceValue == null) { - var foundSkeletonRenderer = follower.GetComponentInParent(); - if (foundSkeletonRenderer != null) - Debug.Log("BoundingBoxFollower automatically assigned: " + foundSkeletonRenderer.gameObject.name); - else if (Event.current.type == EventType.Repaint) - Debug.Log("No Spine GameObject detected. Make sure to set this GameObject as a child of the Spine GameObject; or set BoundingBoxFollower's 'Skeleton Renderer' field in the inspector."); - - skeletonRenderer.objectReferenceValue = foundSkeletonRenderer; - serializedObject.ApplyModifiedProperties(); - } - - var skeletonRendererValue = skeletonRenderer.objectReferenceValue as SkeletonRenderer; - if (skeletonRendererValue != null && skeletonRendererValue.gameObject == follower.gameObject) { - using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { - EditorGUILayout.HelpBox("It's ideal to add BoundingBoxFollower to a separate child GameObject of the Spine GameObject.", MessageType.Warning); - - if (GUILayout.Button(new GUIContent("Move BoundingBoxFollower to new GameObject", Icons.boundingBox), GUILayout.Height(50f))) { - AddBoundingBoxFollowerChild(skeletonRendererValue, follower); - DestroyImmediate(follower); - return; - } - } - EditorGUILayout.Space(); - } - - EditorGUI.BeginChangeCheck(); - EditorGUILayout.PropertyField(skeletonRenderer); - EditorGUILayout.PropertyField(slotName, new GUIContent("Slot")); - if (EditorGUI.EndChangeCheck()) { - serializedObject.ApplyModifiedProperties(); - if (!isInspectingPrefab) - rebuildRequired = true; - } - - using (new SpineInspectorUtility.LabelWidthScope(150f)) { - EditorGUI.BeginChangeCheck(); - EditorGUILayout.PropertyField(isTrigger); - bool triggerChanged = EditorGUI.EndChangeCheck(); - - EditorGUI.BeginChangeCheck(); - EditorGUILayout.PropertyField(clearStateOnDisable, new GUIContent(clearStateOnDisable.displayName, "Enable this if you are pooling your Spine GameObject")); - bool clearStateChanged = EditorGUI.EndChangeCheck(); - - if (clearStateChanged || triggerChanged) { - serializedObject.ApplyModifiedProperties(); - if (triggerChanged) - foreach (var col in follower.colliderTable.Values) - col.isTrigger = isTrigger.boolValue; - } - } - - if (isInspectingPrefab) { - follower.colliderTable.Clear(); - follower.nameTable.Clear(); - EditorGUILayout.HelpBox("BoundingBoxAttachments cannot be previewed in prefabs.", MessageType.Info); - - // How do you prevent components from being saved into the prefab? No such HideFlag. DontSaveInEditor | DontSaveInBuild does not work. DestroyImmediate does not work. - var collider = follower.GetComponent(); - if (collider != null) Debug.LogWarning("Found BoundingBoxFollower collider components in prefab. These are disposed and regenerated at runtime."); - - } else { - using (new SpineInspectorUtility.BoxScope()) { - if (debugIsExpanded = EditorGUILayout.Foldout(debugIsExpanded, "Debug Colliders")) { - EditorGUI.indentLevel++; - EditorGUILayout.LabelField(string.Format("Attachment Names ({0} PolygonCollider2D)", follower.colliderTable.Count)); - EditorGUI.BeginChangeCheck(); - foreach (var kp in follower.nameTable) { - string attachmentName = kp.Value; - var collider = follower.colliderTable[kp.Key]; - bool isPlaceholder = attachmentName != kp.Key.Name; - collider.enabled = EditorGUILayout.ToggleLeft(new GUIContent(!isPlaceholder ? attachmentName : string.Format("{0} [{1}]", attachmentName, kp.Key.Name), isPlaceholder ? Icons.skinPlaceholder : Icons.boundingBox), collider.enabled); - } - sceneRepaintRequired |= EditorGUI.EndChangeCheck(); - EditorGUI.indentLevel--; - } - } - - } - - bool hasBoneFollower = follower.GetComponent() != null; - if (!hasBoneFollower) { - bool buttonDisabled = follower.Slot == null; - using (new EditorGUI.DisabledGroupScope(buttonDisabled)) { - addBoneFollower |= SpineInspectorUtility.LargeCenteredButton(AddBoneFollowerLabel, true); - EditorGUILayout.Space(); - } - } - - - if (Event.current.type == EventType.Repaint) { - if (addBoneFollower) { - var boneFollower = follower.gameObject.AddComponent(); - boneFollower.skeletonRenderer = skeletonRendererValue; - boneFollower.SetBone(follower.Slot.Data.BoneData.Name); - addBoneFollower = false; - } - - if (sceneRepaintRequired) { - SceneView.RepaintAll(); - sceneRepaintRequired = false; - } - - if (rebuildRequired) { - follower.Initialize(); - rebuildRequired = false; - } - } - } - - #region Menus - [MenuItem("CONTEXT/SkeletonRenderer/Add BoundingBoxFollower GameObject")] - static void AddBoundingBoxFollowerChild (MenuCommand command) { - var go = AddBoundingBoxFollowerChild((SkeletonRenderer)command.context); - Undo.RegisterCreatedObjectUndo(go, "Add BoundingBoxFollower"); - } - #endregion - - static GameObject AddBoundingBoxFollowerChild (SkeletonRenderer sr, BoundingBoxFollower original = null) { - var go = new GameObject("BoundingBoxFollower"); - go.transform.SetParent(sr.transform, false); - var newFollower = go.AddComponent(); - - if (original != null) { - newFollower.slotName = original.slotName; - newFollower.isTrigger = original.isTrigger; - newFollower.clearStateOnDisable = original.clearStateOnDisable; - } - - newFollower.skeletonRenderer = sr; - newFollower.Initialize(); - - - Selection.activeGameObject = go; - EditorGUIUtility.PingObject(go); - return go; - } - - } - -} +/****************************************************************************** + * 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 UnityEngine; +using UnityEditor; + +namespace Spine.Unity.Editor { + using Event = UnityEngine.Event; + using Icons = SpineEditorUtilities.Icons; + + [CustomEditor(typeof(BoundingBoxFollower))] + public class BoundingBoxFollowerInspector : UnityEditor.Editor { + SerializedProperty skeletonRenderer, slotName, isTrigger, clearStateOnDisable; + BoundingBoxFollower follower; + bool rebuildRequired = false; + bool addBoneFollower = false; + bool sceneRepaintRequired = false; + bool debugIsExpanded; + + GUIContent addBoneFollowerLabel; + GUIContent AddBoneFollowerLabel { + get { + if (addBoneFollowerLabel == null) addBoneFollowerLabel = new GUIContent("Add Bone Follower", Icons.bone); + return addBoneFollowerLabel; + } + } + + void OnEnable () { + skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); + slotName = serializedObject.FindProperty("slotName"); + isTrigger = serializedObject.FindProperty("isTrigger"); + clearStateOnDisable = serializedObject.FindProperty("clearStateOnDisable"); + follower = (BoundingBoxFollower)target; + } + + public override void OnInspectorGUI () { + bool isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab); + + // Try to auto-assign SkeletonRenderer field. + if (skeletonRenderer.objectReferenceValue == null) { + var foundSkeletonRenderer = follower.GetComponentInParent(); + if (foundSkeletonRenderer != null) + Debug.Log("BoundingBoxFollower automatically assigned: " + foundSkeletonRenderer.gameObject.name); + else if (Event.current.type == EventType.Repaint) + Debug.Log("No Spine GameObject detected. Make sure to set this GameObject as a child of the Spine GameObject; or set BoundingBoxFollower's 'Skeleton Renderer' field in the inspector."); + + skeletonRenderer.objectReferenceValue = foundSkeletonRenderer; + serializedObject.ApplyModifiedProperties(); + } + + var skeletonRendererValue = skeletonRenderer.objectReferenceValue as SkeletonRenderer; + if (skeletonRendererValue != null && skeletonRendererValue.gameObject == follower.gameObject) { + using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { + EditorGUILayout.HelpBox("It's ideal to add BoundingBoxFollower to a separate child GameObject of the Spine GameObject.", MessageType.Warning); + + if (GUILayout.Button(new GUIContent("Move BoundingBoxFollower to new GameObject", Icons.boundingBox), GUILayout.Height(50f))) { + AddBoundingBoxFollowerChild(skeletonRendererValue, follower); + DestroyImmediate(follower); + return; + } + } + EditorGUILayout.Space(); + } + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(skeletonRenderer); + EditorGUILayout.PropertyField(slotName, new GUIContent("Slot")); + if (EditorGUI.EndChangeCheck()) { + serializedObject.ApplyModifiedProperties(); + if (!isInspectingPrefab) + rebuildRequired = true; + } + + using (new SpineInspectorUtility.LabelWidthScope(150f)) { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(isTrigger); + bool triggerChanged = EditorGUI.EndChangeCheck(); + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(clearStateOnDisable, new GUIContent(clearStateOnDisable.displayName, "Enable this if you are pooling your Spine GameObject")); + bool clearStateChanged = EditorGUI.EndChangeCheck(); + + if (clearStateChanged || triggerChanged) { + serializedObject.ApplyModifiedProperties(); + if (triggerChanged) + foreach (var col in follower.colliderTable.Values) + col.isTrigger = isTrigger.boolValue; + } + } + + if (isInspectingPrefab) { + follower.colliderTable.Clear(); + follower.nameTable.Clear(); + EditorGUILayout.HelpBox("BoundingBoxAttachments cannot be previewed in prefabs.", MessageType.Info); + + // How do you prevent components from being saved into the prefab? No such HideFlag. DontSaveInEditor | DontSaveInBuild does not work. DestroyImmediate does not work. + var collider = follower.GetComponent(); + if (collider != null) Debug.LogWarning("Found BoundingBoxFollower collider components in prefab. These are disposed and regenerated at runtime."); + + } else { + using (new SpineInspectorUtility.BoxScope()) { + if (debugIsExpanded = EditorGUILayout.Foldout(debugIsExpanded, "Debug Colliders")) { + EditorGUI.indentLevel++; + EditorGUILayout.LabelField(string.Format("Attachment Names ({0} PolygonCollider2D)", follower.colliderTable.Count)); + EditorGUI.BeginChangeCheck(); + foreach (var kp in follower.nameTable) { + string attachmentName = kp.Value; + var collider = follower.colliderTable[kp.Key]; + bool isPlaceholder = attachmentName != kp.Key.Name; + collider.enabled = EditorGUILayout.ToggleLeft(new GUIContent(!isPlaceholder ? attachmentName : string.Format("{0} [{1}]", attachmentName, kp.Key.Name), isPlaceholder ? Icons.skinPlaceholder : Icons.boundingBox), collider.enabled); + } + sceneRepaintRequired |= EditorGUI.EndChangeCheck(); + EditorGUI.indentLevel--; + } + } + + } + + bool hasBoneFollower = follower.GetComponent() != null; + if (!hasBoneFollower) { + bool buttonDisabled = follower.Slot == null; + using (new EditorGUI.DisabledGroupScope(buttonDisabled)) { + addBoneFollower |= SpineInspectorUtility.LargeCenteredButton(AddBoneFollowerLabel, true); + EditorGUILayout.Space(); + } + } + + + if (Event.current.type == EventType.Repaint) { + if (addBoneFollower) { + var boneFollower = follower.gameObject.AddComponent(); + boneFollower.skeletonRenderer = skeletonRendererValue; + boneFollower.SetBone(follower.Slot.Data.BoneData.Name); + addBoneFollower = false; + } + + if (sceneRepaintRequired) { + SceneView.RepaintAll(); + sceneRepaintRequired = false; + } + + if (rebuildRequired) { + follower.Initialize(); + rebuildRequired = false; + } + } + } + + #region Menus + [MenuItem("CONTEXT/SkeletonRenderer/Add BoundingBoxFollower GameObject")] + static void AddBoundingBoxFollowerChild (MenuCommand command) { + var go = AddBoundingBoxFollowerChild((SkeletonRenderer)command.context); + Undo.RegisterCreatedObjectUndo(go, "Add BoundingBoxFollower"); + } + #endregion + + static GameObject AddBoundingBoxFollowerChild (SkeletonRenderer sr, BoundingBoxFollower original = null) { + var go = new GameObject("BoundingBoxFollower"); + go.transform.SetParent(sr.transform, false); + var newFollower = go.AddComponent(); + + if (original != null) { + newFollower.slotName = original.slotName; + newFollower.isTrigger = original.isTrigger; + newFollower.clearStateOnDisable = original.clearStateOnDisable; + } + + newFollower.skeletonRenderer = sr; + newFollower.Initialize(); + + + Selection.activeGameObject = go; + EditorGUIUtility.PingObject(go); + return go; + } + + } + +} diff --git a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/Editor/BoundingBoxFollowerInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/BoundingBoxFollower/Editor/BoundingBoxFollowerInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/Editor/BoundingBoxFollowerInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/BoundingBoxFollower/Editor/BoundingBoxFollowerInspector.cs.meta diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Modules/CustomMaterials.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/CustomMaterials.meta new file mode 100644 index 000000000..7499980e3 --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/CustomMaterials.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ffde24e0e567a61418f76218f8cffb4c +folderAsset: yes +timeCreated: 1527569418 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/CustomMaterials/Editor.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/CustomMaterials/Editor.meta diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs index 47d532d12..e102ad8a5 100644 --- a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs @@ -1,166 +1,166 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -#define SPINE_OPTIONAL_MATERIALOVERRIDE - -// Contributed by: Lost Polygon - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEditor; -using UnityEngine; -using Spine.Unity.Modules; - -namespace Spine.Unity.Editor { - - // This script is not intended for use with code. See the readme.txt file in SkeletonRendererCustomMaterials folder to learn more. - [CustomEditor(typeof(SkeletonRendererCustomMaterials))] - public class SkeletonRendererCustomMaterialsInspector : UnityEditor.Editor { - List componentCustomMaterialOverrides, _customMaterialOverridesPrev; - List componentCustomSlotMaterials, _customSlotMaterialsPrev; - SkeletonRendererCustomMaterials component; - - const BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic; - MethodInfo RemoveCustomMaterialOverrides, RemoveCustomSlotMaterials, SetCustomMaterialOverrides, SetCustomSlotMaterials; - - #region SkeletonRenderer context menu - [MenuItem("CONTEXT/SkeletonRenderer/Add Basic Serialized Custom Materials")] - static void AddSkeletonRendererCustomMaterials (MenuCommand menuCommand) { - var skeletonRenderer = (SkeletonRenderer)menuCommand.context; - var newComponent = skeletonRenderer.gameObject.AddComponent(); - Undo.RegisterCreatedObjectUndo(newComponent, "Add Basic Serialized Custom Materials"); - } - - [MenuItem("CONTEXT/SkeletonRenderer/Add Basic Serialized Custom Materials", true)] - static bool AddSkeletonRendererCustomMaterials_Validate (MenuCommand menuCommand) { - var skeletonRenderer = (SkeletonRenderer)menuCommand.context; - return (skeletonRenderer.GetComponent() == null); - } - #endregion - - void OnEnable () { - Type cm = typeof(SkeletonRendererCustomMaterials); - RemoveCustomMaterialOverrides = cm.GetMethod("RemoveCustomMaterialOverrides", PrivateInstance); - RemoveCustomSlotMaterials = cm.GetMethod("RemoveCustomSlotMaterials", PrivateInstance); - SetCustomMaterialOverrides = cm.GetMethod("SetCustomMaterialOverrides", PrivateInstance); - SetCustomSlotMaterials = cm.GetMethod("SetCustomSlotMaterials", PrivateInstance); - } - - public override void OnInspectorGUI () { - component = (SkeletonRendererCustomMaterials)target; - var skeletonRenderer = component.skeletonRenderer; - - // Draw the default inspector - DrawDefaultInspector(); - - if (serializedObject.isEditingMultipleObjects) - return; - - if (componentCustomMaterialOverrides == null) { - Type cm = typeof(SkeletonRendererCustomMaterials); - componentCustomMaterialOverrides = cm.GetField("customMaterialOverrides", PrivateInstance).GetValue(component) as List; - componentCustomSlotMaterials = cm.GetField("customSlotMaterials", PrivateInstance).GetValue(component) as List; - if (componentCustomMaterialOverrides == null) { - Debug.Log("Reflection failed."); - return; - } - } - - // Fill with current values at start - if (_customMaterialOverridesPrev == null || _customSlotMaterialsPrev == null) { - _customMaterialOverridesPrev = CopyList(componentCustomMaterialOverrides); - _customSlotMaterialsPrev = CopyList(componentCustomSlotMaterials); - } - - // Compare new values with saved. If change is detected: - // store new values, restore old values, remove overrides, restore new values, restore overrides. - - // 1. Store new values - var customMaterialOverridesNew = CopyList(componentCustomMaterialOverrides); - var customSlotMaterialsNew = CopyList(componentCustomSlotMaterials); - - // Detect changes - if (!_customMaterialOverridesPrev.SequenceEqual(customMaterialOverridesNew) || - !_customSlotMaterialsPrev.SequenceEqual(customSlotMaterialsNew)) { - // 2. Restore old values - componentCustomMaterialOverrides.Clear(); - componentCustomSlotMaterials.Clear(); - componentCustomMaterialOverrides.AddRange(_customMaterialOverridesPrev); - componentCustomSlotMaterials.AddRange(_customSlotMaterialsPrev); - - // 3. Remove overrides - RemoveCustomMaterials(); - - // 4. Restore new values - componentCustomMaterialOverrides.Clear(); - componentCustomSlotMaterials.Clear(); - componentCustomMaterialOverrides.AddRange(customMaterialOverridesNew); - componentCustomSlotMaterials.AddRange(customSlotMaterialsNew); - - // 5. Restore overrides - SetCustomMaterials(); - - if (skeletonRenderer != null) - skeletonRenderer.LateUpdate(); - } - - _customMaterialOverridesPrev = CopyList(componentCustomMaterialOverrides); - _customSlotMaterialsPrev = CopyList(componentCustomSlotMaterials); - - if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent("Clear and Reapply Changes", tooltip: "Removes all non-serialized overrides in the SkeletonRenderer and reapplies the overrides on this component."))) { - if (skeletonRenderer != null) { - #if SPINE_OPTIONAL_MATERIALOVERRIDE - skeletonRenderer.CustomMaterialOverride.Clear(); - #endif - skeletonRenderer.CustomSlotMaterials.Clear(); - RemoveCustomMaterials(); - SetCustomMaterials(); - skeletonRenderer.LateUpdate(); - } - } - } - - void RemoveCustomMaterials () { - RemoveCustomMaterialOverrides.Invoke(component, null); - RemoveCustomSlotMaterials.Invoke(component, null); - } - - void SetCustomMaterials () { - SetCustomMaterialOverrides.Invoke(component, null); - SetCustomSlotMaterials.Invoke(component, null); - } - - static List CopyList (List list) { - return list.GetRange(0, list.Count); - } - } -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +#define SPINE_OPTIONAL_MATERIALOVERRIDE + +// Contributed by: Lost Polygon + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using Spine.Unity.Modules; + +namespace Spine.Unity.Editor { + + // This script is not intended for use with code. See the readme.txt file in SkeletonRendererCustomMaterials folder to learn more. + [CustomEditor(typeof(SkeletonRendererCustomMaterials))] + public class SkeletonRendererCustomMaterialsInspector : UnityEditor.Editor { + List componentCustomMaterialOverrides, _customMaterialOverridesPrev; + List componentCustomSlotMaterials, _customSlotMaterialsPrev; + SkeletonRendererCustomMaterials component; + + const BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic; + MethodInfo RemoveCustomMaterialOverrides, RemoveCustomSlotMaterials, SetCustomMaterialOverrides, SetCustomSlotMaterials; + + #region SkeletonRenderer context menu + [MenuItem("CONTEXT/SkeletonRenderer/Add Basic Serialized Custom Materials")] + static void AddSkeletonRendererCustomMaterials (MenuCommand menuCommand) { + var skeletonRenderer = (SkeletonRenderer)menuCommand.context; + var newComponent = skeletonRenderer.gameObject.AddComponent(); + Undo.RegisterCreatedObjectUndo(newComponent, "Add Basic Serialized Custom Materials"); + } + + [MenuItem("CONTEXT/SkeletonRenderer/Add Basic Serialized Custom Materials", true)] + static bool AddSkeletonRendererCustomMaterials_Validate (MenuCommand menuCommand) { + var skeletonRenderer = (SkeletonRenderer)menuCommand.context; + return (skeletonRenderer.GetComponent() == null); + } + #endregion + + void OnEnable () { + Type cm = typeof(SkeletonRendererCustomMaterials); + RemoveCustomMaterialOverrides = cm.GetMethod("RemoveCustomMaterialOverrides", PrivateInstance); + RemoveCustomSlotMaterials = cm.GetMethod("RemoveCustomSlotMaterials", PrivateInstance); + SetCustomMaterialOverrides = cm.GetMethod("SetCustomMaterialOverrides", PrivateInstance); + SetCustomSlotMaterials = cm.GetMethod("SetCustomSlotMaterials", PrivateInstance); + } + + public override void OnInspectorGUI () { + component = (SkeletonRendererCustomMaterials)target; + var skeletonRenderer = component.skeletonRenderer; + + // Draw the default inspector + DrawDefaultInspector(); + + if (serializedObject.isEditingMultipleObjects) + return; + + if (componentCustomMaterialOverrides == null) { + Type cm = typeof(SkeletonRendererCustomMaterials); + componentCustomMaterialOverrides = cm.GetField("customMaterialOverrides", PrivateInstance).GetValue(component) as List; + componentCustomSlotMaterials = cm.GetField("customSlotMaterials", PrivateInstance).GetValue(component) as List; + if (componentCustomMaterialOverrides == null) { + Debug.Log("Reflection failed."); + return; + } + } + + // Fill with current values at start + if (_customMaterialOverridesPrev == null || _customSlotMaterialsPrev == null) { + _customMaterialOverridesPrev = CopyList(componentCustomMaterialOverrides); + _customSlotMaterialsPrev = CopyList(componentCustomSlotMaterials); + } + + // Compare new values with saved. If change is detected: + // store new values, restore old values, remove overrides, restore new values, restore overrides. + + // 1. Store new values + var customMaterialOverridesNew = CopyList(componentCustomMaterialOverrides); + var customSlotMaterialsNew = CopyList(componentCustomSlotMaterials); + + // Detect changes + if (!_customMaterialOverridesPrev.SequenceEqual(customMaterialOverridesNew) || + !_customSlotMaterialsPrev.SequenceEqual(customSlotMaterialsNew)) { + // 2. Restore old values + componentCustomMaterialOverrides.Clear(); + componentCustomSlotMaterials.Clear(); + componentCustomMaterialOverrides.AddRange(_customMaterialOverridesPrev); + componentCustomSlotMaterials.AddRange(_customSlotMaterialsPrev); + + // 3. Remove overrides + RemoveCustomMaterials(); + + // 4. Restore new values + componentCustomMaterialOverrides.Clear(); + componentCustomSlotMaterials.Clear(); + componentCustomMaterialOverrides.AddRange(customMaterialOverridesNew); + componentCustomSlotMaterials.AddRange(customSlotMaterialsNew); + + // 5. Restore overrides + SetCustomMaterials(); + + if (skeletonRenderer != null) + skeletonRenderer.LateUpdate(); + } + + _customMaterialOverridesPrev = CopyList(componentCustomMaterialOverrides); + _customSlotMaterialsPrev = CopyList(componentCustomSlotMaterials); + + if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent("Clear and Reapply Changes", tooltip: "Removes all non-serialized overrides in the SkeletonRenderer and reapplies the overrides on this component."))) { + if (skeletonRenderer != null) { + #if SPINE_OPTIONAL_MATERIALOVERRIDE + skeletonRenderer.CustomMaterialOverride.Clear(); + #endif + skeletonRenderer.CustomSlotMaterials.Clear(); + RemoveCustomMaterials(); + SetCustomMaterials(); + skeletonRenderer.LateUpdate(); + } + } + } + + void RemoveCustomMaterials () { + RemoveCustomMaterialOverrides.Invoke(component, null); + RemoveCustomSlotMaterials.Invoke(component, null); + } + + void SetCustomMaterials () { + SetCustomMaterialOverrides.Invoke(component, null); + SetCustomSlotMaterials.Invoke(component, null); + } + + static List CopyList (List list) { + return list.GetRange(0, list.Count); + } + } +} diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs.meta diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll.meta new file mode 100644 index 000000000..194252b11 --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a5ca7a6f2b7e25646ad2f5776178bf78 +folderAsset: yes +timeCreated: 1527569438 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs similarity index 98% rename from spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs index 075954977..9a75edb98 100644 --- a/spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs @@ -1,38 +1,38 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -// Contributed by: Mitch Thompson - -using UnityEngine; -using UnityEditor; - -namespace Spine.Unity.Modules { - public class SkeletonRagdoll2DInspector {} -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Contributed by: Mitch Thompson + +using UnityEngine; +using UnityEditor; + +namespace Spine.Unity.Modules { + public class SkeletonRagdoll2DInspector {} +} diff --git a/spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdollInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdollInspector.cs similarity index 98% rename from spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdollInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdollInspector.cs index 095d5ecb7..c374f8282 100644 --- a/spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdollInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdollInspector.cs @@ -1,47 +1,47 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -// Contributed by: Mitch Thompson - -using UnityEngine; -using UnityEditor; - -namespace Spine.Unity.Modules { - - public class SkeletonRagdollInspector : UnityEditor.Editor { - [CustomPropertyDrawer(typeof(SkeletonRagdoll.LayerFieldAttribute))] - public class LayerFieldPropertyDrawer : PropertyDrawer { - public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { - property.intValue = EditorGUI.LayerField(position, label, property.intValue); - } - } - } - -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Contributed by: Mitch Thompson + +using UnityEngine; +using UnityEditor; + +namespace Spine.Unity.Modules { + + public class SkeletonRagdollInspector : UnityEditor.Editor { + [CustomPropertyDrawer(typeof(SkeletonRagdoll.LayerFieldAttribute))] + public class LayerFieldPropertyDrawer : PropertyDrawer { + public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { + property.intValue = EditorGUI.LayerField(position, label, property.intValue); + } + } + } + +} diff --git a/spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdollInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdollInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdollInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Ragdoll/Editor/SkeletonRagdollInspector.cs.meta diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders.meta new file mode 100644 index 000000000..007cc76e6 --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 10e0b626d7ae7394a934ee9f2fb81b5a +folderAsset: yes +timeCreated: 1527569604 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders/Sprite.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders/Sprite.meta new file mode 100644 index 000000000..6550f0405 --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders/Sprite.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f9ef69c370f1b0f4db091a85df7f2c96 +folderAsset: yes +timeCreated: 1527569612 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/Editor.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders/Sprite/Editor.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/Editor.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders/Sprite/Editor.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Shaders/Sprite/Editor/SpineSpriteShaderGUI.cs.meta diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic.meta new file mode 100644 index 000000000..9e6f04cda --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7a4120eda5e72634b8ea086a00778669 +folderAsset: yes +timeCreated: 1527569450 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic/Editor.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic/Editor.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/BoneFollowerGraphicInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic/Editor/BoneFollowerGraphicInspector.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/BoneFollowerGraphicInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic/Editor/BoneFollowerGraphicInspector.cs diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/BoneFollowerGraphicInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic/Editor/BoneFollowerGraphicInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/BoneFollowerGraphicInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic/Editor/BoneFollowerGraphicInspector.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs index 5f95f924e..acf9bbf5a 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs @@ -1,229 +1,229 @@ -/****************************************************************************** - * 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 UnityEngine; -using UnityEditor; -using Spine; - -namespace Spine.Unity.Editor { - - [InitializeOnLoad] - [CustomEditor(typeof(SkeletonGraphic))] - [CanEditMultipleObjects] - public class SkeletonGraphicInspector : UnityEditor.Editor { - SerializedProperty material, color; - SerializedProperty skeletonDataAsset, initialSkinName; - SerializedProperty startingAnimation, startingLoop, timeScale, freeze, unscaledTime, tintBlack; - SerializedProperty initialFlipX, initialFlipY; - SerializedProperty meshGeneratorSettings; - SerializedProperty raycastTarget; - - SkeletonGraphic thisSkeletonGraphic; - - void OnEnable () { - var so = this.serializedObject; - thisSkeletonGraphic = target as SkeletonGraphic; - - // MaskableGraphic - material = so.FindProperty("m_Material"); - color = so.FindProperty("m_Color"); - raycastTarget = so.FindProperty("m_RaycastTarget"); - - // SkeletonRenderer - skeletonDataAsset = so.FindProperty("skeletonDataAsset"); - initialSkinName = so.FindProperty("initialSkinName"); - - initialFlipX = so.FindProperty("initialFlipX"); - initialFlipY = so.FindProperty("initialFlipY"); - - // SkeletonAnimation - startingAnimation = so.FindProperty("startingAnimation"); - startingLoop = so.FindProperty("startingLoop"); - timeScale = so.FindProperty("timeScale"); - unscaledTime = so.FindProperty("unscaledTime"); - freeze = so.FindProperty("freeze"); - - meshGeneratorSettings = so.FindProperty("meshGenerator").FindPropertyRelative("settings"); - meshGeneratorSettings.isExpanded = SkeletonRendererInspector.advancedFoldout; - } - - 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; - initialFlipX.boolValue = EditorGUI.ToggleLeft(rect, SpineInspectorUtility.TempContent("X", tooltip:"initialFlipX"), initialFlipX.boolValue); - rect.x += 35f; - initialFlipY.boolValue = EditorGUI.ToggleLeft(rect, SpineInspectorUtility.TempContent("Y", tooltip:"initialFlipY"), initialFlipY.boolValue); - } - - 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); - - bool wasChanged = EditorGUI.EndChangeCheck(); - - if (wasChanged) - serializedObject.ApplyModifiedProperties(); - } - - #region Menus - [MenuItem("CONTEXT/SkeletonGraphic/Match RectTransform with Mesh Bounds")] - static void MatchRectTransformWithBounds (MenuCommand command) { - var skeletonGraphic = (SkeletonGraphic)command.context; - Mesh mesh = skeletonGraphic.GetLastMesh(); - if (mesh == null) { - Debug.Log("Mesh was not previously generated."); - return; - } - - if (mesh.vertexCount == 0) { - skeletonGraphic.rectTransform.sizeDelta = new Vector2(50f, 50f); - skeletonGraphic.rectTransform.pivot = new Vector2(0.5f, 0.5f); - return; - } - - mesh.RecalculateBounds(); - var bounds = mesh.bounds; - var size = bounds.size; - var center = bounds.center; - var p = new Vector2( - 0.5f - (center.x / size.x), - 0.5f - (center.y / size.y) - ); - - skeletonGraphic.rectTransform.sizeDelta = size; - skeletonGraphic.rectTransform.pivot = p; - } - - [MenuItem("GameObject/Spine/SkeletonGraphic (UnityUI)", false, 15)] - static public void SkeletonGraphicCreateMenuItem () { - var parentGameObject = Selection.activeObject as GameObject; - var parentTransform = parentGameObject == null ? null : parentGameObject.GetComponent(); - - 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); - EditorUtility.FocusProjectWindow(); - Selection.activeObject = gameObject; - EditorGUIUtility.PingObject(Selection.activeObject); - } - - // SpineEditorUtilities.InstantiateDelegate. Used by drag and drop. - public static Component SpawnSkeletonGraphicFromDrop (SkeletonDataAsset data) { - return InstantiateSkeletonGraphic(data); - } - - public static SkeletonGraphic InstantiateSkeletonGraphic (SkeletonDataAsset skeletonDataAsset, string skinName) { - return InstantiateSkeletonGraphic(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName)); - } - - public static SkeletonGraphic InstantiateSkeletonGraphic (SkeletonDataAsset skeletonDataAsset, Skin skin = null) { - string spineGameObjectName = string.Format("SkeletonGraphic ({0})", skeletonDataAsset.name.Replace("_SkeletonData", "")); - var go = NewSkeletonGraphicGameObject(spineGameObjectName); - var graphic = go.GetComponent(); - graphic.skeletonDataAsset = skeletonDataAsset; - - SkeletonData data = skeletonDataAsset.GetSkeletonData(true); - - if (data == null) { - for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) { - string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]); - skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset)); - } - - data = skeletonDataAsset.GetSkeletonData(true); - } - - skin = skin ?? data.DefaultSkin ?? data.Skins.Items[0]; - graphic.MeshGenerator.settings.zSpacing = SpineEditorUtilities.defaultZSpacing; - - graphic.Initialize(false); - if (skin != null) graphic.Skeleton.SetSkin(skin); - graphic.initialSkinName = skin.Name; - graphic.Skeleton.UpdateWorldTransform(); - graphic.UpdateMesh(); - - return graphic; - } - - static GameObject NewSkeletonGraphicGameObject (string gameObjectName) { - var go = new GameObject(gameObjectName, typeof(RectTransform), typeof(CanvasRenderer), typeof(SkeletonGraphic)); - var graphic = go.GetComponent(); - graphic.material = SkeletonGraphicInspector.DefaultSkeletonGraphicMaterial; - return go; - } - - public static Material DefaultSkeletonGraphicMaterial { - get { - var guids = AssetDatabase.FindAssets("SkeletonGraphicDefault t:material"); - if (guids.Length <= 0) return null; - - var firstAssetPath = AssetDatabase.GUIDToAssetPath(guids[0]); - if (string.IsNullOrEmpty(firstAssetPath)) return null; - - var firstMaterial = AssetDatabase.LoadAssetAtPath(firstAssetPath); - return firstMaterial; - } - } - - #endregion - } -} +/****************************************************************************** + * 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 UnityEngine; +using UnityEditor; +using Spine; + +namespace Spine.Unity.Editor { + + [InitializeOnLoad] + [CustomEditor(typeof(SkeletonGraphic))] + [CanEditMultipleObjects] + public class SkeletonGraphicInspector : UnityEditor.Editor { + SerializedProperty material, color; + SerializedProperty skeletonDataAsset, initialSkinName; + SerializedProperty startingAnimation, startingLoop, timeScale, freeze, unscaledTime, tintBlack; + SerializedProperty initialFlipX, initialFlipY; + SerializedProperty meshGeneratorSettings; + SerializedProperty raycastTarget; + + SkeletonGraphic thisSkeletonGraphic; + + void OnEnable () { + var so = this.serializedObject; + thisSkeletonGraphic = target as SkeletonGraphic; + + // MaskableGraphic + material = so.FindProperty("m_Material"); + color = so.FindProperty("m_Color"); + raycastTarget = so.FindProperty("m_RaycastTarget"); + + // SkeletonRenderer + skeletonDataAsset = so.FindProperty("skeletonDataAsset"); + initialSkinName = so.FindProperty("initialSkinName"); + + initialFlipX = so.FindProperty("initialFlipX"); + initialFlipY = so.FindProperty("initialFlipY"); + + // SkeletonAnimation + startingAnimation = so.FindProperty("startingAnimation"); + startingLoop = so.FindProperty("startingLoop"); + timeScale = so.FindProperty("timeScale"); + unscaledTime = so.FindProperty("unscaledTime"); + freeze = so.FindProperty("freeze"); + + meshGeneratorSettings = so.FindProperty("meshGenerator").FindPropertyRelative("settings"); + meshGeneratorSettings.isExpanded = SkeletonRendererInspector.advancedFoldout; + } + + 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; + initialFlipX.boolValue = EditorGUI.ToggleLeft(rect, SpineInspectorUtility.TempContent("X", tooltip:"initialFlipX"), initialFlipX.boolValue); + rect.x += 35f; + initialFlipY.boolValue = EditorGUI.ToggleLeft(rect, SpineInspectorUtility.TempContent("Y", tooltip:"initialFlipY"), initialFlipY.boolValue); + } + + 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); + + bool wasChanged = EditorGUI.EndChangeCheck(); + + if (wasChanged) + serializedObject.ApplyModifiedProperties(); + } + + #region Menus + [MenuItem("CONTEXT/SkeletonGraphic/Match RectTransform with Mesh Bounds")] + static void MatchRectTransformWithBounds (MenuCommand command) { + var skeletonGraphic = (SkeletonGraphic)command.context; + Mesh mesh = skeletonGraphic.GetLastMesh(); + if (mesh == null) { + Debug.Log("Mesh was not previously generated."); + return; + } + + if (mesh.vertexCount == 0) { + skeletonGraphic.rectTransform.sizeDelta = new Vector2(50f, 50f); + skeletonGraphic.rectTransform.pivot = new Vector2(0.5f, 0.5f); + return; + } + + mesh.RecalculateBounds(); + var bounds = mesh.bounds; + var size = bounds.size; + var center = bounds.center; + var p = new Vector2( + 0.5f - (center.x / size.x), + 0.5f - (center.y / size.y) + ); + + skeletonGraphic.rectTransform.sizeDelta = size; + skeletonGraphic.rectTransform.pivot = p; + } + + [MenuItem("GameObject/Spine/SkeletonGraphic (UnityUI)", false, 15)] + static public void SkeletonGraphicCreateMenuItem () { + var parentGameObject = Selection.activeObject as GameObject; + var parentTransform = parentGameObject == null ? null : parentGameObject.GetComponent(); + + 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); + EditorUtility.FocusProjectWindow(); + Selection.activeObject = gameObject; + EditorGUIUtility.PingObject(Selection.activeObject); + } + + // SpineEditorUtilities.InstantiateDelegate. Used by drag and drop. + public static Component SpawnSkeletonGraphicFromDrop (SkeletonDataAsset data) { + return InstantiateSkeletonGraphic(data); + } + + public static SkeletonGraphic InstantiateSkeletonGraphic (SkeletonDataAsset skeletonDataAsset, string skinName) { + return InstantiateSkeletonGraphic(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName)); + } + + public static SkeletonGraphic InstantiateSkeletonGraphic (SkeletonDataAsset skeletonDataAsset, Skin skin = null) { + string spineGameObjectName = string.Format("SkeletonGraphic ({0})", skeletonDataAsset.name.Replace("_SkeletonData", "")); + var go = NewSkeletonGraphicGameObject(spineGameObjectName); + var graphic = go.GetComponent(); + graphic.skeletonDataAsset = skeletonDataAsset; + + SkeletonData data = skeletonDataAsset.GetSkeletonData(true); + + if (data == null) { + for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) { + string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]); + skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset)); + } + + data = skeletonDataAsset.GetSkeletonData(true); + } + + skin = skin ?? data.DefaultSkin ?? data.Skins.Items[0]; + graphic.MeshGenerator.settings.zSpacing = SpineEditorUtilities.defaultZSpacing; + + graphic.Initialize(false); + if (skin != null) graphic.Skeleton.SetSkin(skin); + graphic.initialSkinName = skin.Name; + graphic.Skeleton.UpdateWorldTransform(); + graphic.UpdateMesh(); + + return graphic; + } + + static GameObject NewSkeletonGraphicGameObject (string gameObjectName) { + var go = new GameObject(gameObjectName, typeof(RectTransform), typeof(CanvasRenderer), typeof(SkeletonGraphic)); + var graphic = go.GetComponent(); + graphic.material = SkeletonGraphicInspector.DefaultSkeletonGraphicMaterial; + return go; + } + + public static Material DefaultSkeletonGraphicMaterial { + get { + var guids = AssetDatabase.FindAssets("SkeletonGraphicDefault t:material"); + if (guids.Length <= 0) return null; + + var firstAssetPath = AssetDatabase.GUIDToAssetPath(guids[0]); + if (string.IsNullOrEmpty(firstAssetPath)) return null; + + var firstMaterial = AssetDatabase.LoadAssetAtPath(firstAssetPath); + return firstMaterial; + } + } + + #endregion + } +} diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs.meta diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator.meta new file mode 100644 index 000000000..40aec39a1 --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1bf8fd476d074f449bbae932a1c8a360 +folderAsset: yes +timeCreated: 1527569465 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs similarity index 98% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs index 30dbe4f21..81eda3f98 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs @@ -1,56 +1,56 @@ -/****************************************************************************** - * 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 UnityEngine; -using UnityEditor; -using Spine.Unity.Editor; - -namespace Spine.Unity.Modules { - [CustomEditor(typeof(SkeletonPartsRenderer))] - public class SkeletonRenderPartInspector : UnityEditor.Editor { - SpineInspectorUtility.SerializedSortingProperties sortingProperties; - - void OnEnable () { - sortingProperties = new SpineInspectorUtility.SerializedSortingProperties((target as Component).GetComponent()); - } - - public override void OnInspectorGUI () { - SpineInspectorUtility.SortingPropertyFields(sortingProperties, true); - EditorGUILayout.Space(); - if (SpineInspectorUtility.LargeCenteredButton(new GUIContent("Select SkeletonRenderer", SpineEditorUtilities.Icons.spine))) { - var thisSkeletonPartsRenderer = target as SkeletonPartsRenderer; - var srs = thisSkeletonPartsRenderer.GetComponentInParent(); - if (srs != null && srs.partsRenderers.Contains(thisSkeletonPartsRenderer) && srs.SkeletonRenderer != null) - Selection.activeGameObject = srs.SkeletonRenderer.gameObject; - } - } - } - -} +/****************************************************************************** + * 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 UnityEngine; +using UnityEditor; +using Spine.Unity.Editor; + +namespace Spine.Unity.Modules { + [CustomEditor(typeof(SkeletonPartsRenderer))] + public class SkeletonRenderPartInspector : UnityEditor.Editor { + SpineInspectorUtility.SerializedSortingProperties sortingProperties; + + void OnEnable () { + sortingProperties = new SpineInspectorUtility.SerializedSortingProperties((target as Component).GetComponent()); + } + + public override void OnInspectorGUI () { + SpineInspectorUtility.SortingPropertyFields(sortingProperties, true); + EditorGUILayout.Space(); + if (SpineInspectorUtility.LargeCenteredButton(new GUIContent("Select SkeletonRenderer", SpineEditorUtilities.Icons.spine))) { + var thisSkeletonPartsRenderer = target as SkeletonPartsRenderer; + var srs = thisSkeletonPartsRenderer.GetComponentInParent(); + if (srs != null && srs.partsRenderers.Contains(thisSkeletonPartsRenderer) && srs.SkeletonRenderer != null) + Selection.activeGameObject = srs.SkeletonRenderer.gameObject; + } + } + } + +} diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs index d2052b0c2..856e5318b 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs @@ -1,291 +1,291 @@ -/****************************************************************************** - * 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 UnityEngine; -using UnityEditor; - -using System.Collections.Generic; - -using Spine.Unity; -using Spine.Unity.Editor; - -namespace Spine.Unity.Modules { - - [CustomEditor(typeof(SkeletonRenderSeparator))] - public class SkeletonRenderSeparatorInspector : UnityEditor.Editor { - SkeletonRenderSeparator component; - - // Properties - SerializedProperty skeletonRenderer_, copyPropertyBlock_, copyMeshRendererFlags_, partsRenderers_; - static bool partsRenderersExpanded = false; - - // For separator field. - SerializedObject skeletonRendererSerializedObject; - SerializedProperty separatorNamesProp; - static bool skeletonRendererExpanded = true; - bool slotsReapplyRequired = false; - - void OnEnable () { - if (component == null) - component = target as SkeletonRenderSeparator; - - skeletonRenderer_ = serializedObject.FindProperty("skeletonRenderer"); - copyPropertyBlock_ = serializedObject.FindProperty("copyPropertyBlock"); - copyMeshRendererFlags_ = serializedObject.FindProperty("copyMeshRendererFlags"); - - var partsRenderers = component.partsRenderers; - partsRenderers_ = serializedObject.FindProperty("partsRenderers"); - partsRenderers_.isExpanded = partsRenderersExpanded || // last state - partsRenderers.Contains(null) || // null items found - partsRenderers.Count < 1 || // no parts renderers - (skeletonRenderer_.objectReferenceValue != null && SkeletonRendererSeparatorCount + 1 > partsRenderers.Count); // not enough parts renderers - } - - int SkeletonRendererSeparatorCount { - get { - if (Application.isPlaying) - return component.SkeletonRenderer.separatorSlots.Count; - else - return separatorNamesProp == null ? 0 : separatorNamesProp.arraySize; - } - } - - public override void OnInspectorGUI () { - var componentRenderers = component.partsRenderers; - int totalParts; - - using (new SpineInspectorUtility.LabelWidthScope()) { - bool componentEnabled = component.enabled; - bool checkBox = EditorGUILayout.Toggle("Enable Separator", componentEnabled); - if (checkBox != componentEnabled) - component.enabled = checkBox; - if (component.SkeletonRenderer.disableRenderingOnOverride && !component.enabled) - EditorGUILayout.HelpBox("By default, SkeletonRenderer's MeshRenderer is disabled while the SkeletonRenderSeparator takes over rendering. It is re-enabled when SkeletonRenderSeparator is disabled.", MessageType.Info); - - EditorGUILayout.PropertyField(copyPropertyBlock_); - EditorGUILayout.PropertyField(copyMeshRendererFlags_); - } - - // SkeletonRenderer Box - using (new SpineInspectorUtility.BoxScope(false)) { - // Fancy SkeletonRenderer foldout reference field - { - EditorGUI.indentLevel++; - EditorGUI.BeginChangeCheck(); - var foldoutSkeletonRendererRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight); - EditorGUI.PropertyField(foldoutSkeletonRendererRect, skeletonRenderer_); - if (EditorGUI.EndChangeCheck()) - serializedObject.ApplyModifiedProperties(); - if (component.SkeletonRenderer != null) { - skeletonRendererExpanded = EditorGUI.Foldout(foldoutSkeletonRendererRect, skeletonRendererExpanded, ""); - } - EditorGUI.indentLevel--; - } - - int separatorCount = 0; - EditorGUI.BeginChangeCheck(); - if (component.SkeletonRenderer != null) { - // Separators from SkeletonRenderer - { - bool skeletonRendererMismatch = skeletonRendererSerializedObject != null && skeletonRendererSerializedObject.targetObject != component.SkeletonRenderer; - if (separatorNamesProp == null || skeletonRendererMismatch) { - if (component.SkeletonRenderer != null) { - skeletonRendererSerializedObject = new SerializedObject(component.SkeletonRenderer); - separatorNamesProp = skeletonRendererSerializedObject.FindProperty("separatorSlotNames"); - separatorNamesProp.isExpanded = true; - } - } - - if (separatorNamesProp != null) { - if (skeletonRendererExpanded) { - EditorGUI.indentLevel++; - SkeletonRendererInspector.SeparatorsField(separatorNamesProp); - EditorGUI.indentLevel--; - } - separatorCount = this.SkeletonRendererSeparatorCount; - } - } - - if (SkeletonRendererSeparatorCount == 0) { - EditorGUILayout.HelpBox("Separators are empty. Change the size to 1 and choose a slot if you want the render to be separated.", MessageType.Info); - } - } - - if (EditorGUI.EndChangeCheck()) { - skeletonRendererSerializedObject.ApplyModifiedProperties(); - - if (!Application.isPlaying) - slotsReapplyRequired = true; - } - - - totalParts = separatorCount + 1; - var counterStyle = skeletonRendererExpanded ? EditorStyles.label : EditorStyles.miniLabel; - EditorGUILayout.LabelField(string.Format("{0}: separates into {1}.", SpineInspectorUtility.Pluralize(separatorCount, "separator", "separators"), SpineInspectorUtility.Pluralize(totalParts, "part", "parts") ), counterStyle); - } - - // Parts renderers - using (new SpineInspectorUtility.BoxScope(false)) { - EditorGUI.indentLevel++; - EditorGUILayout.PropertyField(this.partsRenderers_, true); - EditorGUI.indentLevel--; - - // Null items warning - bool nullItemsFound = componentRenderers.Contains(null); - if (nullItemsFound) - EditorGUILayout.HelpBox("Some items in the parts renderers list are null and may cause problems.\n\nYou can right-click on that element and choose 'Delete Array Element' to remove it.", MessageType.Warning); - - // (Button) Match Separators count - if (separatorNamesProp != null) { - int currentRenderers = 0; - foreach (var r in componentRenderers) { - if (r != null) - currentRenderers++; - } - int extraRenderersNeeded = totalParts - currentRenderers; - - if (component.enabled && component.SkeletonRenderer != null && extraRenderersNeeded > 0) { - EditorGUILayout.HelpBox(string.Format("Insufficient parts renderers. Some parts will not be rendered."), MessageType.Warning); - string addMissingLabel = string.Format("Add the missing renderer{1} ({0}) ", extraRenderersNeeded, SpineInspectorUtility.PluralThenS(extraRenderersNeeded)); - if (GUILayout.Button(addMissingLabel, GUILayout.Height(40f))) { - AddPartsRenderer(extraRenderersNeeded); - DetectOrphanedPartsRenderers(component); - } - } - } - - if (partsRenderers_.isExpanded != partsRenderersExpanded) partsRenderersExpanded = partsRenderers_.isExpanded; - if (partsRenderers_.isExpanded) { - using (new EditorGUILayout.HorizontalScope()) { - // (Button) Destroy Renderers button - if (componentRenderers.Count > 0) { - if (GUILayout.Button("Clear Parts Renderers")) { - // Do you really want to destroy all? - Undo.RegisterCompleteObjectUndo(component, "Clear Parts Renderers"); - if (EditorUtility.DisplayDialog("Destroy Renderers", "Do you really want to destroy all the Parts Renderer GameObjects in the list?", "Destroy", "Cancel")) { - foreach (var r in componentRenderers) { - if (r != null) - Undo.DestroyObjectImmediate(r.gameObject); - } - componentRenderers.Clear(); - // Do you also want to destroy orphans? (You monster.) - DetectOrphanedPartsRenderers(component); - } - } - } - - // (Button) Add Part Renderer button - if (GUILayout.Button("Add Parts Renderer")) - AddPartsRenderer(1); - } - } - } - - serializedObject.ApplyModifiedProperties(); - - if (slotsReapplyRequired && UnityEngine.Event.current.type == EventType.Repaint) { - SkeletonRendererInspector.ReapplySeparatorSlotNames(component.SkeletonRenderer); - component.SkeletonRenderer.LateUpdate(); - SceneView.RepaintAll(); - slotsReapplyRequired = false; - } - } - - public void AddPartsRenderer (int count) { - var componentRenderers = component.partsRenderers; - bool emptyFound = componentRenderers.Contains(null); - if (emptyFound) { - bool userClearEntries = EditorUtility.DisplayDialog("Empty entries found", "Null entries found. Do you want to remove null entries before adding the new renderer? ", "Clear Empty Entries", "Don't Clear"); - if (userClearEntries) componentRenderers.RemoveAll(x => x == null); - } - - Undo.RegisterCompleteObjectUndo(component, "Add Parts Renderers"); - for (int i = 0; i < count; i++) { - int index = componentRenderers.Count; - var smr = SkeletonPartsRenderer.NewPartsRendererGameObject(component.transform, index.ToString()); - Undo.RegisterCreatedObjectUndo(smr.gameObject, "New Parts Renderer GameObject."); - componentRenderers.Add(smr); - - // increment renderer sorting order. - if (index == 0) continue; - var prev = componentRenderers[index - 1]; if (prev == null) continue; - - var prevMeshRenderer = prev.GetComponent(); - var currentMeshRenderer = smr.GetComponent(); - if (prevMeshRenderer == null || currentMeshRenderer == null) continue; - - int prevSortingLayer = prevMeshRenderer.sortingLayerID; - int prevSortingOrder = prevMeshRenderer.sortingOrder; - currentMeshRenderer.sortingLayerID = prevSortingLayer; - currentMeshRenderer.sortingOrder = prevSortingOrder + SkeletonRenderSeparator.DefaultSortingOrderIncrement; - } - - } - - /// Detects orphaned parts renderers and offers to delete them. - public void DetectOrphanedPartsRenderers (SkeletonRenderSeparator component) { - var children = component.GetComponentsInChildren(); - - var orphans = new System.Collections.Generic.List(); - foreach (var r in children) { - if (!component.partsRenderers.Contains(r)) - orphans.Add(r); - } - - if (orphans.Count > 0) { - if (EditorUtility.DisplayDialog("Destroy Submesh Renderers", "Unassigned renderers were found. Do you want to delete them? (These may belong to another Render Separator in the same hierarchy. If you don't have another Render Separator component in the children of this GameObject, it's likely safe to delete. Warning: This operation cannot be undone.)", "Delete", "Cancel")) { - foreach (var o in orphans) { - Undo.DestroyObjectImmediate(o.gameObject); - } - } - } - } - - #region SkeletonRenderer Context Menu Item - [MenuItem ("CONTEXT/SkeletonRenderer/Add Skeleton Render Separator")] - static void AddRenderSeparatorComponent (MenuCommand cmd) { - var skeletonRenderer = cmd.context as SkeletonRenderer; - var newComponent = skeletonRenderer.gameObject.AddComponent(); - - Undo.RegisterCreatedObjectUndo(newComponent, "Add SkeletonRenderSeparator"); - } - - // Validate - [MenuItem ("CONTEXT/SkeletonRenderer/Add Skeleton Render Separator", true)] - static bool ValidateAddRenderSeparatorComponent (MenuCommand cmd) { - var skeletonRenderer = cmd.context as SkeletonRenderer; - var separator = skeletonRenderer.GetComponent(); - bool separatorNotOnObject = separator == null; - return separatorNotOnObject; - } - #endregion - - } -} +/****************************************************************************** + * 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 UnityEngine; +using UnityEditor; + +using System.Collections.Generic; + +using Spine.Unity; +using Spine.Unity.Editor; + +namespace Spine.Unity.Modules { + + [CustomEditor(typeof(SkeletonRenderSeparator))] + public class SkeletonRenderSeparatorInspector : UnityEditor.Editor { + SkeletonRenderSeparator component; + + // Properties + SerializedProperty skeletonRenderer_, copyPropertyBlock_, copyMeshRendererFlags_, partsRenderers_; + static bool partsRenderersExpanded = false; + + // For separator field. + SerializedObject skeletonRendererSerializedObject; + SerializedProperty separatorNamesProp; + static bool skeletonRendererExpanded = true; + bool slotsReapplyRequired = false; + + void OnEnable () { + if (component == null) + component = target as SkeletonRenderSeparator; + + skeletonRenderer_ = serializedObject.FindProperty("skeletonRenderer"); + copyPropertyBlock_ = serializedObject.FindProperty("copyPropertyBlock"); + copyMeshRendererFlags_ = serializedObject.FindProperty("copyMeshRendererFlags"); + + var partsRenderers = component.partsRenderers; + partsRenderers_ = serializedObject.FindProperty("partsRenderers"); + partsRenderers_.isExpanded = partsRenderersExpanded || // last state + partsRenderers.Contains(null) || // null items found + partsRenderers.Count < 1 || // no parts renderers + (skeletonRenderer_.objectReferenceValue != null && SkeletonRendererSeparatorCount + 1 > partsRenderers.Count); // not enough parts renderers + } + + int SkeletonRendererSeparatorCount { + get { + if (Application.isPlaying) + return component.SkeletonRenderer.separatorSlots.Count; + else + return separatorNamesProp == null ? 0 : separatorNamesProp.arraySize; + } + } + + public override void OnInspectorGUI () { + var componentRenderers = component.partsRenderers; + int totalParts; + + using (new SpineInspectorUtility.LabelWidthScope()) { + bool componentEnabled = component.enabled; + bool checkBox = EditorGUILayout.Toggle("Enable Separator", componentEnabled); + if (checkBox != componentEnabled) + component.enabled = checkBox; + if (component.SkeletonRenderer.disableRenderingOnOverride && !component.enabled) + EditorGUILayout.HelpBox("By default, SkeletonRenderer's MeshRenderer is disabled while the SkeletonRenderSeparator takes over rendering. It is re-enabled when SkeletonRenderSeparator is disabled.", MessageType.Info); + + EditorGUILayout.PropertyField(copyPropertyBlock_); + EditorGUILayout.PropertyField(copyMeshRendererFlags_); + } + + // SkeletonRenderer Box + using (new SpineInspectorUtility.BoxScope(false)) { + // Fancy SkeletonRenderer foldout reference field + { + EditorGUI.indentLevel++; + EditorGUI.BeginChangeCheck(); + var foldoutSkeletonRendererRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(foldoutSkeletonRendererRect, skeletonRenderer_); + if (EditorGUI.EndChangeCheck()) + serializedObject.ApplyModifiedProperties(); + if (component.SkeletonRenderer != null) { + skeletonRendererExpanded = EditorGUI.Foldout(foldoutSkeletonRendererRect, skeletonRendererExpanded, ""); + } + EditorGUI.indentLevel--; + } + + int separatorCount = 0; + EditorGUI.BeginChangeCheck(); + if (component.SkeletonRenderer != null) { + // Separators from SkeletonRenderer + { + bool skeletonRendererMismatch = skeletonRendererSerializedObject != null && skeletonRendererSerializedObject.targetObject != component.SkeletonRenderer; + if (separatorNamesProp == null || skeletonRendererMismatch) { + if (component.SkeletonRenderer != null) { + skeletonRendererSerializedObject = new SerializedObject(component.SkeletonRenderer); + separatorNamesProp = skeletonRendererSerializedObject.FindProperty("separatorSlotNames"); + separatorNamesProp.isExpanded = true; + } + } + + if (separatorNamesProp != null) { + if (skeletonRendererExpanded) { + EditorGUI.indentLevel++; + SkeletonRendererInspector.SeparatorsField(separatorNamesProp); + EditorGUI.indentLevel--; + } + separatorCount = this.SkeletonRendererSeparatorCount; + } + } + + if (SkeletonRendererSeparatorCount == 0) { + EditorGUILayout.HelpBox("Separators are empty. Change the size to 1 and choose a slot if you want the render to be separated.", MessageType.Info); + } + } + + if (EditorGUI.EndChangeCheck()) { + skeletonRendererSerializedObject.ApplyModifiedProperties(); + + if (!Application.isPlaying) + slotsReapplyRequired = true; + } + + + totalParts = separatorCount + 1; + var counterStyle = skeletonRendererExpanded ? EditorStyles.label : EditorStyles.miniLabel; + EditorGUILayout.LabelField(string.Format("{0}: separates into {1}.", SpineInspectorUtility.Pluralize(separatorCount, "separator", "separators"), SpineInspectorUtility.Pluralize(totalParts, "part", "parts") ), counterStyle); + } + + // Parts renderers + using (new SpineInspectorUtility.BoxScope(false)) { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(this.partsRenderers_, true); + EditorGUI.indentLevel--; + + // Null items warning + bool nullItemsFound = componentRenderers.Contains(null); + if (nullItemsFound) + EditorGUILayout.HelpBox("Some items in the parts renderers list are null and may cause problems.\n\nYou can right-click on that element and choose 'Delete Array Element' to remove it.", MessageType.Warning); + + // (Button) Match Separators count + if (separatorNamesProp != null) { + int currentRenderers = 0; + foreach (var r in componentRenderers) { + if (r != null) + currentRenderers++; + } + int extraRenderersNeeded = totalParts - currentRenderers; + + if (component.enabled && component.SkeletonRenderer != null && extraRenderersNeeded > 0) { + EditorGUILayout.HelpBox(string.Format("Insufficient parts renderers. Some parts will not be rendered."), MessageType.Warning); + string addMissingLabel = string.Format("Add the missing renderer{1} ({0}) ", extraRenderersNeeded, SpineInspectorUtility.PluralThenS(extraRenderersNeeded)); + if (GUILayout.Button(addMissingLabel, GUILayout.Height(40f))) { + AddPartsRenderer(extraRenderersNeeded); + DetectOrphanedPartsRenderers(component); + } + } + } + + if (partsRenderers_.isExpanded != partsRenderersExpanded) partsRenderersExpanded = partsRenderers_.isExpanded; + if (partsRenderers_.isExpanded) { + using (new EditorGUILayout.HorizontalScope()) { + // (Button) Destroy Renderers button + if (componentRenderers.Count > 0) { + if (GUILayout.Button("Clear Parts Renderers")) { + // Do you really want to destroy all? + Undo.RegisterCompleteObjectUndo(component, "Clear Parts Renderers"); + if (EditorUtility.DisplayDialog("Destroy Renderers", "Do you really want to destroy all the Parts Renderer GameObjects in the list?", "Destroy", "Cancel")) { + foreach (var r in componentRenderers) { + if (r != null) + Undo.DestroyObjectImmediate(r.gameObject); + } + componentRenderers.Clear(); + // Do you also want to destroy orphans? (You monster.) + DetectOrphanedPartsRenderers(component); + } + } + } + + // (Button) Add Part Renderer button + if (GUILayout.Button("Add Parts Renderer")) + AddPartsRenderer(1); + } + } + } + + serializedObject.ApplyModifiedProperties(); + + if (slotsReapplyRequired && UnityEngine.Event.current.type == EventType.Repaint) { + SkeletonRendererInspector.ReapplySeparatorSlotNames(component.SkeletonRenderer); + component.SkeletonRenderer.LateUpdate(); + SceneView.RepaintAll(); + slotsReapplyRequired = false; + } + } + + public void AddPartsRenderer (int count) { + var componentRenderers = component.partsRenderers; + bool emptyFound = componentRenderers.Contains(null); + if (emptyFound) { + bool userClearEntries = EditorUtility.DisplayDialog("Empty entries found", "Null entries found. Do you want to remove null entries before adding the new renderer? ", "Clear Empty Entries", "Don't Clear"); + if (userClearEntries) componentRenderers.RemoveAll(x => x == null); + } + + Undo.RegisterCompleteObjectUndo(component, "Add Parts Renderers"); + for (int i = 0; i < count; i++) { + int index = componentRenderers.Count; + var smr = SkeletonPartsRenderer.NewPartsRendererGameObject(component.transform, index.ToString()); + Undo.RegisterCreatedObjectUndo(smr.gameObject, "New Parts Renderer GameObject."); + componentRenderers.Add(smr); + + // increment renderer sorting order. + if (index == 0) continue; + var prev = componentRenderers[index - 1]; if (prev == null) continue; + + var prevMeshRenderer = prev.GetComponent(); + var currentMeshRenderer = smr.GetComponent(); + if (prevMeshRenderer == null || currentMeshRenderer == null) continue; + + int prevSortingLayer = prevMeshRenderer.sortingLayerID; + int prevSortingOrder = prevMeshRenderer.sortingOrder; + currentMeshRenderer.sortingLayerID = prevSortingLayer; + currentMeshRenderer.sortingOrder = prevSortingOrder + SkeletonRenderSeparator.DefaultSortingOrderIncrement; + } + + } + + /// Detects orphaned parts renderers and offers to delete them. + public void DetectOrphanedPartsRenderers (SkeletonRenderSeparator component) { + var children = component.GetComponentsInChildren(); + + var orphans = new System.Collections.Generic.List(); + foreach (var r in children) { + if (!component.partsRenderers.Contains(r)) + orphans.Add(r); + } + + if (orphans.Count > 0) { + if (EditorUtility.DisplayDialog("Destroy Submesh Renderers", "Unassigned renderers were found. Do you want to delete them? (These may belong to another Render Separator in the same hierarchy. If you don't have another Render Separator component in the children of this GameObject, it's likely safe to delete. Warning: This operation cannot be undone.)", "Delete", "Cancel")) { + foreach (var o in orphans) { + Undo.DestroyObjectImmediate(o.gameObject); + } + } + } + } + + #region SkeletonRenderer Context Menu Item + [MenuItem ("CONTEXT/SkeletonRenderer/Add Skeleton Render Separator")] + static void AddRenderSeparatorComponent (MenuCommand cmd) { + var skeletonRenderer = cmd.context as SkeletonRenderer; + var newComponent = skeletonRenderer.gameObject.AddComponent(); + + Undo.RegisterCreatedObjectUndo(newComponent, "Add SkeletonRenderSeparator"); + } + + // Validate + [MenuItem ("CONTEXT/SkeletonRenderer/Add Skeleton Render Separator", true)] + static bool ValidateAddRenderSeparatorComponent (MenuCommand cmd) { + var skeletonRenderer = cmd.context as SkeletonRenderer; + var separator = skeletonRenderer.GetComponent(); + bool separatorNotOnObject = separator == null; + return separatorNotOnObject; + } + #endregion + + } +} diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonRenderSeparatorInspector.cs.meta diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes.meta new file mode 100644 index 000000000..34d8d7e02 --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 18ee2876d53412642bbfa1070a1b947f +folderAsset: yes +timeCreated: 1527569487 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Editor.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Editor.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/SlotBlendModes/Editor/SlotBlendModesEditor.cs.meta diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline.meta new file mode 100644 index 000000000..6c6b7ad4c --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b7ef9595ebe8c204a8a4f251a55d4d22 +folderAsset: yes +timeCreated: 1527569508 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/Editor.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor.meta similarity index 60% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/Editor.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor.meta index 198f69055..2198595bc 100644 --- a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/Editor.meta +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor.meta @@ -1,10 +1,9 @@ fileFormatVersion: 2 -guid: 54bc1978049774f4aa13bfd014a5773a +guid: 3cdbaf8cb2e511f4fa3b631af94fa18e folderAsset: yes -timeCreated: 1510816616 +timeCreated: 1527569538 licenseType: Free DefaultImporter: - externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/Editor/SpineAnimationStateDrawer.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor/SpineAnimationStateDrawer.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/Editor/SpineAnimationStateDrawer.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor/SpineAnimationStateDrawer.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/Editor/SpineAnimationStateDrawer.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor/SpineAnimationStateDrawer.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/Editor/SpineAnimationStateDrawer.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor/SpineAnimationStateDrawer.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/Editor/SpineSkeletonFlipDrawer.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor/SpineSkeletonFlipDrawer.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/Editor/SpineSkeletonFlipDrawer.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor/SpineSkeletonFlipDrawer.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/Editor/SpineSkeletonFlipDrawer.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor/SpineSkeletonFlipDrawer.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/Editor/SpineSkeletonFlipDrawer.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor/SpineSkeletonFlipDrawer.cs.meta diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility.meta b/spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility.meta new file mode 100644 index 000000000..66e5d621e --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 88e9a484884f9cb498c122a17ea0b4e5 +folderAsset: yes +timeCreated: 1527569561 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor.meta b/spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility/Editor.meta similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonUtility/Editor.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility/Editor.meta diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs.meta diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs rename to spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs.meta rename to spine-unity/Assets/Spine/Editor/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs.meta diff --git a/spine-unity/Assets/Spine/Runtime.meta b/spine-unity/Assets/Spine/Runtime.meta new file mode 100644 index 000000000..b6b0c1b12 --- /dev/null +++ b/spine-unity/Assets/Spine/Runtime.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ddb0e27aa2258854a8d171196f395b87 +folderAsset: yes +timeCreated: 1527569312 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/Spine/Runtime/spine-csharp.meta b/spine-unity/Assets/Spine/Runtime/spine-csharp.meta new file mode 100644 index 000000000..81ebc4e4d --- /dev/null +++ b/spine-unity/Assets/Spine/Runtime/spine-csharp.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a60dd41ef13d98647b9f963089feb7b0 +folderAsset: yes +timeCreated: 1456265151 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysMeshGenerator.cs b/spine-unity/Assets/Spine/Runtime/spine-csharp/add spine-csharp here.txt similarity index 100% rename from spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysMeshGenerator.cs rename to spine-unity/Assets/Spine/Runtime/spine-csharp/add spine-csharp here.txt diff --git a/spine-unity/Assets/spine-unity.meta b/spine-unity/Assets/Spine/Runtime/spine-unity.meta similarity index 100% rename from spine-unity/Assets/spine-unity.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity.meta diff --git a/spine-unity/Assets/spine-unity/Asset Types.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Asset Types.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types.meta diff --git a/spine-unity/Assets/spine-unity/Asset Types/AnimationReferenceAsset.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AnimationReferenceAsset.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Asset Types/AnimationReferenceAsset.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AnimationReferenceAsset.cs diff --git a/spine-unity/Assets/spine-unity/Asset Types/AnimationReferenceAsset.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AnimationReferenceAsset.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Asset Types/AnimationReferenceAsset.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AnimationReferenceAsset.cs.meta diff --git a/spine-unity/Assets/spine-unity/Asset Types/AtlasAsset.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAsset.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Asset Types/AtlasAsset.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAsset.cs index 80bc8f5e6..824e500f9 100644 --- a/spine-unity/Assets/spine-unity/Asset Types/AtlasAsset.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAsset.cs @@ -1,241 +1,241 @@ -/****************************************************************************** - * 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 System.Collections.Generic; -using System.IO; -using UnityEngine; -using Spine; - -namespace Spine.Unity { - /// Loads and stores a Spine atlas and list of materials. - public class AtlasAsset : ScriptableObject { - public TextAsset atlasFile; - public Material[] materials; - protected Atlas atlas; - - public bool IsLoaded { get { return this.atlas != null; } } - - #region Runtime Instantiation - /// - /// Creates a runtime AtlasAsset - public static AtlasAsset CreateRuntimeInstance (TextAsset atlasText, Material[] materials, bool initialize) { - AtlasAsset atlasAsset = ScriptableObject.CreateInstance(); - atlasAsset.Reset(); - atlasAsset.atlasFile = atlasText; - atlasAsset.materials = materials; - - if (initialize) - atlasAsset.GetAtlas(); - - return atlasAsset; - } - - /// - /// Creates a runtime AtlasAsset. Only providing the textures is slower because it has to search for atlas page matches. - public static AtlasAsset CreateRuntimeInstance (TextAsset atlasText, Texture2D[] textures, Material materialPropertySource, bool initialize) { - // Get atlas page names. - string atlasString = atlasText.text; - atlasString = atlasString.Replace("\r", ""); - string[] atlasLines = atlasString.Split('\n'); - var pages = new List(); - for (int i = 0; i < atlasLines.Length - 1; i++) { - if (atlasLines[i].Trim().Length == 0) - pages.Add(atlasLines[i + 1].Trim().Replace(".png", "")); - } - - // Populate Materials[] by matching texture names with page names. - var materials = new Material[pages.Count]; - for (int i = 0, n = pages.Count; i < n; i++) { - Material mat = null; - - // Search for a match. - string pageName = pages[i]; - for (int j = 0, m = textures.Length; j < m; j++) { - if (string.Equals(pageName, textures[j].name, System.StringComparison.OrdinalIgnoreCase)) { - // Match found. - mat = new Material(materialPropertySource); - mat.mainTexture = textures[j]; - break; - } - } - - if (mat != null) - materials[i] = mat; - else - throw new ArgumentException("Could not find matching atlas page in the texture array."); - } - - // Create AtlasAsset normally - return CreateRuntimeInstance(atlasText, materials, initialize); - } - - /// - /// Creates a runtime AtlasAsset. Only providing the textures is slower because it has to search for atlas page matches. - public static AtlasAsset CreateRuntimeInstance (TextAsset atlasText, Texture2D[] textures, Shader shader, bool initialize) { - if (shader == null) - shader = Shader.Find("Spine/Skeleton"); - - Material materialProperySource = new Material(shader); - var oa = CreateRuntimeInstance(atlasText, textures, materialProperySource, initialize); - - return oa; - } - #endregion - - void Reset () { - Clear(); - } - - public virtual void Clear () { - atlas = null; - } - - /// The atlas or null if it could not be loaded. - public virtual Atlas GetAtlas () { - if (atlasFile == null) { - Debug.LogError("Atlas file not set for atlas asset: " + name, this); - Clear(); - return null; - } - - if (materials == null || materials.Length == 0) { - Debug.LogError("Materials not set for atlas asset: " + name, this); - Clear(); - return null; - } - - if (atlas != null) return atlas; - - try { - atlas = new Atlas(new StringReader(atlasFile.text), "", new MaterialsTextureLoader(this)); - atlas.FlipV(); - return atlas; - } catch (Exception ex) { - Debug.LogError("Error reading atlas file for atlas asset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace, this); - return null; - } - } - - public Mesh GenerateMesh (string name, Mesh mesh, out Material material, float scale = 0.01f) { - AtlasRegion region = atlas.FindRegion(name); - material = null; - if (region != null) { - if (mesh == null) { - mesh = new Mesh(); - mesh.name = name; - } - - Vector3[] verts = new Vector3[4]; - Vector2[] uvs = new Vector2[4]; - Color[] colors = { Color.white, Color.white, Color.white, Color.white }; - int[] triangles = { 0, 1, 2, 2, 3, 0 }; - - float left, right, top, bottom; - left = region.width / -2f; - right = left * -1f; - top = region.height / 2f; - bottom = top * -1; - - verts[0] = new Vector3(left, bottom, 0) * scale; - verts[1] = new Vector3(left, top, 0) * scale; - verts[2] = new Vector3(right, top, 0) * scale; - verts[3] = new Vector3(right, bottom, 0) * scale; - float u, v, u2, v2; - u = region.u; - v = region.v; - u2 = region.u2; - v2 = region.v2; - - if (!region.rotate) { - uvs[0] = new Vector2(u, v2); - uvs[1] = new Vector2(u, v); - uvs[2] = new Vector2(u2, v); - uvs[3] = new Vector2(u2, v2); - } else { - uvs[0] = new Vector2(u2, v2); - uvs[1] = new Vector2(u, v2); - uvs[2] = new Vector2(u, v); - uvs[3] = new Vector2(u2, v); - } - - mesh.triangles = new int[0]; - mesh.vertices = verts; - mesh.uv = uvs; - mesh.colors = colors; - mesh.triangles = triangles; - mesh.RecalculateNormals(); - mesh.RecalculateBounds(); - - material = (Material)region.page.rendererObject; - } else { - mesh = null; - } - - return mesh; - } - } - - public class MaterialsTextureLoader : TextureLoader { - AtlasAsset atlasAsset; - - public MaterialsTextureLoader (AtlasAsset atlasAsset) { - this.atlasAsset = atlasAsset; - } - - public void Load (AtlasPage page, string path) { - String name = Path.GetFileNameWithoutExtension(path); - Material material = null; - foreach (Material other in atlasAsset.materials) { - if (other.mainTexture == null) { - Debug.LogError("Material is missing texture: " + other.name, other); - return; - } - if (other.mainTexture.name == name) { - material = other; - break; - } - } - if (material == null) { - Debug.LogError("Material with texture name \"" + name + "\" not found for atlas asset: " + atlasAsset.name, atlasAsset); - return; - } - page.rendererObject = material; - - // Very old atlas files expected the texture's actual size to be used at runtime. - if (page.width == 0 || page.height == 0) { - page.width = material.mainTexture.width; - page.height = material.mainTexture.height; - } - } - - public void Unload (object texture) { } - } -} +/****************************************************************************** + * 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 System.Collections.Generic; +using System.IO; +using UnityEngine; +using Spine; + +namespace Spine.Unity { + /// Loads and stores a Spine atlas and list of materials. + public class AtlasAsset : ScriptableObject { + public TextAsset atlasFile; + public Material[] materials; + protected Atlas atlas; + + public bool IsLoaded { get { return this.atlas != null; } } + + #region Runtime Instantiation + /// + /// Creates a runtime AtlasAsset + public static AtlasAsset CreateRuntimeInstance (TextAsset atlasText, Material[] materials, bool initialize) { + AtlasAsset atlasAsset = ScriptableObject.CreateInstance(); + atlasAsset.Reset(); + atlasAsset.atlasFile = atlasText; + atlasAsset.materials = materials; + + if (initialize) + atlasAsset.GetAtlas(); + + return atlasAsset; + } + + /// + /// Creates a runtime AtlasAsset. Only providing the textures is slower because it has to search for atlas page matches. + public static AtlasAsset CreateRuntimeInstance (TextAsset atlasText, Texture2D[] textures, Material materialPropertySource, bool initialize) { + // Get atlas page names. + string atlasString = atlasText.text; + atlasString = atlasString.Replace("\r", ""); + string[] atlasLines = atlasString.Split('\n'); + var pages = new List(); + for (int i = 0; i < atlasLines.Length - 1; i++) { + if (atlasLines[i].Trim().Length == 0) + pages.Add(atlasLines[i + 1].Trim().Replace(".png", "")); + } + + // Populate Materials[] by matching texture names with page names. + var materials = new Material[pages.Count]; + for (int i = 0, n = pages.Count; i < n; i++) { + Material mat = null; + + // Search for a match. + string pageName = pages[i]; + for (int j = 0, m = textures.Length; j < m; j++) { + if (string.Equals(pageName, textures[j].name, System.StringComparison.OrdinalIgnoreCase)) { + // Match found. + mat = new Material(materialPropertySource); + mat.mainTexture = textures[j]; + break; + } + } + + if (mat != null) + materials[i] = mat; + else + throw new ArgumentException("Could not find matching atlas page in the texture array."); + } + + // Create AtlasAsset normally + return CreateRuntimeInstance(atlasText, materials, initialize); + } + + /// + /// Creates a runtime AtlasAsset. Only providing the textures is slower because it has to search for atlas page matches. + public static AtlasAsset CreateRuntimeInstance (TextAsset atlasText, Texture2D[] textures, Shader shader, bool initialize) { + if (shader == null) + shader = Shader.Find("Spine/Skeleton"); + + Material materialProperySource = new Material(shader); + var oa = CreateRuntimeInstance(atlasText, textures, materialProperySource, initialize); + + return oa; + } + #endregion + + void Reset () { + Clear(); + } + + public virtual void Clear () { + atlas = null; + } + + /// The atlas or null if it could not be loaded. + public virtual Atlas GetAtlas () { + if (atlasFile == null) { + Debug.LogError("Atlas file not set for atlas asset: " + name, this); + Clear(); + return null; + } + + if (materials == null || materials.Length == 0) { + Debug.LogError("Materials not set for atlas asset: " + name, this); + Clear(); + return null; + } + + if (atlas != null) return atlas; + + try { + atlas = new Atlas(new StringReader(atlasFile.text), "", new MaterialsTextureLoader(this)); + atlas.FlipV(); + return atlas; + } catch (Exception ex) { + Debug.LogError("Error reading atlas file for atlas asset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace, this); + return null; + } + } + + public Mesh GenerateMesh (string name, Mesh mesh, out Material material, float scale = 0.01f) { + AtlasRegion region = atlas.FindRegion(name); + material = null; + if (region != null) { + if (mesh == null) { + mesh = new Mesh(); + mesh.name = name; + } + + Vector3[] verts = new Vector3[4]; + Vector2[] uvs = new Vector2[4]; + Color[] colors = { Color.white, Color.white, Color.white, Color.white }; + int[] triangles = { 0, 1, 2, 2, 3, 0 }; + + float left, right, top, bottom; + left = region.width / -2f; + right = left * -1f; + top = region.height / 2f; + bottom = top * -1; + + verts[0] = new Vector3(left, bottom, 0) * scale; + verts[1] = new Vector3(left, top, 0) * scale; + verts[2] = new Vector3(right, top, 0) * scale; + verts[3] = new Vector3(right, bottom, 0) * scale; + float u, v, u2, v2; + u = region.u; + v = region.v; + u2 = region.u2; + v2 = region.v2; + + if (!region.rotate) { + uvs[0] = new Vector2(u, v2); + uvs[1] = new Vector2(u, v); + uvs[2] = new Vector2(u2, v); + uvs[3] = new Vector2(u2, v2); + } else { + uvs[0] = new Vector2(u2, v2); + uvs[1] = new Vector2(u, v2); + uvs[2] = new Vector2(u, v); + uvs[3] = new Vector2(u2, v); + } + + mesh.triangles = new int[0]; + mesh.vertices = verts; + mesh.uv = uvs; + mesh.colors = colors; + mesh.triangles = triangles; + mesh.RecalculateNormals(); + mesh.RecalculateBounds(); + + material = (Material)region.page.rendererObject; + } else { + mesh = null; + } + + return mesh; + } + } + + public class MaterialsTextureLoader : TextureLoader { + AtlasAsset atlasAsset; + + public MaterialsTextureLoader (AtlasAsset atlasAsset) { + this.atlasAsset = atlasAsset; + } + + public void Load (AtlasPage page, string path) { + String name = Path.GetFileNameWithoutExtension(path); + Material material = null; + foreach (Material other in atlasAsset.materials) { + if (other.mainTexture == null) { + Debug.LogError("Material is missing texture: " + other.name, other); + return; + } + if (other.mainTexture.name == name) { + material = other; + break; + } + } + if (material == null) { + Debug.LogError("Material with texture name \"" + name + "\" not found for atlas asset: " + atlasAsset.name, atlasAsset); + return; + } + page.rendererObject = material; + + // Very old atlas files expected the texture's actual size to be used at runtime. + if (page.width == 0 || page.height == 0) { + page.width = material.mainTexture.width; + page.height = material.mainTexture.height; + } + } + + public void Unload (object texture) { } + } +} diff --git a/spine-unity/Assets/spine-unity/Asset Types/AtlasAsset.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAsset.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Asset Types/AtlasAsset.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/AtlasAsset.cs.meta diff --git a/spine-unity/Assets/spine-unity/Asset Types/EventDataReferenceAsset.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/EventDataReferenceAsset.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Asset Types/EventDataReferenceAsset.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/EventDataReferenceAsset.cs diff --git a/spine-unity/Assets/spine-unity/Asset Types/EventDataReferenceAsset.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/EventDataReferenceAsset.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Asset Types/EventDataReferenceAsset.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/EventDataReferenceAsset.cs.meta diff --git a/spine-unity/Assets/spine-unity/Asset Types/RegionlessAttachmentLoader.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/RegionlessAttachmentLoader.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Asset Types/RegionlessAttachmentLoader.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/RegionlessAttachmentLoader.cs diff --git a/spine-unity/Assets/spine-unity/Asset Types/RegionlessAttachmentLoader.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/RegionlessAttachmentLoader.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Asset Types/RegionlessAttachmentLoader.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/RegionlessAttachmentLoader.cs.meta diff --git a/spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs index 66b0cd97c..8891ee3b8 100644 --- a/spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs @@ -1,221 +1,221 @@ -/****************************************************************************** - * 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 System.IO; -using UnityEngine; -using Spine; - -namespace Spine.Unity { - public class SkeletonDataAsset : ScriptableObject { - #region Inspector - public AtlasAsset[] atlasAssets = new AtlasAsset[0]; - #if SPINE_TK2D - public tk2dSpriteCollectionData spriteCollection; - public float scale = 1f; - #else - public float scale = 0.01f; - #endif - public TextAsset skeletonJSON; - [SpineAnimation(includeNone: false)] - public string[] fromAnimation = new string[0]; - [SpineAnimation(includeNone: false)] - public string[] toAnimation = new string[0]; - public float[] duration = new float[0]; - public float defaultMix; - public RuntimeAnimatorController controller; - - public bool IsLoaded { get { return this.skeletonData != null; } } - - void Reset () { - Clear(); - } - #endregion - - SkeletonData skeletonData; - AnimationStateData stateData; - - #region Runtime Instantiation - /// - /// Creates a runtime SkeletonDataAsset. - public static SkeletonDataAsset CreateRuntimeInstance (TextAsset skeletonDataFile, AtlasAsset atlasAsset, bool initialize, float scale = 0.01f) { - return CreateRuntimeInstance(skeletonDataFile, new [] {atlasAsset}, initialize, scale); - } - - /// - /// Creates a runtime SkeletonDataAsset. - public static SkeletonDataAsset CreateRuntimeInstance (TextAsset skeletonDataFile, AtlasAsset[] atlasAssets, bool initialize, float scale = 0.01f) { - SkeletonDataAsset skeletonDataAsset = ScriptableObject.CreateInstance(); - skeletonDataAsset.Clear(); - skeletonDataAsset.skeletonJSON = skeletonDataFile; - skeletonDataAsset.atlasAssets = atlasAssets; - skeletonDataAsset.scale = scale; - - if (initialize) - skeletonDataAsset.GetSkeletonData(true); - - return skeletonDataAsset; - } - #endregion - - public void Clear () { - skeletonData = null; - stateData = null; - } - - public SkeletonData GetSkeletonData (bool quiet) { - if (skeletonJSON == null) { - if (!quiet) - Debug.LogError("Skeleton JSON file not set for SkeletonData asset: " + name, this); - Clear(); - return null; - } - - // Disabled to support attachmentless/skinless SkeletonData. -// if (atlasAssets == null) { -// atlasAssets = new AtlasAsset[0]; -// if (!quiet) -// Debug.LogError("Atlas not set for SkeletonData asset: " + name, this); -// Clear(); -// return null; -// } -// #if !SPINE_TK2D -// if (atlasAssets.Length == 0) { -// Clear(); -// return null; -// } -// #else -// if (atlasAssets.Length == 0 && spriteCollection == null) { -// Clear(); -// return null; -// } -// #endif - - if (skeletonData != null) - return skeletonData; - - AttachmentLoader attachmentLoader; - float skeletonDataScale; - Atlas[] atlasArray = this.GetAtlasArray(); - - #if !SPINE_TK2D - attachmentLoader = (atlasArray.Length == 0) ? (AttachmentLoader)new RegionlessAttachmentLoader() : (AttachmentLoader)new AtlasAttachmentLoader(atlasArray); - skeletonDataScale = scale; - #else - if (spriteCollection != null) { - attachmentLoader = new Spine.Unity.TK2D.SpriteCollectionAttachmentLoader(spriteCollection); - skeletonDataScale = (1.0f / (spriteCollection.invOrthoSize * spriteCollection.halfTargetHeight) * scale); - } else { - if (atlasArray.Length == 0) { - Reset(); - if (!quiet) Debug.LogError("Atlas not set for SkeletonData asset: " + name, this); - return null; - } - attachmentLoader = new AtlasAttachmentLoader(atlasArray); - skeletonDataScale = scale; - } - #endif - - bool isBinary = skeletonJSON.name.ToLower().Contains(".skel"); - SkeletonData loadedSkeletonData; - - try { - if (isBinary) - loadedSkeletonData = SkeletonDataAsset.ReadSkeletonData(skeletonJSON.bytes, attachmentLoader, skeletonDataScale); - else - loadedSkeletonData = SkeletonDataAsset.ReadSkeletonData(skeletonJSON.text, attachmentLoader, skeletonDataScale); - - } catch (Exception ex) { - if (!quiet) - Debug.LogError("Error reading skeleton JSON file for SkeletonData asset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace, this); - return null; - - } - - this.InitializeWithData(loadedSkeletonData); - - return skeletonData; - } - - internal void InitializeWithData (SkeletonData sd) { - this.skeletonData = sd; - this.stateData = new AnimationStateData(skeletonData); - FillStateData(); - } - - internal Atlas[] GetAtlasArray () { - var returnList = new System.Collections.Generic.List(atlasAssets.Length); - for (int i = 0; i < atlasAssets.Length; i++) { - var aa = atlasAssets[i]; - if (aa == null) continue; - var a = aa.GetAtlas(); - if (a == null) continue; - returnList.Add(a); - } - return returnList.ToArray(); - } - - internal static SkeletonData ReadSkeletonData (byte[] bytes, AttachmentLoader attachmentLoader, float scale) { - var input = new MemoryStream(bytes); - var binary = new SkeletonBinary(attachmentLoader) { - Scale = scale - }; - return binary.ReadSkeletonData(input); - } - - internal static SkeletonData ReadSkeletonData (string text, AttachmentLoader attachmentLoader, float scale) { - var input = new StringReader(text); - var json = new SkeletonJson(attachmentLoader) { - Scale = scale - }; - return json.ReadSkeletonData(input); - } - - public void FillStateData () { - if (stateData != null) { - stateData.defaultMix = defaultMix; - - for (int i = 0, n = fromAnimation.Length; i < n; i++) { - if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0) - continue; - stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]); - } - } - } - - public AnimationStateData GetAnimationStateData () { - if (stateData != null) - return stateData; - GetSkeletonData(false); - return stateData; - } - } - -} +/****************************************************************************** + * 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 System.IO; +using UnityEngine; +using Spine; + +namespace Spine.Unity { + public class SkeletonDataAsset : ScriptableObject { + #region Inspector + public AtlasAsset[] atlasAssets = new AtlasAsset[0]; + #if SPINE_TK2D + public tk2dSpriteCollectionData spriteCollection; + public float scale = 1f; + #else + public float scale = 0.01f; + #endif + public TextAsset skeletonJSON; + [SpineAnimation(includeNone: false)] + public string[] fromAnimation = new string[0]; + [SpineAnimation(includeNone: false)] + public string[] toAnimation = new string[0]; + public float[] duration = new float[0]; + public float defaultMix; + public RuntimeAnimatorController controller; + + public bool IsLoaded { get { return this.skeletonData != null; } } + + void Reset () { + Clear(); + } + #endregion + + SkeletonData skeletonData; + AnimationStateData stateData; + + #region Runtime Instantiation + /// + /// Creates a runtime SkeletonDataAsset. + public static SkeletonDataAsset CreateRuntimeInstance (TextAsset skeletonDataFile, AtlasAsset atlasAsset, bool initialize, float scale = 0.01f) { + return CreateRuntimeInstance(skeletonDataFile, new [] {atlasAsset}, initialize, scale); + } + + /// + /// Creates a runtime SkeletonDataAsset. + public static SkeletonDataAsset CreateRuntimeInstance (TextAsset skeletonDataFile, AtlasAsset[] atlasAssets, bool initialize, float scale = 0.01f) { + SkeletonDataAsset skeletonDataAsset = ScriptableObject.CreateInstance(); + skeletonDataAsset.Clear(); + skeletonDataAsset.skeletonJSON = skeletonDataFile; + skeletonDataAsset.atlasAssets = atlasAssets; + skeletonDataAsset.scale = scale; + + if (initialize) + skeletonDataAsset.GetSkeletonData(true); + + return skeletonDataAsset; + } + #endregion + + public void Clear () { + skeletonData = null; + stateData = null; + } + + public SkeletonData GetSkeletonData (bool quiet) { + if (skeletonJSON == null) { + if (!quiet) + Debug.LogError("Skeleton JSON file not set for SkeletonData asset: " + name, this); + Clear(); + return null; + } + + // Disabled to support attachmentless/skinless SkeletonData. +// if (atlasAssets == null) { +// atlasAssets = new AtlasAsset[0]; +// if (!quiet) +// Debug.LogError("Atlas not set for SkeletonData asset: " + name, this); +// Clear(); +// return null; +// } +// #if !SPINE_TK2D +// if (atlasAssets.Length == 0) { +// Clear(); +// return null; +// } +// #else +// if (atlasAssets.Length == 0 && spriteCollection == null) { +// Clear(); +// return null; +// } +// #endif + + if (skeletonData != null) + return skeletonData; + + AttachmentLoader attachmentLoader; + float skeletonDataScale; + Atlas[] atlasArray = this.GetAtlasArray(); + + #if !SPINE_TK2D + attachmentLoader = (atlasArray.Length == 0) ? (AttachmentLoader)new RegionlessAttachmentLoader() : (AttachmentLoader)new AtlasAttachmentLoader(atlasArray); + skeletonDataScale = scale; + #else + if (spriteCollection != null) { + attachmentLoader = new Spine.Unity.TK2D.SpriteCollectionAttachmentLoader(spriteCollection); + skeletonDataScale = (1.0f / (spriteCollection.invOrthoSize * spriteCollection.halfTargetHeight) * scale); + } else { + if (atlasArray.Length == 0) { + Reset(); + if (!quiet) Debug.LogError("Atlas not set for SkeletonData asset: " + name, this); + return null; + } + attachmentLoader = new AtlasAttachmentLoader(atlasArray); + skeletonDataScale = scale; + } + #endif + + bool isBinary = skeletonJSON.name.ToLower().Contains(".skel"); + SkeletonData loadedSkeletonData; + + try { + if (isBinary) + loadedSkeletonData = SkeletonDataAsset.ReadSkeletonData(skeletonJSON.bytes, attachmentLoader, skeletonDataScale); + else + loadedSkeletonData = SkeletonDataAsset.ReadSkeletonData(skeletonJSON.text, attachmentLoader, skeletonDataScale); + + } catch (Exception ex) { + if (!quiet) + Debug.LogError("Error reading skeleton JSON file for SkeletonData asset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace, this); + return null; + + } + + this.InitializeWithData(loadedSkeletonData); + + return skeletonData; + } + + internal void InitializeWithData (SkeletonData sd) { + this.skeletonData = sd; + this.stateData = new AnimationStateData(skeletonData); + FillStateData(); + } + + internal Atlas[] GetAtlasArray () { + var returnList = new System.Collections.Generic.List(atlasAssets.Length); + for (int i = 0; i < atlasAssets.Length; i++) { + var aa = atlasAssets[i]; + if (aa == null) continue; + var a = aa.GetAtlas(); + if (a == null) continue; + returnList.Add(a); + } + return returnList.ToArray(); + } + + internal static SkeletonData ReadSkeletonData (byte[] bytes, AttachmentLoader attachmentLoader, float scale) { + var input = new MemoryStream(bytes); + var binary = new SkeletonBinary(attachmentLoader) { + Scale = scale + }; + return binary.ReadSkeletonData(input); + } + + internal static SkeletonData ReadSkeletonData (string text, AttachmentLoader attachmentLoader, float scale) { + var input = new StringReader(text); + var json = new SkeletonJson(attachmentLoader) { + Scale = scale + }; + return json.ReadSkeletonData(input); + } + + public void FillStateData () { + if (stateData != null) { + stateData.defaultMix = defaultMix; + + for (int i = 0, n = fromAnimation.Length; i < n; i++) { + if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0) + continue; + stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]); + } + } + } + + public AnimationStateData GetAnimationStateData () { + if (stateData != null) + return stateData; + GetSkeletonData(false); + return stateData; + } + } + +} diff --git a/spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs.meta diff --git a/spine-unity/Assets/spine-unity/Components.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Components.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Components.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Components.meta diff --git a/spine-unity/Assets/spine-unity/Components/BoneFollower.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/BoneFollower.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Components/BoneFollower.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Components/BoneFollower.cs diff --git a/spine-unity/Assets/spine-unity/Components/BoneFollower.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/BoneFollower.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Components/BoneFollower.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Components/BoneFollower.cs.meta diff --git a/spine-unity/Assets/spine-unity/Components/PointFollower.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/PointFollower.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Components/PointFollower.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Components/PointFollower.cs diff --git a/spine-unity/Assets/spine-unity/Components/PointFollower.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/PointFollower.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Components/PointFollower.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Components/PointFollower.cs.meta diff --git a/spine-unity/Assets/spine-unity/Components/SkeletonAnimation.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Components/SkeletonAnimation.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs diff --git a/spine-unity/Assets/spine-unity/Components/SkeletonAnimation.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Components/SkeletonAnimation.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs.meta diff --git a/spine-unity/Assets/spine-unity/Components/SkeletonAnimator.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimator.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Components/SkeletonAnimator.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimator.cs diff --git a/spine-unity/Assets/spine-unity/Components/SkeletonAnimator.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimator.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Components/SkeletonAnimator.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimator.cs.meta diff --git a/spine-unity/Assets/spine-unity/Components/SkeletonRenderer.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Components/SkeletonRenderer.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs diff --git a/spine-unity/Assets/spine-unity/Components/SkeletonRenderer.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Components/SkeletonRenderer.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs.meta diff --git a/spine-unity/Assets/spine-unity/ISkeletonAnimation.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs similarity index 98% rename from spine-unity/Assets/spine-unity/ISkeletonAnimation.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs index bf31e878f..d1ab2ffcb 100644 --- a/spine-unity/Assets/spine-unity/ISkeletonAnimation.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs @@ -1,75 +1,75 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -namespace Spine.Unity { - public delegate void UpdateBonesDelegate (ISkeletonAnimation animated); - - /// A Spine-Unity Component that animates a Skeleton but not necessarily with a Spine.AnimationState. - public interface ISkeletonAnimation { - event UpdateBonesDelegate UpdateLocal; - event UpdateBonesDelegate UpdateWorld; - event UpdateBonesDelegate UpdateComplete; - - //void LateUpdate (); - Skeleton Skeleton { get; } - } - - /// Holds a reference to a SkeletonDataAsset. - public interface IHasSkeletonDataAsset { - /// Gets the SkeletonDataAsset of the Spine Component. - SkeletonDataAsset SkeletonDataAsset { get; } - } - - /// A Spine-Unity Component that manages a Spine.Skeleton instance, instantiated from a SkeletonDataAsset. - public interface ISkeletonComponent { - /// Gets the SkeletonDataAsset of the Spine Component. - //[System.Obsolete] - SkeletonDataAsset SkeletonDataAsset { get; } - - /// Gets the Spine.Skeleton instance of the Spine Component. This is equivalent to SkeletonRenderer's .skeleton. - Skeleton Skeleton { get; } - } - - /// A Spine-Unity Component that uses a Spine.AnimationState to animate its skeleton. - public interface IAnimationStateComponent { - /// Gets the Spine.AnimationState of the animated Spine Component. This is equivalent to SkeletonAnimation.state. - AnimationState AnimationState { get; } - } - - /// A Spine-Unity Component that holds a reference to a SkeletonRenderer. - public interface IHasSkeletonRenderer { - SkeletonRenderer SkeletonRenderer { get; } - } - - /// A Spine-Unity Component that holds a reference to an ISkeletonComponent. - public interface IHasSkeletonComponent { - ISkeletonComponent SkeletonComponent { get; } - } -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +namespace Spine.Unity { + public delegate void UpdateBonesDelegate (ISkeletonAnimation animated); + + /// A Spine-Unity Component that animates a Skeleton but not necessarily with a Spine.AnimationState. + public interface ISkeletonAnimation { + event UpdateBonesDelegate UpdateLocal; + event UpdateBonesDelegate UpdateWorld; + event UpdateBonesDelegate UpdateComplete; + + //void LateUpdate (); + Skeleton Skeleton { get; } + } + + /// Holds a reference to a SkeletonDataAsset. + public interface IHasSkeletonDataAsset { + /// Gets the SkeletonDataAsset of the Spine Component. + SkeletonDataAsset SkeletonDataAsset { get; } + } + + /// A Spine-Unity Component that manages a Spine.Skeleton instance, instantiated from a SkeletonDataAsset. + public interface ISkeletonComponent { + /// Gets the SkeletonDataAsset of the Spine Component. + //[System.Obsolete] + SkeletonDataAsset SkeletonDataAsset { get; } + + /// Gets the Spine.Skeleton instance of the Spine Component. This is equivalent to SkeletonRenderer's .skeleton. + Skeleton Skeleton { get; } + } + + /// A Spine-Unity Component that uses a Spine.AnimationState to animate its skeleton. + public interface IAnimationStateComponent { + /// Gets the Spine.AnimationState of the animated Spine Component. This is equivalent to SkeletonAnimation.state. + AnimationState AnimationState { get; } + } + + /// A Spine-Unity Component that holds a reference to a SkeletonRenderer. + public interface IHasSkeletonRenderer { + SkeletonRenderer SkeletonRenderer { get; } + } + + /// A Spine-Unity Component that holds a reference to an ISkeletonComponent. + public interface IHasSkeletonComponent { + ISkeletonComponent SkeletonComponent { get; } + } +} diff --git a/spine-unity/Assets/spine-unity/ISkeletonAnimation.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/ISkeletonAnimation.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs.meta diff --git a/spine-unity/Assets/spine-unity/Mesh Generation.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Mesh Generation.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation.meta diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/DoubleBuffered.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/DoubleBuffered.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Mesh Generation/DoubleBuffered.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/DoubleBuffered.cs index 0a674387c..c4dea808b 100644 --- a/spine-unity/Assets/spine-unity/Mesh Generation/DoubleBuffered.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/DoubleBuffered.cs @@ -1,46 +1,46 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -namespace Spine.Unity { - public class DoubleBuffered where T : new() { - readonly T a = new T(); - readonly T b = new T(); - bool usingA; - - public T GetCurrent () { - return usingA ? a : b; - } - - public T GetNext () { - usingA = !usingA; - return usingA ? a : b; - } - } -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +namespace Spine.Unity { + public class DoubleBuffered where T : new() { + readonly T a = new T(); + readonly T b = new T(); + bool usingA; + + public T GetCurrent () { + return usingA ? a : b; + } + + public T GetNext () { + usingA = !usingA; + return usingA ? a : b; + } + } +} diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/DoubleBuffered.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/DoubleBuffered.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Mesh Generation/DoubleBuffered.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/DoubleBuffered.cs.meta diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules.meta diff --git a/spine-unity/Assets/spine-unity/Modules/AttachmentTools.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/AttachmentTools.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools.meta diff --git a/spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs diff --git a/spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/BoundingBoxFollower.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/BoundingBoxFollower.meta diff --git a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs index 00e74d18b..54df52ea0 100644 --- a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs @@ -1,240 +1,240 @@ -/****************************************************************************** - * 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 UnityEngine; -using System.Collections.Generic; - -namespace Spine.Unity { - - [ExecuteInEditMode] - public class BoundingBoxFollower : MonoBehaviour { - internal static bool DebugMessages = true; - - #region Inspector - public SkeletonRenderer skeletonRenderer; - [SpineSlot(dataField: "skeletonRenderer", containsBoundingBoxes: true)] - public string slotName; - public bool isTrigger; - public bool clearStateOnDisable = true; - #endregion - - Slot slot; - BoundingBoxAttachment currentAttachment; - string currentAttachmentName; - PolygonCollider2D currentCollider; - - public readonly Dictionary colliderTable = new Dictionary(); - public readonly Dictionary nameTable = new Dictionary(); - - public Slot Slot { get { return slot; } } - public BoundingBoxAttachment CurrentAttachment { get { return currentAttachment; } } - public string CurrentAttachmentName { get { return currentAttachmentName; } } - public PolygonCollider2D CurrentCollider { get { return currentCollider; } } - public bool IsTrigger { get { return isTrigger; } } - - void Start () { - Initialize(); - } - - void OnEnable () { - if (skeletonRenderer != null) { - skeletonRenderer.OnRebuild -= HandleRebuild; - skeletonRenderer.OnRebuild += HandleRebuild; - } - - Initialize(); - } - - void HandleRebuild (SkeletonRenderer sr) { - //if (BoundingBoxFollower.DebugMessages) Debug.Log("Skeleton was rebuilt. Repopulating BoundingBoxFollower."); - Initialize(); - } - - /// - /// Initialize and instantiate the BoundingBoxFollower colliders. This is method checks if the BoundingBoxFollower has already been initialized for the skeleton instance and slotName and prevents overwriting unless it detects a new setup. - public void Initialize (bool overwrite = false) { - if (skeletonRenderer == null) - return; - - skeletonRenderer.Initialize(false); - - if (string.IsNullOrEmpty(slotName)) - return; - - // Don't reinitialize if the setup did not change. - if (!overwrite - && - colliderTable.Count > 0 && slot != null // Slot is set and colliders already populated. - && - skeletonRenderer.skeleton == slot.Skeleton // Skeleton object did not change. - && - slotName == slot.data.name // Slot object did not change. - ) - return; - - DisposeColliders(); - - var skeleton = skeletonRenderer.skeleton; - slot = skeleton.FindSlot(slotName); - int slotIndex = skeleton.FindSlotIndex(slotName); - - if (slot == null) { - if (BoundingBoxFollower.DebugMessages) - Debug.LogWarning(string.Format("Slot '{0}' not found for BoundingBoxFollower on '{1}'. (Previous colliders were disposed.)", slotName, this.gameObject.name)); - return; - } - - if (this.gameObject.activeInHierarchy) { - foreach (var skin in skeleton.Data.Skins) - AddSkin(skin, slotIndex); - - if (skeleton.skin != null) - AddSkin(skeleton.skin, slotIndex); - } - - if (BoundingBoxFollower.DebugMessages) { - bool valid = colliderTable.Count != 0; - if (!valid) { - if (this.gameObject.activeInHierarchy) - Debug.LogWarning("Bounding Box Follower not valid! Slot [" + slotName + "] does not contain any Bounding Box Attachments!"); - else - Debug.LogWarning("Bounding Box Follower tried to rebuild as a prefab."); - } - } - } - - void AddSkin (Skin skin, int slotIndex) { - if (skin == null) return; - var attachmentNames = new List(); - skin.FindNamesForSlot(slotIndex, attachmentNames); - - foreach (var skinKey in attachmentNames) { - var attachment = skin.GetAttachment(slotIndex, skinKey); - var boundingBoxAttachment = attachment as BoundingBoxAttachment; - - if (BoundingBoxFollower.DebugMessages && attachment != null && boundingBoxAttachment == null) - Debug.Log("BoundingBoxFollower tried to follow a slot that contains non-boundingbox attachments: " + slotName); - - if (boundingBoxAttachment != null) { - if (!colliderTable.ContainsKey(boundingBoxAttachment)) { - var bbCollider = SkeletonUtility.AddBoundingBoxAsComponent(boundingBoxAttachment, slot, gameObject, isTrigger); - bbCollider.enabled = false; - bbCollider.hideFlags = HideFlags.NotEditable; - bbCollider.isTrigger = IsTrigger; - colliderTable.Add(boundingBoxAttachment, bbCollider); - nameTable.Add(boundingBoxAttachment, skinKey); - } - } - } - } - - void OnDisable () { - if (clearStateOnDisable) - ClearState(); - } - - public void ClearState () { - if (colliderTable != null) - foreach (var col in colliderTable.Values) - col.enabled = false; - - currentAttachment = null; - currentAttachmentName = null; - currentCollider = null; - } - - void DisposeColliders () { - var colliders = GetComponents(); - if (colliders.Length == 0) return; - - if (Application.isEditor) { - if (Application.isPlaying) { - foreach (var c in colliders) { - if (c != null) - Destroy(c); - } - } else { - foreach (var c in colliders) - if (c != null) - DestroyImmediate(c); - } - } else { - foreach (PolygonCollider2D c in colliders) - if (c != null) - Destroy(c); - } - - slot = null; - currentAttachment = null; - currentAttachmentName = null; - currentCollider = null; - colliderTable.Clear(); - nameTable.Clear(); - } - - void LateUpdate () { - if (slot != null && slot.Attachment != currentAttachment) - MatchAttachment(slot.Attachment); - } - - /// Sets the current collider to match attachment. - /// If the attachment is not a bounding box, it will be treated as null. - void MatchAttachment (Attachment attachment) { - var bbAttachment = attachment as BoundingBoxAttachment; - - if (BoundingBoxFollower.DebugMessages && attachment != null && bbAttachment == null) - Debug.LogWarning("BoundingBoxFollower tried to match a non-boundingbox attachment. It will treat it as null."); - - if (currentCollider != null) - currentCollider.enabled = false; - - if (bbAttachment == null) { - currentCollider = null; - currentAttachment = null; - currentAttachmentName = null; - } else { - PolygonCollider2D foundCollider; - colliderTable.TryGetValue(bbAttachment, out foundCollider); - if (foundCollider != null) { - currentCollider = foundCollider; - currentCollider.enabled = true; - currentAttachment = bbAttachment; - currentAttachmentName = nameTable[bbAttachment]; - } else { - currentCollider = null; - currentAttachment = bbAttachment; - currentAttachmentName = null; - if (BoundingBoxFollower.DebugMessages) Debug.LogFormat("Collider for BoundingBoxAttachment named '{0}' was not initialized. It is possibly from a new skin. currentAttachmentName will be null. You may need to call BoundingBoxFollower.Initialize(overwrite: true);", bbAttachment.Name); - } - } - } - } - -} +/****************************************************************************** + * 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 UnityEngine; +using System.Collections.Generic; + +namespace Spine.Unity { + + [ExecuteInEditMode] + public class BoundingBoxFollower : MonoBehaviour { + internal static bool DebugMessages = true; + + #region Inspector + public SkeletonRenderer skeletonRenderer; + [SpineSlot(dataField: "skeletonRenderer", containsBoundingBoxes: true)] + public string slotName; + public bool isTrigger; + public bool clearStateOnDisable = true; + #endregion + + Slot slot; + BoundingBoxAttachment currentAttachment; + string currentAttachmentName; + PolygonCollider2D currentCollider; + + public readonly Dictionary colliderTable = new Dictionary(); + public readonly Dictionary nameTable = new Dictionary(); + + public Slot Slot { get { return slot; } } + public BoundingBoxAttachment CurrentAttachment { get { return currentAttachment; } } + public string CurrentAttachmentName { get { return currentAttachmentName; } } + public PolygonCollider2D CurrentCollider { get { return currentCollider; } } + public bool IsTrigger { get { return isTrigger; } } + + void Start () { + Initialize(); + } + + void OnEnable () { + if (skeletonRenderer != null) { + skeletonRenderer.OnRebuild -= HandleRebuild; + skeletonRenderer.OnRebuild += HandleRebuild; + } + + Initialize(); + } + + void HandleRebuild (SkeletonRenderer sr) { + //if (BoundingBoxFollower.DebugMessages) Debug.Log("Skeleton was rebuilt. Repopulating BoundingBoxFollower."); + Initialize(); + } + + /// + /// Initialize and instantiate the BoundingBoxFollower colliders. This is method checks if the BoundingBoxFollower has already been initialized for the skeleton instance and slotName and prevents overwriting unless it detects a new setup. + public void Initialize (bool overwrite = false) { + if (skeletonRenderer == null) + return; + + skeletonRenderer.Initialize(false); + + if (string.IsNullOrEmpty(slotName)) + return; + + // Don't reinitialize if the setup did not change. + if (!overwrite + && + colliderTable.Count > 0 && slot != null // Slot is set and colliders already populated. + && + skeletonRenderer.skeleton == slot.Skeleton // Skeleton object did not change. + && + slotName == slot.data.name // Slot object did not change. + ) + return; + + DisposeColliders(); + + var skeleton = skeletonRenderer.skeleton; + slot = skeleton.FindSlot(slotName); + int slotIndex = skeleton.FindSlotIndex(slotName); + + if (slot == null) { + if (BoundingBoxFollower.DebugMessages) + Debug.LogWarning(string.Format("Slot '{0}' not found for BoundingBoxFollower on '{1}'. (Previous colliders were disposed.)", slotName, this.gameObject.name)); + return; + } + + if (this.gameObject.activeInHierarchy) { + foreach (var skin in skeleton.Data.Skins) + AddSkin(skin, slotIndex); + + if (skeleton.skin != null) + AddSkin(skeleton.skin, slotIndex); + } + + if (BoundingBoxFollower.DebugMessages) { + bool valid = colliderTable.Count != 0; + if (!valid) { + if (this.gameObject.activeInHierarchy) + Debug.LogWarning("Bounding Box Follower not valid! Slot [" + slotName + "] does not contain any Bounding Box Attachments!"); + else + Debug.LogWarning("Bounding Box Follower tried to rebuild as a prefab."); + } + } + } + + void AddSkin (Skin skin, int slotIndex) { + if (skin == null) return; + var attachmentNames = new List(); + skin.FindNamesForSlot(slotIndex, attachmentNames); + + foreach (var skinKey in attachmentNames) { + var attachment = skin.GetAttachment(slotIndex, skinKey); + var boundingBoxAttachment = attachment as BoundingBoxAttachment; + + if (BoundingBoxFollower.DebugMessages && attachment != null && boundingBoxAttachment == null) + Debug.Log("BoundingBoxFollower tried to follow a slot that contains non-boundingbox attachments: " + slotName); + + if (boundingBoxAttachment != null) { + if (!colliderTable.ContainsKey(boundingBoxAttachment)) { + var bbCollider = SkeletonUtility.AddBoundingBoxAsComponent(boundingBoxAttachment, slot, gameObject, isTrigger); + bbCollider.enabled = false; + bbCollider.hideFlags = HideFlags.NotEditable; + bbCollider.isTrigger = IsTrigger; + colliderTable.Add(boundingBoxAttachment, bbCollider); + nameTable.Add(boundingBoxAttachment, skinKey); + } + } + } + } + + void OnDisable () { + if (clearStateOnDisable) + ClearState(); + } + + public void ClearState () { + if (colliderTable != null) + foreach (var col in colliderTable.Values) + col.enabled = false; + + currentAttachment = null; + currentAttachmentName = null; + currentCollider = null; + } + + void DisposeColliders () { + var colliders = GetComponents(); + if (colliders.Length == 0) return; + + if (Application.isEditor) { + if (Application.isPlaying) { + foreach (var c in colliders) { + if (c != null) + Destroy(c); + } + } else { + foreach (var c in colliders) + if (c != null) + DestroyImmediate(c); + } + } else { + foreach (PolygonCollider2D c in colliders) + if (c != null) + Destroy(c); + } + + slot = null; + currentAttachment = null; + currentAttachmentName = null; + currentCollider = null; + colliderTable.Clear(); + nameTable.Clear(); + } + + void LateUpdate () { + if (slot != null && slot.Attachment != currentAttachment) + MatchAttachment(slot.Attachment); + } + + /// Sets the current collider to match attachment. + /// If the attachment is not a bounding box, it will be treated as null. + void MatchAttachment (Attachment attachment) { + var bbAttachment = attachment as BoundingBoxAttachment; + + if (BoundingBoxFollower.DebugMessages && attachment != null && bbAttachment == null) + Debug.LogWarning("BoundingBoxFollower tried to match a non-boundingbox attachment. It will treat it as null."); + + if (currentCollider != null) + currentCollider.enabled = false; + + if (bbAttachment == null) { + currentCollider = null; + currentAttachment = null; + currentAttachmentName = null; + } else { + PolygonCollider2D foundCollider; + colliderTable.TryGetValue(bbAttachment, out foundCollider); + if (foundCollider != null) { + currentCollider = foundCollider; + currentCollider.enabled = true; + currentAttachment = bbAttachment; + currentAttachmentName = nameTable[bbAttachment]; + } else { + currentCollider = null; + currentAttachment = bbAttachment; + currentAttachmentName = null; + if (BoundingBoxFollower.DebugMessages) Debug.LogFormat("Collider for BoundingBoxAttachment named '{0}' was not initialized. It is possibly from a new skin. currentAttachmentName will be null. You may need to call BoundingBoxFollower.Initialize(overwrite: true);", bbAttachment.Name); + } + } + } + } + +} diff --git a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/CustomMaterials.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/CustomMaterials.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/CustomMaterials.meta diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs index 6a0120f72..a8d8a714e 100644 --- a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs @@ -1,204 +1,204 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -#define SPINE_OPTIONAL_MATERIALOVERRIDE - -// Contributed by: Lost Polygon - -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace Spine.Unity.Modules { - [ExecuteInEditMode] - public class SkeletonRendererCustomMaterials : MonoBehaviour { - - #region Inspector - public SkeletonRenderer skeletonRenderer; - [SerializeField] protected List customSlotMaterials = new List(); - [SerializeField] protected List customMaterialOverrides = new List(); - - #if UNITY_EDITOR - void Reset () { - skeletonRenderer = GetComponent(); - - // Populate atlas list - if (skeletonRenderer != null && skeletonRenderer.skeletonDataAsset != null) { - AtlasAsset[] atlasAssets = skeletonRenderer.skeletonDataAsset.atlasAssets; - - var initialAtlasMaterialOverrides = new List(); - foreach (AtlasAsset atlasAsset in atlasAssets) { - foreach (Material atlasMaterial in atlasAsset.materials) { - var atlasMaterialOverride = new AtlasMaterialOverride(); - atlasMaterialOverride.overrideDisabled = true; - atlasMaterialOverride.originalMaterial = atlasMaterial; - - initialAtlasMaterialOverrides.Add(atlasMaterialOverride); - } - } - - customMaterialOverrides = initialAtlasMaterialOverrides; - } - } - #endif - #endregion - - void SetCustomSlotMaterials () { - if (skeletonRenderer == null) { - Debug.LogError("skeletonRenderer == null"); - return; - } - - for (int i = 0; i < customSlotMaterials.Count; i++) { - SlotMaterialOverride slotMaterialOverride = customSlotMaterials[i]; - if (slotMaterialOverride.overrideDisabled || string.IsNullOrEmpty(slotMaterialOverride.slotName)) - continue; - - Slot slotObject = skeletonRenderer.skeleton.FindSlot(slotMaterialOverride.slotName); - skeletonRenderer.CustomSlotMaterials[slotObject] = slotMaterialOverride.material; - } - } - - void RemoveCustomSlotMaterials () { - if (skeletonRenderer == null) { - Debug.LogError("skeletonRenderer == null"); - return; - } - - for (int i = 0; i < customSlotMaterials.Count; i++) { - SlotMaterialOverride slotMaterialOverride = customSlotMaterials[i]; - if (string.IsNullOrEmpty(slotMaterialOverride.slotName)) - continue; - - Slot slotObject = skeletonRenderer.skeleton.FindSlot(slotMaterialOverride.slotName); - - Material currentMaterial; - if (!skeletonRenderer.CustomSlotMaterials.TryGetValue(slotObject, out currentMaterial)) - continue; - - // Do not revert the material if it was changed by something else - if (currentMaterial != slotMaterialOverride.material) - continue; - - skeletonRenderer.CustomSlotMaterials.Remove(slotObject); - } - } - - void SetCustomMaterialOverrides () { - if (skeletonRenderer == null) { - Debug.LogError("skeletonRenderer == null"); - return; - } - - #if SPINE_OPTIONAL_MATERIALOVERRIDE - for (int i = 0; i < customMaterialOverrides.Count; i++) { - AtlasMaterialOverride atlasMaterialOverride = customMaterialOverrides[i]; - if (atlasMaterialOverride.overrideDisabled) - continue; - - skeletonRenderer.CustomMaterialOverride[atlasMaterialOverride.originalMaterial] = atlasMaterialOverride.replacementMaterial; - } - #endif - } - - void RemoveCustomMaterialOverrides () { - if (skeletonRenderer == null) { - Debug.LogError("skeletonRenderer == null"); - return; - } - - #if SPINE_OPTIONAL_MATERIALOVERRIDE - for (int i = 0; i < customMaterialOverrides.Count; i++) { - AtlasMaterialOverride atlasMaterialOverride = customMaterialOverrides[i]; - Material currentMaterial; - - if (!skeletonRenderer.CustomMaterialOverride.TryGetValue(atlasMaterialOverride.originalMaterial, out currentMaterial)) - continue; - - // Do not revert the material if it was changed by something else - if (currentMaterial != atlasMaterialOverride.replacementMaterial) - continue; - - skeletonRenderer.CustomMaterialOverride.Remove(atlasMaterialOverride.originalMaterial); - } - #endif - } - - // OnEnable applies the overrides at runtime, and when the editor loads. - void OnEnable () { - if (skeletonRenderer == null) - skeletonRenderer = GetComponent(); - - if (skeletonRenderer == null) { - Debug.LogError("skeletonRenderer == null"); - return; - } - - skeletonRenderer.Initialize(false); - SetCustomMaterialOverrides(); - SetCustomSlotMaterials(); - } - - // OnDisable removes the overrides at runtime, and in the editor when the component is disabled or destroyed. - void OnDisable () { - if (skeletonRenderer == null) { - Debug.LogError("skeletonRenderer == null"); - return; - } - - RemoveCustomMaterialOverrides(); - RemoveCustomSlotMaterials(); - } - - [Serializable] - public struct SlotMaterialOverride : IEquatable { - public bool overrideDisabled; - - [SpineSlot] - public string slotName; - public Material material; - - public bool Equals (SlotMaterialOverride other) { - return overrideDisabled == other.overrideDisabled && slotName == other.slotName && material == other.material; - } - } - - [Serializable] - public struct AtlasMaterialOverride : IEquatable { - public bool overrideDisabled; - public Material originalMaterial; - public Material replacementMaterial; - - public bool Equals (AtlasMaterialOverride other) { - return overrideDisabled == other.overrideDisabled && originalMaterial == other.originalMaterial && replacementMaterial == other.replacementMaterial; - } - } - } -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +#define SPINE_OPTIONAL_MATERIALOVERRIDE + +// Contributed by: Lost Polygon + +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Spine.Unity.Modules { + [ExecuteInEditMode] + public class SkeletonRendererCustomMaterials : MonoBehaviour { + + #region Inspector + public SkeletonRenderer skeletonRenderer; + [SerializeField] protected List customSlotMaterials = new List(); + [SerializeField] protected List customMaterialOverrides = new List(); + + #if UNITY_EDITOR + void Reset () { + skeletonRenderer = GetComponent(); + + // Populate atlas list + if (skeletonRenderer != null && skeletonRenderer.skeletonDataAsset != null) { + AtlasAsset[] atlasAssets = skeletonRenderer.skeletonDataAsset.atlasAssets; + + var initialAtlasMaterialOverrides = new List(); + foreach (AtlasAsset atlasAsset in atlasAssets) { + foreach (Material atlasMaterial in atlasAsset.materials) { + var atlasMaterialOverride = new AtlasMaterialOverride(); + atlasMaterialOverride.overrideDisabled = true; + atlasMaterialOverride.originalMaterial = atlasMaterial; + + initialAtlasMaterialOverrides.Add(atlasMaterialOverride); + } + } + + customMaterialOverrides = initialAtlasMaterialOverrides; + } + } + #endif + #endregion + + void SetCustomSlotMaterials () { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + for (int i = 0; i < customSlotMaterials.Count; i++) { + SlotMaterialOverride slotMaterialOverride = customSlotMaterials[i]; + if (slotMaterialOverride.overrideDisabled || string.IsNullOrEmpty(slotMaterialOverride.slotName)) + continue; + + Slot slotObject = skeletonRenderer.skeleton.FindSlot(slotMaterialOverride.slotName); + skeletonRenderer.CustomSlotMaterials[slotObject] = slotMaterialOverride.material; + } + } + + void RemoveCustomSlotMaterials () { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + for (int i = 0; i < customSlotMaterials.Count; i++) { + SlotMaterialOverride slotMaterialOverride = customSlotMaterials[i]; + if (string.IsNullOrEmpty(slotMaterialOverride.slotName)) + continue; + + Slot slotObject = skeletonRenderer.skeleton.FindSlot(slotMaterialOverride.slotName); + + Material currentMaterial; + if (!skeletonRenderer.CustomSlotMaterials.TryGetValue(slotObject, out currentMaterial)) + continue; + + // Do not revert the material if it was changed by something else + if (currentMaterial != slotMaterialOverride.material) + continue; + + skeletonRenderer.CustomSlotMaterials.Remove(slotObject); + } + } + + void SetCustomMaterialOverrides () { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + #if SPINE_OPTIONAL_MATERIALOVERRIDE + for (int i = 0; i < customMaterialOverrides.Count; i++) { + AtlasMaterialOverride atlasMaterialOverride = customMaterialOverrides[i]; + if (atlasMaterialOverride.overrideDisabled) + continue; + + skeletonRenderer.CustomMaterialOverride[atlasMaterialOverride.originalMaterial] = atlasMaterialOverride.replacementMaterial; + } + #endif + } + + void RemoveCustomMaterialOverrides () { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + #if SPINE_OPTIONAL_MATERIALOVERRIDE + for (int i = 0; i < customMaterialOverrides.Count; i++) { + AtlasMaterialOverride atlasMaterialOverride = customMaterialOverrides[i]; + Material currentMaterial; + + if (!skeletonRenderer.CustomMaterialOverride.TryGetValue(atlasMaterialOverride.originalMaterial, out currentMaterial)) + continue; + + // Do not revert the material if it was changed by something else + if (currentMaterial != atlasMaterialOverride.replacementMaterial) + continue; + + skeletonRenderer.CustomMaterialOverride.Remove(atlasMaterialOverride.originalMaterial); + } + #endif + } + + // OnEnable applies the overrides at runtime, and when the editor loads. + void OnEnable () { + if (skeletonRenderer == null) + skeletonRenderer = GetComponent(); + + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + skeletonRenderer.Initialize(false); + SetCustomMaterialOverrides(); + SetCustomSlotMaterials(); + } + + // OnDisable removes the overrides at runtime, and in the editor when the component is disabled or destroyed. + void OnDisable () { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + RemoveCustomMaterialOverrides(); + RemoveCustomSlotMaterials(); + } + + [Serializable] + public struct SlotMaterialOverride : IEquatable { + public bool overrideDisabled; + + [SpineSlot] + public string slotName; + public Material material; + + public bool Equals (SlotMaterialOverride other) { + return overrideDisabled == other.overrideDisabled && slotName == other.slotName && material == other.material; + } + } + + [Serializable] + public struct AtlasMaterialOverride : IEquatable { + public bool overrideDisabled; + public Material originalMaterial; + public Material replacementMaterial; + + public bool Equals (AtlasMaterialOverride other) { + return overrideDisabled == other.overrideDisabled && originalMaterial == other.originalMaterial && replacementMaterial == other.replacementMaterial; + } + } + } +} diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.txt b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.txt similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.txt rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.txt diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.txt.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.txt.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.txt.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.txt.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Ghost.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ghost.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Ghost/Shaders.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/Shaders.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ghost/Shaders.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/Shaders.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Ghost/Shaders/Spine-Special-Skeleton-Ghost.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/Shaders/Spine-Special-Skeleton-Ghost.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ghost/Shaders/Spine-Special-Skeleton-Ghost.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/Shaders/Spine-Special-Skeleton-Ghost.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Ghost/Shaders/Spine-Special-Skeleton-Ghost.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/Shaders/Spine-Special-Skeleton-Ghost.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ghost/Shaders/Spine-Special-Skeleton-Ghost.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/Shaders/Spine-Special-Skeleton-Ghost.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Ghost/SkeletonGhost.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/SkeletonGhost.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/Ghost/SkeletonGhost.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/SkeletonGhost.cs index 365d1272c..5f04eac38 100644 --- a/spine-unity/Assets/spine-unity/Modules/Ghost/SkeletonGhost.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/SkeletonGhost.cs @@ -1,184 +1,184 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -// Contributed by: Mitch Thompson - -using UnityEngine; -using System.Collections.Generic; - -namespace Spine.Unity.Modules { - - [RequireComponent(typeof(SkeletonRenderer))] - public class SkeletonGhost : MonoBehaviour { - // Internal Settings - const HideFlags GhostHideFlags = HideFlags.HideInHierarchy; - const string GhostingShaderName = "Spine/Special/SkeletonGhost"; - - public bool ghostingEnabled = true; - public float spawnRate = 0.05f; - public Color32 color = new Color32(0xFF, 0xFF, 0xFF, 0x00); // default for additive. - [Tooltip("Remember to set color alpha to 0 if Additive is true")] - public bool additive = true; - public int maximumGhosts = 10; - public float fadeSpeed = 10; - public Shader ghostShader; - [Tooltip("0 is Color and Alpha, 1 is Alpha only.")] - [Range(0, 1)] - public float textureFade = 1; - - [Header("Sorting")] - public bool sortWithDistanceOnly; - public float zOffset = 0f; - - float nextSpawnTime; - SkeletonGhostRenderer[] pool; - int poolIndex = 0; - SkeletonRenderer skeletonRenderer; - MeshRenderer meshRenderer; - MeshFilter meshFilter; - - readonly Dictionary materialTable = new Dictionary(); - - void Start () { - if (ghostShader == null) - ghostShader = Shader.Find(GhostingShaderName); - - skeletonRenderer = GetComponent(); - meshFilter = GetComponent(); - meshRenderer = GetComponent(); - nextSpawnTime = Time.time + spawnRate; - pool = new SkeletonGhostRenderer[maximumGhosts]; - for (int i = 0; i < maximumGhosts; i++) { - GameObject go = new GameObject(gameObject.name + " Ghost", typeof(SkeletonGhostRenderer)); - pool[i] = go.GetComponent(); - go.SetActive(false); - go.hideFlags = GhostHideFlags; - } - - var skeletonAnimation = skeletonRenderer as Spine.Unity.IAnimationStateComponent; - if (skeletonAnimation != null) skeletonAnimation.AnimationState.Event += OnEvent; - } - - //SkeletonAnimation - /* - * Int Value: 0 sets ghostingEnabled to false, 1 sets ghostingEnabled to true - * Float Value: Values greater than 0 set the spawnRate equal the float value - * String Value: Pass RGBA hex color values in to set the color property. IE: "A0FF8BFF" - */ - void OnEvent (Spine.TrackEntry trackEntry, Spine.Event e) { - if (e.Data.Name.Equals("Ghosting", System.StringComparison.Ordinal)) { - ghostingEnabled = e.Int > 0; - if (e.Float > 0) - spawnRate = e.Float; - - if (!string.IsNullOrEmpty(e.stringValue)) - this.color = HexToColor(e.String); - } - } - - //SkeletonAnimator - //SkeletonAnimator or Mecanim based animations only support toggling ghostingEnabled. Be sure not to set anything other than the Int param in Spine or String will take priority. - void Ghosting (float val) { - ghostingEnabled = val > 0; - } - - void Update () { - if (!ghostingEnabled) - return; - - if (Time.time >= nextSpawnTime) { - GameObject go = pool[poolIndex].gameObject; - - Material[] materials = meshRenderer.sharedMaterials; - for (int i = 0; i < materials.Length; i++) { - var originalMat = materials[i]; - Material ghostMat; - if (!materialTable.ContainsKey(originalMat)) { - ghostMat = new Material(originalMat); - ghostMat.shader = ghostShader; - ghostMat.color = Color.white; - if (ghostMat.HasProperty("_TextureFade")) - ghostMat.SetFloat("_TextureFade", textureFade); - materialTable.Add(originalMat, ghostMat); - } else { - ghostMat = materialTable[originalMat]; - } - - materials[i] = ghostMat; - } - - var goTransform = go.transform; - goTransform.parent = transform; - - pool[poolIndex].Initialize(meshFilter.sharedMesh, materials, color, additive, fadeSpeed, meshRenderer.sortingLayerID, (sortWithDistanceOnly) ? meshRenderer.sortingOrder : meshRenderer.sortingOrder - 1); - - goTransform.localPosition = new Vector3(0f, 0f, zOffset); - goTransform.localRotation = Quaternion.identity; - goTransform.localScale = Vector3.one; - - goTransform.parent = null; - - poolIndex++; - - if (poolIndex == pool.Length) - poolIndex = 0; - - nextSpawnTime = Time.time + spawnRate; - } - } - - void OnDestroy () { - if (pool != null) { - for (int i = 0; i < maximumGhosts; i++) - if (pool[i] != null) pool[i].Cleanup(); - } - - foreach (var mat in materialTable.Values) - Destroy(mat); - } - - //based on UnifyWiki http://wiki.unity3d.com/index.php?title=HexConverter - static Color32 HexToColor (string hex) { - if (hex.Length < 6) - return Color.magenta; - - hex = hex.Replace("#", ""); - byte r = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber); - byte g = byte.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber); - byte b = byte.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber); - byte a = 0xFF; - if (hex.Length == 8) - a = byte.Parse(hex.Substring(6, 2), System.Globalization.NumberStyles.HexNumber); - - return new Color32(r, g, b, a); - } - } - -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Contributed by: Mitch Thompson + +using UnityEngine; +using System.Collections.Generic; + +namespace Spine.Unity.Modules { + + [RequireComponent(typeof(SkeletonRenderer))] + public class SkeletonGhost : MonoBehaviour { + // Internal Settings + const HideFlags GhostHideFlags = HideFlags.HideInHierarchy; + const string GhostingShaderName = "Spine/Special/SkeletonGhost"; + + public bool ghostingEnabled = true; + public float spawnRate = 0.05f; + public Color32 color = new Color32(0xFF, 0xFF, 0xFF, 0x00); // default for additive. + [Tooltip("Remember to set color alpha to 0 if Additive is true")] + public bool additive = true; + public int maximumGhosts = 10; + public float fadeSpeed = 10; + public Shader ghostShader; + [Tooltip("0 is Color and Alpha, 1 is Alpha only.")] + [Range(0, 1)] + public float textureFade = 1; + + [Header("Sorting")] + public bool sortWithDistanceOnly; + public float zOffset = 0f; + + float nextSpawnTime; + SkeletonGhostRenderer[] pool; + int poolIndex = 0; + SkeletonRenderer skeletonRenderer; + MeshRenderer meshRenderer; + MeshFilter meshFilter; + + readonly Dictionary materialTable = new Dictionary(); + + void Start () { + if (ghostShader == null) + ghostShader = Shader.Find(GhostingShaderName); + + skeletonRenderer = GetComponent(); + meshFilter = GetComponent(); + meshRenderer = GetComponent(); + nextSpawnTime = Time.time + spawnRate; + pool = new SkeletonGhostRenderer[maximumGhosts]; + for (int i = 0; i < maximumGhosts; i++) { + GameObject go = new GameObject(gameObject.name + " Ghost", typeof(SkeletonGhostRenderer)); + pool[i] = go.GetComponent(); + go.SetActive(false); + go.hideFlags = GhostHideFlags; + } + + var skeletonAnimation = skeletonRenderer as Spine.Unity.IAnimationStateComponent; + if (skeletonAnimation != null) skeletonAnimation.AnimationState.Event += OnEvent; + } + + //SkeletonAnimation + /* + * Int Value: 0 sets ghostingEnabled to false, 1 sets ghostingEnabled to true + * Float Value: Values greater than 0 set the spawnRate equal the float value + * String Value: Pass RGBA hex color values in to set the color property. IE: "A0FF8BFF" + */ + void OnEvent (Spine.TrackEntry trackEntry, Spine.Event e) { + if (e.Data.Name.Equals("Ghosting", System.StringComparison.Ordinal)) { + ghostingEnabled = e.Int > 0; + if (e.Float > 0) + spawnRate = e.Float; + + if (!string.IsNullOrEmpty(e.stringValue)) + this.color = HexToColor(e.String); + } + } + + //SkeletonAnimator + //SkeletonAnimator or Mecanim based animations only support toggling ghostingEnabled. Be sure not to set anything other than the Int param in Spine or String will take priority. + void Ghosting (float val) { + ghostingEnabled = val > 0; + } + + void Update () { + if (!ghostingEnabled) + return; + + if (Time.time >= nextSpawnTime) { + GameObject go = pool[poolIndex].gameObject; + + Material[] materials = meshRenderer.sharedMaterials; + for (int i = 0; i < materials.Length; i++) { + var originalMat = materials[i]; + Material ghostMat; + if (!materialTable.ContainsKey(originalMat)) { + ghostMat = new Material(originalMat); + ghostMat.shader = ghostShader; + ghostMat.color = Color.white; + if (ghostMat.HasProperty("_TextureFade")) + ghostMat.SetFloat("_TextureFade", textureFade); + materialTable.Add(originalMat, ghostMat); + } else { + ghostMat = materialTable[originalMat]; + } + + materials[i] = ghostMat; + } + + var goTransform = go.transform; + goTransform.parent = transform; + + pool[poolIndex].Initialize(meshFilter.sharedMesh, materials, color, additive, fadeSpeed, meshRenderer.sortingLayerID, (sortWithDistanceOnly) ? meshRenderer.sortingOrder : meshRenderer.sortingOrder - 1); + + goTransform.localPosition = new Vector3(0f, 0f, zOffset); + goTransform.localRotation = Quaternion.identity; + goTransform.localScale = Vector3.one; + + goTransform.parent = null; + + poolIndex++; + + if (poolIndex == pool.Length) + poolIndex = 0; + + nextSpawnTime = Time.time + spawnRate; + } + } + + void OnDestroy () { + if (pool != null) { + for (int i = 0; i < maximumGhosts; i++) + if (pool[i] != null) pool[i].Cleanup(); + } + + foreach (var mat in materialTable.Values) + Destroy(mat); + } + + //based on UnifyWiki http://wiki.unity3d.com/index.php?title=HexConverter + static Color32 HexToColor (string hex) { + if (hex.Length < 6) + return Color.magenta; + + hex = hex.Replace("#", ""); + byte r = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber); + byte g = byte.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber); + byte b = byte.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber); + byte a = 0xFF; + if (hex.Length == 8) + a = byte.Parse(hex.Substring(6, 2), System.Globalization.NumberStyles.HexNumber); + + return new Color32(r, g, b, a); + } + } + +} diff --git a/spine-unity/Assets/spine-unity/Modules/Ghost/SkeletonGhost.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/SkeletonGhost.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ghost/SkeletonGhost.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/SkeletonGhost.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Ghost/SkeletonGhostRenderer.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/SkeletonGhostRenderer.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ghost/SkeletonGhostRenderer.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/SkeletonGhostRenderer.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Ghost/SkeletonGhostRenderer.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/SkeletonGhostRenderer.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ghost/SkeletonGhostRenderer.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ghost/SkeletonGhostRenderer.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Ragdoll.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ragdoll.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll.cs index 8e196c602..d43fb19ac 100644 --- a/spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll.cs @@ -1,405 +1,405 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -// Contributed by: Mitch Thompson - -using UnityEngine; -using System.Collections; -using System.Collections.Generic; - -namespace Spine.Unity.Modules { - [RequireComponent(typeof(SkeletonRenderer))] - public class SkeletonRagdoll : MonoBehaviour { - static Transform parentSpaceHelper; - - #region Inspector - [Header("Hierarchy")] - [SpineBone] - public string startingBoneName = ""; - [SpineBone] - public List stopBoneNames = new List(); - - [Header("Parameters")] - public bool applyOnStart; - [Tooltip("Warning! You will have to re-enable and tune mix values manually if attempting to remove the ragdoll system.")] - public bool disableIK = true; - public bool disableOtherConstraints = false; - [Space(18)] - [Tooltip("Set RootRigidbody IsKinematic to true when Apply is called.")] - public bool pinStartBone; - [Tooltip("Enable Collision between adjacent ragdoll elements (IE: Neck and Head)")] - public bool enableJointCollision; - public bool useGravity = true; - [Tooltip("If no BoundingBox Attachment is attached to a bone, this becomes the default Width or Radius of a Bone's ragdoll Rigidbody")] - public float thickness = 0.125f; - [Tooltip("Default rotational limit value. Min is negative this value, Max is this value.")] - public float rotationLimit = 20; - public float rootMass = 20; - [Tooltip("If your ragdoll seems unstable or uneffected by limits, try lowering this value.")] - [Range(0.01f, 1f)] - public float massFalloffFactor = 0.4f; - [Tooltip("The layer assigned to all of the rigidbody parts.")] - public int colliderLayer = 0; - [Range(0, 1)] - public float mix = 1; - #endregion - - ISkeletonAnimation targetSkeletonComponent; - Skeleton skeleton; - Dictionary boneTable = new Dictionary(); - Transform ragdollRoot; - public Rigidbody RootRigidbody { get; private set; } - public Bone StartingBone { get; private set; } - Vector3 rootOffset; - public Vector3 RootOffset { get { return this.rootOffset; } } - bool isActive; - public bool IsActive { get { return this.isActive; } } - - IEnumerator Start () { - if (parentSpaceHelper == null) { - parentSpaceHelper = (new GameObject("Parent Space Helper")).transform; - parentSpaceHelper.hideFlags = HideFlags.HideInHierarchy; - } - - targetSkeletonComponent = GetComponent() as ISkeletonAnimation; - if (targetSkeletonComponent == null) Debug.LogError("Attached Spine component does not implement ISkeletonAnimation. This script is not compatible."); - skeleton = targetSkeletonComponent.Skeleton; - - if (applyOnStart) { - yield return null; - Apply(); - } - } - - #region API - public Rigidbody[] RigidbodyArray { - get { - if (!isActive) - return new Rigidbody[0]; - - var rigidBodies = new Rigidbody[boneTable.Count]; - int i = 0; - foreach (Transform t in boneTable.Values) { - rigidBodies[i] = t.GetComponent(); - i++; - } - - return rigidBodies; - } - } - - public Vector3 EstimatedSkeletonPosition { - get { return RootRigidbody.position - rootOffset; } - } - - /// Instantiates the ragdoll simulation and applies its transforms to the skeleton. - public void Apply () { - isActive = true; - mix = 1; - - StartingBone = skeleton.FindBone(startingBoneName); - RecursivelyCreateBoneProxies(StartingBone); - - RootRigidbody = boneTable[StartingBone].GetComponent(); - RootRigidbody.isKinematic = pinStartBone; - RootRigidbody.mass = rootMass; - var boneColliders = new List(); - foreach (var pair in boneTable) { - var b = pair.Key; - var t = pair.Value; - Transform parentTransform; - boneColliders.Add(t.GetComponent()); - if (b == StartingBone) { - ragdollRoot = new GameObject("RagdollRoot").transform; - ragdollRoot.SetParent(transform, false); - if (b == skeleton.RootBone) { // RagdollRoot is skeleton root. - ragdollRoot.localPosition = new Vector3(b.WorldX, b.WorldY, 0); - ragdollRoot.localRotation = Quaternion.Euler(0, 0, GetPropagatedRotation(b)); - } else { - ragdollRoot.localPosition = new Vector3(b.Parent.WorldX, b.Parent.WorldY, 0); - ragdollRoot.localRotation = Quaternion.Euler(0, 0, GetPropagatedRotation(b.Parent)); - } - parentTransform = ragdollRoot; - rootOffset = t.position - transform.position; - } else { - parentTransform = boneTable[b.Parent]; - } - - // Add joint and attach to parent. - var rbParent = parentTransform.GetComponent(); - if (rbParent != null) { - var joint = t.gameObject.AddComponent(); - joint.connectedBody = rbParent; - Vector3 localPos = parentTransform.InverseTransformPoint(t.position); - localPos.x *= 1; - joint.connectedAnchor = localPos; - joint.axis = Vector3.forward; - - joint.GetComponent().mass = joint.connectedBody.mass * massFalloffFactor; - joint.limits = new JointLimits { - min = -rotationLimit, - max = rotationLimit, - }; - joint.useLimits = true; - joint.enableCollision = enableJointCollision; - } - } - - // Ignore collisions among bones. - for (int x = 0; x < boneColliders.Count; x++) { - for (int y = 0; y < boneColliders.Count; y++) { - if (x == y) continue; - Physics.IgnoreCollision(boneColliders[x], boneColliders[y]); - } - } - - // Destroy existing override-mode SkeletonUtilityBones. - var utilityBones = GetComponentsInChildren(); - if (utilityBones.Length > 0) { - var destroyedUtilityBoneNames = new List(); - foreach (var ub in utilityBones) { - if (ub.mode == SkeletonUtilityBone.Mode.Override) { - destroyedUtilityBoneNames.Add(ub.gameObject.name); - Destroy(ub.gameObject); - } - } - if (destroyedUtilityBoneNames.Count > 0) { - string msg = "Destroyed Utility Bones: "; - for (int i = 0; i < destroyedUtilityBoneNames.Count; i++) { - msg += destroyedUtilityBoneNames[i]; - if (i != destroyedUtilityBoneNames.Count - 1) { - msg += ","; - } - } - Debug.LogWarning(msg); - } - } - - // Disable skeleton constraints. - if (disableIK) { - var ikConstraints = skeleton.IkConstraints; - for (int i = 0, n = ikConstraints.Count; i < n; i++) - ikConstraints.Items[i].mix = 0; - } - - if (disableOtherConstraints) { - var transformConstraints = skeleton.transformConstraints; - for (int i = 0, n = transformConstraints.Count; i < n; i++) { - transformConstraints.Items[i].rotateMix = 0; - transformConstraints.Items[i].scaleMix = 0; - transformConstraints.Items[i].shearMix = 0; - transformConstraints.Items[i].translateMix = 0; - } - - var pathConstraints = skeleton.pathConstraints; - for (int i = 0, n = pathConstraints.Count; i < n; i++) { - pathConstraints.Items[i].rotateMix = 0; - pathConstraints.Items[i].translateMix = 0; - } - } - - targetSkeletonComponent.UpdateWorld += UpdateSpineSkeleton; - } - - /// Transitions the mix value from the current value to a target value. - public Coroutine SmoothMix (float target, float duration) { - return StartCoroutine(SmoothMixCoroutine(target, duration)); - } - - IEnumerator SmoothMixCoroutine (float target, float duration) { - float startTime = Time.time; - float startMix = mix; - while (mix > 0) { - skeleton.SetBonesToSetupPose(); - mix = Mathf.SmoothStep(startMix, target, (Time.time - startTime) / duration); - yield return null; - } - } - - /// Set the transform world position while preserving the ragdoll parts world position. - public void SetSkeletonPosition (Vector3 worldPosition) { - if (!isActive) { - Debug.LogWarning("Can't call SetSkeletonPosition while Ragdoll is not active!"); - return; - } - - Vector3 offset = worldPosition - transform.position; - transform.position = worldPosition; - foreach (Transform t in boneTable.Values) - t.position -= offset; - - UpdateSpineSkeleton(null); - skeleton.UpdateWorldTransform(); - } - - /// Removes the ragdoll instance and effect from the animated skeleton. - public void Remove () { - isActive = false; - foreach (var t in boneTable.Values) - Destroy(t.gameObject); - - Destroy(ragdollRoot.gameObject); - - boneTable.Clear(); - targetSkeletonComponent.UpdateWorld -= UpdateSpineSkeleton; - } - - public Rigidbody GetRigidbody (string boneName) { - var bone = skeleton.FindBone(boneName); - return (bone != null && boneTable.ContainsKey(bone)) ? boneTable[bone].GetComponent() : null; - } - #endregion - - void RecursivelyCreateBoneProxies (Bone b) { - string boneName = b.data.name; - if (stopBoneNames.Contains(boneName)) - return; - - var boneGameObject = new GameObject(boneName); - boneGameObject.layer = colliderLayer; - Transform t = boneGameObject.transform; - boneTable.Add(b, t); - - t.parent = transform; - t.localPosition = new Vector3(b.WorldX, b.WorldY, 0); - t.localRotation = Quaternion.Euler(0, 0, b.WorldRotationX - b.shearX); - t.localScale = new Vector3(b.WorldScaleX, b.WorldScaleY, 1); - - // MITCH: You left "todo: proper ragdoll branching" - var colliders = AttachBoundingBoxRagdollColliders(b); - if (colliders.Count == 0) { - float length = b.Data.Length; - if (length == 0) { - var ball = boneGameObject.AddComponent(); - ball.radius = thickness * 0.5f; - } else { - var box = boneGameObject.AddComponent(); - box.size = new Vector3(length, thickness, thickness); - box.center = new Vector3(length * 0.5f, 0); - } - } - var rb = boneGameObject.AddComponent(); - rb.constraints = RigidbodyConstraints.FreezePositionZ; - - foreach (Bone child in b.Children) - RecursivelyCreateBoneProxies(child); - } - - void UpdateSpineSkeleton (ISkeletonAnimation skeletonRenderer) { - bool flipX = skeleton.flipX; - bool flipY = skeleton.flipY; - bool flipXOR = flipX ^ flipY; - bool flipOR = flipX || flipY; - - foreach (var pair in boneTable) { - var b = pair.Key; - var t = pair.Value; - bool isStartingBone = b == StartingBone; - Transform parentTransform = isStartingBone ? ragdollRoot : boneTable[b.Parent]; - Vector3 parentTransformWorldPosition = parentTransform.position; - Quaternion parentTransformWorldRotation = parentTransform.rotation; - - parentSpaceHelper.position = parentTransformWorldPosition; - parentSpaceHelper.rotation = parentTransformWorldRotation; - parentSpaceHelper.localScale = parentTransform.localScale; - - Vector3 boneWorldPosition = t.position; - Vector3 right = parentSpaceHelper.InverseTransformDirection(t.right); - - Vector3 boneLocalPosition = parentSpaceHelper.InverseTransformPoint(boneWorldPosition); - float boneLocalRotation = Mathf.Atan2(right.y, right.x) * Mathf.Rad2Deg; - - if (flipOR) { - if (isStartingBone) { - if (flipX) boneLocalPosition.x *= -1f; - if (flipY) boneLocalPosition.y *= -1f; - - boneLocalRotation = boneLocalRotation * (flipXOR ? -1f : 1f); - if (flipX) boneLocalRotation += 180; - } else { - if (flipXOR) { - boneLocalRotation *= -1f; - boneLocalPosition.y *= -1f; // wtf?? - } - } - } - - b.x = Mathf.Lerp(b.x, boneLocalPosition.x, mix); - b.y = Mathf.Lerp(b.y, boneLocalPosition.y, mix); - b.rotation = Mathf.Lerp(b.rotation, boneLocalRotation, mix); - //b.AppliedRotation = Mathf.Lerp(b.AppliedRotation, boneLocalRotation, mix); - } - } - - List AttachBoundingBoxRagdollColliders (Bone b) { - const string AttachmentNameMarker = "ragdoll"; - var colliders = new List(); - - Transform t = boneTable[b]; - GameObject go = t.gameObject; - var skin = skeleton.Skin ?? skeleton.Data.DefaultSkin; - - var attachments = new List(); - foreach (Slot s in skeleton.Slots) { - if (s.Bone == b) { - skin.FindAttachmentsForSlot(skeleton.Slots.IndexOf(s), attachments); - foreach (var a in attachments) { - var bbAttachment = a as BoundingBoxAttachment; - if (bbAttachment != null) { - if (!a.Name.ToLower().Contains(AttachmentNameMarker)) - continue; - - var bbCollider = go.AddComponent(); - var bounds = SkeletonUtility.GetBoundingBoxBounds(bbAttachment, thickness); - bbCollider.center = bounds.center; - bbCollider.size = bounds.size; - colliders.Add(bbCollider); - } - } - } - } - - return colliders; - } - - static float GetPropagatedRotation (Bone b) { - Bone parent = b.Parent; - float a = b.AppliedRotation; - while (parent != null) { - a += parent.AppliedRotation; - parent = parent.parent; - } - return a; - } - - public class LayerFieldAttribute : PropertyAttribute {} - } - -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Contributed by: Mitch Thompson + +using UnityEngine; +using System.Collections; +using System.Collections.Generic; + +namespace Spine.Unity.Modules { + [RequireComponent(typeof(SkeletonRenderer))] + public class SkeletonRagdoll : MonoBehaviour { + static Transform parentSpaceHelper; + + #region Inspector + [Header("Hierarchy")] + [SpineBone] + public string startingBoneName = ""; + [SpineBone] + public List stopBoneNames = new List(); + + [Header("Parameters")] + public bool applyOnStart; + [Tooltip("Warning! You will have to re-enable and tune mix values manually if attempting to remove the ragdoll system.")] + public bool disableIK = true; + public bool disableOtherConstraints = false; + [Space(18)] + [Tooltip("Set RootRigidbody IsKinematic to true when Apply is called.")] + public bool pinStartBone; + [Tooltip("Enable Collision between adjacent ragdoll elements (IE: Neck and Head)")] + public bool enableJointCollision; + public bool useGravity = true; + [Tooltip("If no BoundingBox Attachment is attached to a bone, this becomes the default Width or Radius of a Bone's ragdoll Rigidbody")] + public float thickness = 0.125f; + [Tooltip("Default rotational limit value. Min is negative this value, Max is this value.")] + public float rotationLimit = 20; + public float rootMass = 20; + [Tooltip("If your ragdoll seems unstable or uneffected by limits, try lowering this value.")] + [Range(0.01f, 1f)] + public float massFalloffFactor = 0.4f; + [Tooltip("The layer assigned to all of the rigidbody parts.")] + public int colliderLayer = 0; + [Range(0, 1)] + public float mix = 1; + #endregion + + ISkeletonAnimation targetSkeletonComponent; + Skeleton skeleton; + Dictionary boneTable = new Dictionary(); + Transform ragdollRoot; + public Rigidbody RootRigidbody { get; private set; } + public Bone StartingBone { get; private set; } + Vector3 rootOffset; + public Vector3 RootOffset { get { return this.rootOffset; } } + bool isActive; + public bool IsActive { get { return this.isActive; } } + + IEnumerator Start () { + if (parentSpaceHelper == null) { + parentSpaceHelper = (new GameObject("Parent Space Helper")).transform; + parentSpaceHelper.hideFlags = HideFlags.HideInHierarchy; + } + + targetSkeletonComponent = GetComponent() as ISkeletonAnimation; + if (targetSkeletonComponent == null) Debug.LogError("Attached Spine component does not implement ISkeletonAnimation. This script is not compatible."); + skeleton = targetSkeletonComponent.Skeleton; + + if (applyOnStart) { + yield return null; + Apply(); + } + } + + #region API + public Rigidbody[] RigidbodyArray { + get { + if (!isActive) + return new Rigidbody[0]; + + var rigidBodies = new Rigidbody[boneTable.Count]; + int i = 0; + foreach (Transform t in boneTable.Values) { + rigidBodies[i] = t.GetComponent(); + i++; + } + + return rigidBodies; + } + } + + public Vector3 EstimatedSkeletonPosition { + get { return RootRigidbody.position - rootOffset; } + } + + /// Instantiates the ragdoll simulation and applies its transforms to the skeleton. + public void Apply () { + isActive = true; + mix = 1; + + StartingBone = skeleton.FindBone(startingBoneName); + RecursivelyCreateBoneProxies(StartingBone); + + RootRigidbody = boneTable[StartingBone].GetComponent(); + RootRigidbody.isKinematic = pinStartBone; + RootRigidbody.mass = rootMass; + var boneColliders = new List(); + foreach (var pair in boneTable) { + var b = pair.Key; + var t = pair.Value; + Transform parentTransform; + boneColliders.Add(t.GetComponent()); + if (b == StartingBone) { + ragdollRoot = new GameObject("RagdollRoot").transform; + ragdollRoot.SetParent(transform, false); + if (b == skeleton.RootBone) { // RagdollRoot is skeleton root. + ragdollRoot.localPosition = new Vector3(b.WorldX, b.WorldY, 0); + ragdollRoot.localRotation = Quaternion.Euler(0, 0, GetPropagatedRotation(b)); + } else { + ragdollRoot.localPosition = new Vector3(b.Parent.WorldX, b.Parent.WorldY, 0); + ragdollRoot.localRotation = Quaternion.Euler(0, 0, GetPropagatedRotation(b.Parent)); + } + parentTransform = ragdollRoot; + rootOffset = t.position - transform.position; + } else { + parentTransform = boneTable[b.Parent]; + } + + // Add joint and attach to parent. + var rbParent = parentTransform.GetComponent(); + if (rbParent != null) { + var joint = t.gameObject.AddComponent(); + joint.connectedBody = rbParent; + Vector3 localPos = parentTransform.InverseTransformPoint(t.position); + localPos.x *= 1; + joint.connectedAnchor = localPos; + joint.axis = Vector3.forward; + + joint.GetComponent().mass = joint.connectedBody.mass * massFalloffFactor; + joint.limits = new JointLimits { + min = -rotationLimit, + max = rotationLimit, + }; + joint.useLimits = true; + joint.enableCollision = enableJointCollision; + } + } + + // Ignore collisions among bones. + for (int x = 0; x < boneColliders.Count; x++) { + for (int y = 0; y < boneColliders.Count; y++) { + if (x == y) continue; + Physics.IgnoreCollision(boneColliders[x], boneColliders[y]); + } + } + + // Destroy existing override-mode SkeletonUtilityBones. + var utilityBones = GetComponentsInChildren(); + if (utilityBones.Length > 0) { + var destroyedUtilityBoneNames = new List(); + foreach (var ub in utilityBones) { + if (ub.mode == SkeletonUtilityBone.Mode.Override) { + destroyedUtilityBoneNames.Add(ub.gameObject.name); + Destroy(ub.gameObject); + } + } + if (destroyedUtilityBoneNames.Count > 0) { + string msg = "Destroyed Utility Bones: "; + for (int i = 0; i < destroyedUtilityBoneNames.Count; i++) { + msg += destroyedUtilityBoneNames[i]; + if (i != destroyedUtilityBoneNames.Count - 1) { + msg += ","; + } + } + Debug.LogWarning(msg); + } + } + + // Disable skeleton constraints. + if (disableIK) { + var ikConstraints = skeleton.IkConstraints; + for (int i = 0, n = ikConstraints.Count; i < n; i++) + ikConstraints.Items[i].mix = 0; + } + + if (disableOtherConstraints) { + var transformConstraints = skeleton.transformConstraints; + for (int i = 0, n = transformConstraints.Count; i < n; i++) { + transformConstraints.Items[i].rotateMix = 0; + transformConstraints.Items[i].scaleMix = 0; + transformConstraints.Items[i].shearMix = 0; + transformConstraints.Items[i].translateMix = 0; + } + + var pathConstraints = skeleton.pathConstraints; + for (int i = 0, n = pathConstraints.Count; i < n; i++) { + pathConstraints.Items[i].rotateMix = 0; + pathConstraints.Items[i].translateMix = 0; + } + } + + targetSkeletonComponent.UpdateWorld += UpdateSpineSkeleton; + } + + /// Transitions the mix value from the current value to a target value. + public Coroutine SmoothMix (float target, float duration) { + return StartCoroutine(SmoothMixCoroutine(target, duration)); + } + + IEnumerator SmoothMixCoroutine (float target, float duration) { + float startTime = Time.time; + float startMix = mix; + while (mix > 0) { + skeleton.SetBonesToSetupPose(); + mix = Mathf.SmoothStep(startMix, target, (Time.time - startTime) / duration); + yield return null; + } + } + + /// Set the transform world position while preserving the ragdoll parts world position. + public void SetSkeletonPosition (Vector3 worldPosition) { + if (!isActive) { + Debug.LogWarning("Can't call SetSkeletonPosition while Ragdoll is not active!"); + return; + } + + Vector3 offset = worldPosition - transform.position; + transform.position = worldPosition; + foreach (Transform t in boneTable.Values) + t.position -= offset; + + UpdateSpineSkeleton(null); + skeleton.UpdateWorldTransform(); + } + + /// Removes the ragdoll instance and effect from the animated skeleton. + public void Remove () { + isActive = false; + foreach (var t in boneTable.Values) + Destroy(t.gameObject); + + Destroy(ragdollRoot.gameObject); + + boneTable.Clear(); + targetSkeletonComponent.UpdateWorld -= UpdateSpineSkeleton; + } + + public Rigidbody GetRigidbody (string boneName) { + var bone = skeleton.FindBone(boneName); + return (bone != null && boneTable.ContainsKey(bone)) ? boneTable[bone].GetComponent() : null; + } + #endregion + + void RecursivelyCreateBoneProxies (Bone b) { + string boneName = b.data.name; + if (stopBoneNames.Contains(boneName)) + return; + + var boneGameObject = new GameObject(boneName); + boneGameObject.layer = colliderLayer; + Transform t = boneGameObject.transform; + boneTable.Add(b, t); + + t.parent = transform; + t.localPosition = new Vector3(b.WorldX, b.WorldY, 0); + t.localRotation = Quaternion.Euler(0, 0, b.WorldRotationX - b.shearX); + t.localScale = new Vector3(b.WorldScaleX, b.WorldScaleY, 1); + + // MITCH: You left "todo: proper ragdoll branching" + var colliders = AttachBoundingBoxRagdollColliders(b); + if (colliders.Count == 0) { + float length = b.Data.Length; + if (length == 0) { + var ball = boneGameObject.AddComponent(); + ball.radius = thickness * 0.5f; + } else { + var box = boneGameObject.AddComponent(); + box.size = new Vector3(length, thickness, thickness); + box.center = new Vector3(length * 0.5f, 0); + } + } + var rb = boneGameObject.AddComponent(); + rb.constraints = RigidbodyConstraints.FreezePositionZ; + + foreach (Bone child in b.Children) + RecursivelyCreateBoneProxies(child); + } + + void UpdateSpineSkeleton (ISkeletonAnimation skeletonRenderer) { + bool flipX = skeleton.flipX; + bool flipY = skeleton.flipY; + bool flipXOR = flipX ^ flipY; + bool flipOR = flipX || flipY; + + foreach (var pair in boneTable) { + var b = pair.Key; + var t = pair.Value; + bool isStartingBone = b == StartingBone; + Transform parentTransform = isStartingBone ? ragdollRoot : boneTable[b.Parent]; + Vector3 parentTransformWorldPosition = parentTransform.position; + Quaternion parentTransformWorldRotation = parentTransform.rotation; + + parentSpaceHelper.position = parentTransformWorldPosition; + parentSpaceHelper.rotation = parentTransformWorldRotation; + parentSpaceHelper.localScale = parentTransform.localScale; + + Vector3 boneWorldPosition = t.position; + Vector3 right = parentSpaceHelper.InverseTransformDirection(t.right); + + Vector3 boneLocalPosition = parentSpaceHelper.InverseTransformPoint(boneWorldPosition); + float boneLocalRotation = Mathf.Atan2(right.y, right.x) * Mathf.Rad2Deg; + + if (flipOR) { + if (isStartingBone) { + if (flipX) boneLocalPosition.x *= -1f; + if (flipY) boneLocalPosition.y *= -1f; + + boneLocalRotation = boneLocalRotation * (flipXOR ? -1f : 1f); + if (flipX) boneLocalRotation += 180; + } else { + if (flipXOR) { + boneLocalRotation *= -1f; + boneLocalPosition.y *= -1f; // wtf?? + } + } + } + + b.x = Mathf.Lerp(b.x, boneLocalPosition.x, mix); + b.y = Mathf.Lerp(b.y, boneLocalPosition.y, mix); + b.rotation = Mathf.Lerp(b.rotation, boneLocalRotation, mix); + //b.AppliedRotation = Mathf.Lerp(b.AppliedRotation, boneLocalRotation, mix); + } + } + + List AttachBoundingBoxRagdollColliders (Bone b) { + const string AttachmentNameMarker = "ragdoll"; + var colliders = new List(); + + Transform t = boneTable[b]; + GameObject go = t.gameObject; + var skin = skeleton.Skin ?? skeleton.Data.DefaultSkin; + + var attachments = new List(); + foreach (Slot s in skeleton.Slots) { + if (s.Bone == b) { + skin.FindAttachmentsForSlot(skeleton.Slots.IndexOf(s), attachments); + foreach (var a in attachments) { + var bbAttachment = a as BoundingBoxAttachment; + if (bbAttachment != null) { + if (!a.Name.ToLower().Contains(AttachmentNameMarker)) + continue; + + var bbCollider = go.AddComponent(); + var bounds = SkeletonUtility.GetBoundingBoxBounds(bbAttachment, thickness); + bbCollider.center = bounds.center; + bbCollider.size = bounds.size; + colliders.Add(bbCollider); + } + } + } + } + + return colliders; + } + + static float GetPropagatedRotation (Bone b) { + Bone parent = b.Parent; + float a = b.AppliedRotation; + while (parent != null) { + a += parent.AppliedRotation; + parent = parent.parent; + } + return a; + } + + public class LayerFieldAttribute : PropertyAttribute {} + } + +} diff --git a/spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderMaths.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderMaths.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderMaths.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderMaths.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderMaths.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderMaths.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderMaths.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderMaths.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderShared.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderShared.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderShared.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderShared.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderShared.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderShared.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderShared.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/ShaderShared.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpritePixelLighting.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteShadows.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteShadows.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteShadows.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteShadows.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteShadows.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteShadows.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteShadows.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteShadows.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteSpecular.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteVertexLighting.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/README.md b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/README.md similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/README.md rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/README.md diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/README.md.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/README.md.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/README.md.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/README.md.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteLighting.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritePixelLighting.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteShadows.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteShadows.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteShadows.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteShadows.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteShadows.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteShadows.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteShadows.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteShadows.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteUnlit.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteUnlit.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteUnlit.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteUnlit.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteUnlit.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteUnlit.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteUnlit.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteUnlit.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesPixelLit.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesVertexLit.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Straight Alpha.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Straight Alpha.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Straight Alpha.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Straight Alpha.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Fill.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Fill.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Fill.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Fill.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Fill.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Fill.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Fill.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Fill.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Tint.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Tint.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Tint.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Tint.shader diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Tint.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Tint.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Tint.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Straight Alpha/Spine-Straight-Skeleton-Tint.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/BoneFollowerGraphic.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/BoneFollowerGraphic.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/BoneFollowerGraphic.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/BoneFollowerGraphic.cs diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/BoneFollowerGraphic.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/BoneFollowerGraphic.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/BoneFollowerGraphic.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/BoneFollowerGraphic.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicDefault.mat.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicTintBlack.mat b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicTintBlack.mat similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicTintBlack.mat rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicTintBlack.mat diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicTintBlack.mat.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicTintBlack.mat.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicTintBlack.mat.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/SkeletonGraphicTintBlack.mat.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs index 49f0181d9..f0665c17e 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs @@ -1,299 +1,299 @@ -/****************************************************************************** - * 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 UnityEngine; -using UnityEngine.UI; -using Spine; - -namespace Spine.Unity { - [ExecuteInEditMode, RequireComponent(typeof(CanvasRenderer), typeof(RectTransform)), DisallowMultipleComponent] - [AddComponentMenu("Spine/SkeletonGraphic (Unity UI Canvas)")] - public class SkeletonGraphic : MaskableGraphic, ISkeletonComponent, IAnimationStateComponent, ISkeletonAnimation, IHasSkeletonDataAsset { - - #region Inspector - public SkeletonDataAsset skeletonDataAsset; - public SkeletonDataAsset SkeletonDataAsset { get { return skeletonDataAsset; } } - - [SpineSkin(dataField:"skeletonDataAsset")] - public string initialSkinName = "default"; - public bool initialFlipX, initialFlipY; - - [SpineAnimation(dataField:"skeletonDataAsset")] - public string startingAnimation; - public bool startingLoop; - public float timeScale = 1f; - public bool freeze; - public bool unscaledTime; - - #if UNITY_EDITOR - protected override void OnValidate () { - // This handles Scene View preview. - base.OnValidate (); - if (this.IsValid) { - if (skeletonDataAsset == null) { - Clear(); - startingAnimation = ""; - } else if (skeletonDataAsset.GetSkeletonData(true) != skeleton.data) { - Clear(); - Initialize(true); - startingAnimation = ""; - 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; - - if (!string.IsNullOrEmpty(initialSkinName)) { - var skin = skeleton.data.FindSkin(initialSkinName); - if (skin != null) { - if (skin == skeleton.data.defaultSkin) - skeleton.SetSkin((Skin)null); - else - skeleton.SetSkin(skin); - } - - } - - // Only provide visual feedback to inspector changes in Unity Editor Edit mode. - if (!Application.isPlaying) { - skeleton.flipX = this.initialFlipX; - skeleton.flipY = this.initialFlipY; - - skeleton.SetToSetupPose(); - if (!string.IsNullOrEmpty(startingAnimation)) - skeleton.PoseWithAnimation(startingAnimation, 0f, false); - } - - } - } else { - if (skeletonDataAsset != null) - Initialize(true); - } - } - - protected override void Reset () { - base.Reset(); - if (material == null || material.shader != Shader.Find("Spine/SkeletonGraphic (Premultiply Alpha)")) - Debug.LogWarning("SkeletonGraphic works best with the SkeletonGraphic material."); - } - #endif - #endregion - - #region Runtime Instantiation - public static SkeletonGraphic NewSkeletonGraphicGameObject (SkeletonDataAsset skeletonDataAsset, Transform parent) { - SkeletonGraphic sg = SkeletonGraphic.AddSkeletonGraphicComponent(new GameObject("New Spine GameObject"), skeletonDataAsset); - if (parent != null) sg.transform.SetParent(parent, false); - return sg; - } - - public static SkeletonGraphic AddSkeletonGraphicComponent (GameObject gameObject, SkeletonDataAsset skeletonDataAsset) { - var c = gameObject.AddComponent(); - if (skeletonDataAsset != null) { - c.skeletonDataAsset = skeletonDataAsset; - c.Initialize(false); - } - return c; - } - #endregion - - #region Internals - // This is used by the UI system to determine what to put in the MaterialPropertyBlock. - Texture overrideTexture; - public Texture OverrideTexture { - get { return overrideTexture; } - set { - overrideTexture = value; - canvasRenderer.SetTexture(this.mainTexture); // Refresh canvasRenderer's texture. Make sure it handles null. - } - } - public override Texture mainTexture { - get { - // Fail loudly when incorrectly set up. - if (overrideTexture != null) return overrideTexture; - return skeletonDataAsset == null ? null : skeletonDataAsset.atlasAssets[0].materials[0].mainTexture; - } - } - - protected override void Awake () { - base.Awake (); - if (!this.IsValid) { - Initialize(false); - Rebuild(CanvasUpdate.PreRender); - } - } - - public override void Rebuild (CanvasUpdate update) { - base.Rebuild(update); - if (canvasRenderer.cull) return; - if (update == CanvasUpdate.PreRender) UpdateMesh(); - } - - public virtual void Update () { - if (freeze) return; - Update(unscaledTime ? Time.unscaledDeltaTime : Time.deltaTime); - } - - public virtual void Update (float deltaTime) { - if (!this.IsValid) return; - - deltaTime *= timeScale; - skeleton.Update(deltaTime); - state.Update(deltaTime); - state.Apply(skeleton); - - if (UpdateLocal != null) UpdateLocal(this); - - skeleton.UpdateWorldTransform(); - - if (UpdateWorld != null) { - UpdateWorld(this); - skeleton.UpdateWorldTransform(); - } - - if (UpdateComplete != null) UpdateComplete(this); - } - - public void LateUpdate () { - if (freeze) return; - //this.SetVerticesDirty(); // Which is better? - UpdateMesh(); - } - #endregion - - #region API - protected Skeleton skeleton; - public Skeleton Skeleton { get { return skeleton; } } - public SkeletonData SkeletonData { get { return skeleton == null ? null : skeleton.data; } } - public bool IsValid { get { return skeleton != null; } } - - protected Spine.AnimationState state; - public Spine.AnimationState AnimationState { get { return state; } } - - [SerializeField] protected Spine.Unity.MeshGenerator meshGenerator = new MeshGenerator(); - public Spine.Unity.MeshGenerator MeshGenerator { get { return this.meshGenerator; } } - DoubleBuffered meshBuffers; - SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction(); - - public Mesh GetLastMesh () { - return meshBuffers.GetCurrent().mesh; - } - - public event UpdateBonesDelegate UpdateLocal; - public event UpdateBonesDelegate UpdateWorld; - public event UpdateBonesDelegate UpdateComplete; - - /// Occurs after the vertex data populated every frame, before the vertices are pushed into the mesh. - public event Spine.Unity.MeshGeneratorDelegate OnPostProcessVertices; - - public void Clear () { - skeleton = null; - canvasRenderer.Clear(); - } - - public void Initialize (bool overwrite) { - if (this.IsValid && !overwrite) return; - - // Make sure none of the stuff is null - if (this.skeletonDataAsset == null) return; - var skeletonData = this.skeletonDataAsset.GetSkeletonData(false); - if (skeletonData == null) return; - - if (skeletonDataAsset.atlasAssets.Length <= 0 || skeletonDataAsset.atlasAssets[0].materials.Length <= 0) return; - - this.state = new Spine.AnimationState(skeletonDataAsset.GetAnimationStateData()); - if (state == null) { - Clear(); - return; - } - - this.skeleton = new Skeleton(skeletonData) { - flipX = this.initialFlipX, - flipY = this.initialFlipY - }; - - meshBuffers = new DoubleBuffered(); - canvasRenderer.SetTexture(this.mainTexture); // Needed for overwriting initializations. - - // Set the initial Skin and Animation - if (!string.IsNullOrEmpty(initialSkinName)) - skeleton.SetSkin(initialSkinName); - - #if UNITY_EDITOR - if (!string.IsNullOrEmpty(startingAnimation)) { - if (Application.isPlaying) { - state.SetAnimation(0, startingAnimation, startingLoop); - } else { - // Assume SkeletonAnimation is valid for skeletonData and skeleton. Checked above. - var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(startingAnimation); - if (animationObject != null) - animationObject.PoseSkeleton(skeleton, 0); - } - Update(0); - } - #else - if (!string.IsNullOrEmpty(startingAnimation)) { - state.SetAnimation(0, startingAnimation, startingLoop); - Update(0); - } - #endif - } - - public void UpdateMesh () { - if (!this.IsValid) return; - - skeleton.SetColor(this.color); - var smartMesh = meshBuffers.GetNext(); - var currentInstructions = this.currentInstructions; - - MeshGenerator.GenerateSingleSubmeshInstruction(currentInstructions, skeleton, this.material); - bool updateTriangles = SkeletonRendererInstruction.GeometryNotEqual(currentInstructions, smartMesh.instructionUsed); - - meshGenerator.Begin(); - if (currentInstructions.hasActiveClipping) { - meshGenerator.AddSubmesh(currentInstructions.submeshInstructions.Items[0], updateTriangles); - } else { - meshGenerator.BuildMeshWithArrays(currentInstructions, updateTriangles); - } - - if (canvas != null) meshGenerator.ScaleVertexData(canvas.referencePixelsPerUnit); - if (OnPostProcessVertices != null) OnPostProcessVertices.Invoke(this.meshGenerator.Buffers); - - var mesh = smartMesh.mesh; - meshGenerator.FillVertexData(mesh); - if (updateTriangles) meshGenerator.FillTrianglesSingle(mesh); - meshGenerator.FillLateVertexData(mesh); - - canvasRenderer.SetMesh(mesh); - smartMesh.instructionUsed.Set(currentInstructions); - - //this.UpdateMaterial(); // TODO: This allocates memory. - } - #endregion - } -} +/****************************************************************************** + * 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 UnityEngine; +using UnityEngine.UI; +using Spine; + +namespace Spine.Unity { + [ExecuteInEditMode, RequireComponent(typeof(CanvasRenderer), typeof(RectTransform)), DisallowMultipleComponent] + [AddComponentMenu("Spine/SkeletonGraphic (Unity UI Canvas)")] + public class SkeletonGraphic : MaskableGraphic, ISkeletonComponent, IAnimationStateComponent, ISkeletonAnimation, IHasSkeletonDataAsset { + + #region Inspector + public SkeletonDataAsset skeletonDataAsset; + public SkeletonDataAsset SkeletonDataAsset { get { return skeletonDataAsset; } } + + [SpineSkin(dataField:"skeletonDataAsset")] + public string initialSkinName = "default"; + public bool initialFlipX, initialFlipY; + + [SpineAnimation(dataField:"skeletonDataAsset")] + public string startingAnimation; + public bool startingLoop; + public float timeScale = 1f; + public bool freeze; + public bool unscaledTime; + + #if UNITY_EDITOR + protected override void OnValidate () { + // This handles Scene View preview. + base.OnValidate (); + if (this.IsValid) { + if (skeletonDataAsset == null) { + Clear(); + startingAnimation = ""; + } else if (skeletonDataAsset.GetSkeletonData(true) != skeleton.data) { + Clear(); + Initialize(true); + startingAnimation = ""; + 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; + + if (!string.IsNullOrEmpty(initialSkinName)) { + var skin = skeleton.data.FindSkin(initialSkinName); + if (skin != null) { + if (skin == skeleton.data.defaultSkin) + skeleton.SetSkin((Skin)null); + else + skeleton.SetSkin(skin); + } + + } + + // Only provide visual feedback to inspector changes in Unity Editor Edit mode. + if (!Application.isPlaying) { + skeleton.flipX = this.initialFlipX; + skeleton.flipY = this.initialFlipY; + + skeleton.SetToSetupPose(); + if (!string.IsNullOrEmpty(startingAnimation)) + skeleton.PoseWithAnimation(startingAnimation, 0f, false); + } + + } + } else { + if (skeletonDataAsset != null) + Initialize(true); + } + } + + protected override void Reset () { + base.Reset(); + if (material == null || material.shader != Shader.Find("Spine/SkeletonGraphic (Premultiply Alpha)")) + Debug.LogWarning("SkeletonGraphic works best with the SkeletonGraphic material."); + } + #endif + #endregion + + #region Runtime Instantiation + public static SkeletonGraphic NewSkeletonGraphicGameObject (SkeletonDataAsset skeletonDataAsset, Transform parent) { + SkeletonGraphic sg = SkeletonGraphic.AddSkeletonGraphicComponent(new GameObject("New Spine GameObject"), skeletonDataAsset); + if (parent != null) sg.transform.SetParent(parent, false); + return sg; + } + + public static SkeletonGraphic AddSkeletonGraphicComponent (GameObject gameObject, SkeletonDataAsset skeletonDataAsset) { + var c = gameObject.AddComponent(); + if (skeletonDataAsset != null) { + c.skeletonDataAsset = skeletonDataAsset; + c.Initialize(false); + } + return c; + } + #endregion + + #region Internals + // This is used by the UI system to determine what to put in the MaterialPropertyBlock. + Texture overrideTexture; + public Texture OverrideTexture { + get { return overrideTexture; } + set { + overrideTexture = value; + canvasRenderer.SetTexture(this.mainTexture); // Refresh canvasRenderer's texture. Make sure it handles null. + } + } + public override Texture mainTexture { + get { + // Fail loudly when incorrectly set up. + if (overrideTexture != null) return overrideTexture; + return skeletonDataAsset == null ? null : skeletonDataAsset.atlasAssets[0].materials[0].mainTexture; + } + } + + protected override void Awake () { + base.Awake (); + if (!this.IsValid) { + Initialize(false); + Rebuild(CanvasUpdate.PreRender); + } + } + + public override void Rebuild (CanvasUpdate update) { + base.Rebuild(update); + if (canvasRenderer.cull) return; + if (update == CanvasUpdate.PreRender) UpdateMesh(); + } + + public virtual void Update () { + if (freeze) return; + Update(unscaledTime ? Time.unscaledDeltaTime : Time.deltaTime); + } + + public virtual void Update (float deltaTime) { + if (!this.IsValid) return; + + deltaTime *= timeScale; + skeleton.Update(deltaTime); + state.Update(deltaTime); + state.Apply(skeleton); + + if (UpdateLocal != null) UpdateLocal(this); + + skeleton.UpdateWorldTransform(); + + if (UpdateWorld != null) { + UpdateWorld(this); + skeleton.UpdateWorldTransform(); + } + + if (UpdateComplete != null) UpdateComplete(this); + } + + public void LateUpdate () { + if (freeze) return; + //this.SetVerticesDirty(); // Which is better? + UpdateMesh(); + } + #endregion + + #region API + protected Skeleton skeleton; + public Skeleton Skeleton { get { return skeleton; } } + public SkeletonData SkeletonData { get { return skeleton == null ? null : skeleton.data; } } + public bool IsValid { get { return skeleton != null; } } + + protected Spine.AnimationState state; + public Spine.AnimationState AnimationState { get { return state; } } + + [SerializeField] protected Spine.Unity.MeshGenerator meshGenerator = new MeshGenerator(); + public Spine.Unity.MeshGenerator MeshGenerator { get { return this.meshGenerator; } } + DoubleBuffered meshBuffers; + SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction(); + + public Mesh GetLastMesh () { + return meshBuffers.GetCurrent().mesh; + } + + public event UpdateBonesDelegate UpdateLocal; + public event UpdateBonesDelegate UpdateWorld; + public event UpdateBonesDelegate UpdateComplete; + + /// Occurs after the vertex data populated every frame, before the vertices are pushed into the mesh. + public event Spine.Unity.MeshGeneratorDelegate OnPostProcessVertices; + + public void Clear () { + skeleton = null; + canvasRenderer.Clear(); + } + + public void Initialize (bool overwrite) { + if (this.IsValid && !overwrite) return; + + // Make sure none of the stuff is null + if (this.skeletonDataAsset == null) return; + var skeletonData = this.skeletonDataAsset.GetSkeletonData(false); + if (skeletonData == null) return; + + if (skeletonDataAsset.atlasAssets.Length <= 0 || skeletonDataAsset.atlasAssets[0].materials.Length <= 0) return; + + this.state = new Spine.AnimationState(skeletonDataAsset.GetAnimationStateData()); + if (state == null) { + Clear(); + return; + } + + this.skeleton = new Skeleton(skeletonData) { + flipX = this.initialFlipX, + flipY = this.initialFlipY + }; + + meshBuffers = new DoubleBuffered(); + canvasRenderer.SetTexture(this.mainTexture); // Needed for overwriting initializations. + + // Set the initial Skin and Animation + if (!string.IsNullOrEmpty(initialSkinName)) + skeleton.SetSkin(initialSkinName); + + #if UNITY_EDITOR + if (!string.IsNullOrEmpty(startingAnimation)) { + if (Application.isPlaying) { + state.SetAnimation(0, startingAnimation, startingLoop); + } else { + // Assume SkeletonAnimation is valid for skeletonData and skeleton. Checked above. + var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(startingAnimation); + if (animationObject != null) + animationObject.PoseSkeleton(skeleton, 0); + } + Update(0); + } + #else + if (!string.IsNullOrEmpty(startingAnimation)) { + state.SetAnimation(0, startingAnimation, startingLoop); + Update(0); + } + #endif + } + + public void UpdateMesh () { + if (!this.IsValid) return; + + skeleton.SetColor(this.color); + var smartMesh = meshBuffers.GetNext(); + var currentInstructions = this.currentInstructions; + + MeshGenerator.GenerateSingleSubmeshInstruction(currentInstructions, skeleton, this.material); + bool updateTriangles = SkeletonRendererInstruction.GeometryNotEqual(currentInstructions, smartMesh.instructionUsed); + + meshGenerator.Begin(); + if (currentInstructions.hasActiveClipping) { + meshGenerator.AddSubmesh(currentInstructions.submeshInstructions.Items[0], updateTriangles); + } else { + meshGenerator.BuildMeshWithArrays(currentInstructions, updateTriangles); + } + + if (canvas != null) meshGenerator.ScaleVertexData(canvas.referencePixelsPerUnit); + if (OnPostProcessVertices != null) OnPostProcessVertices.Invoke(this.meshGenerator.Buffers); + + var mesh = smartMesh.mesh; + meshGenerator.FillVertexData(mesh); + if (updateTriangles) meshGenerator.FillTrianglesSingle(mesh); + meshGenerator.FillLateVertexData(mesh); + + canvasRenderer.SetMesh(mesh); + smartMesh.instructionUsed.Set(currentInstructions); + + //this.UpdateMaterial(); // TODO: This allocates memory. + } + #endregion + } +} diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonPartsRenderer.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonPartsRenderer.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonPartsRenderer.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonPartsRenderer.cs index 6660bea93..df61f15ca 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonPartsRenderer.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonPartsRenderer.cs @@ -1,139 +1,139 @@ -/****************************************************************************** - * 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 UnityEngine; - -namespace Spine.Unity.Modules { - [RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))] - public class SkeletonPartsRenderer : MonoBehaviour { - - #region Properties - MeshGenerator meshGenerator; - public MeshGenerator MeshGenerator { - get { - LazyIntialize(); - return meshGenerator; - } - } - - MeshRenderer meshRenderer; - public MeshRenderer MeshRenderer { - get { - LazyIntialize(); - return meshRenderer; - } - } - - MeshFilter meshFilter; - public MeshFilter MeshFilter { - get { - LazyIntialize(); - return meshFilter; - } - } - #endregion - - MeshRendererBuffers buffers; - SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction(); - - - void LazyIntialize () { - if (buffers == null) { - buffers = new MeshRendererBuffers(); - buffers.Initialize(); - - if (meshGenerator != null) return; - meshGenerator = new MeshGenerator(); - meshFilter = GetComponent(); - meshRenderer = GetComponent(); - currentInstructions.Clear(); - } - } - - public void ClearMesh () { - LazyIntialize(); - meshFilter.sharedMesh = null; - } - - public void RenderParts (ExposedList instructions, int startSubmesh, int endSubmesh) { - LazyIntialize(); - - // STEP 1: Create instruction - var smartMesh = buffers.GetNextMesh(); - currentInstructions.SetWithSubset(instructions, startSubmesh, endSubmesh); - bool updateTriangles = SkeletonRendererInstruction.GeometryNotEqual(currentInstructions, smartMesh.instructionUsed); - - // STEP 2: Generate mesh buffers. - var currentInstructionsSubmeshesItems = currentInstructions.submeshInstructions.Items; - meshGenerator.Begin(); - if (currentInstructions.hasActiveClipping) { - for (int i = 0; i < currentInstructions.submeshInstructions.Count; i++) - meshGenerator.AddSubmesh(currentInstructionsSubmeshesItems[i], updateTriangles); - } else { - meshGenerator.BuildMeshWithArrays(currentInstructions, updateTriangles); - } - - buffers.UpdateSharedMaterials(currentInstructions.submeshInstructions); - - // STEP 3: modify mesh. - var mesh = smartMesh.mesh; - - if (meshGenerator.VertexCount <= 0) { // Clear an empty mesh - updateTriangles = false; - mesh.Clear(); - } else { - meshGenerator.FillVertexData(mesh); - if (updateTriangles) { - meshGenerator.FillTriangles(mesh); - meshRenderer.sharedMaterials = buffers.GetUpdatedSharedMaterialsArray(); - } else if (buffers.MaterialsChangedInLastUpdate()) { - meshRenderer.sharedMaterials = buffers.GetUpdatedSharedMaterialsArray(); - } - } - meshGenerator.FillLateVertexData(mesh); - - meshFilter.sharedMesh = mesh; - smartMesh.instructionUsed.Set(currentInstructions); - } - - public void SetPropertyBlock (MaterialPropertyBlock block) { - LazyIntialize(); - meshRenderer.SetPropertyBlock(block); - } - - public static SkeletonPartsRenderer NewPartsRendererGameObject (Transform parent, string name) { - var go = new GameObject(name, typeof(MeshFilter), typeof(MeshRenderer)); - go.transform.SetParent(parent, false); - var returnComponent = go.AddComponent(); - - return returnComponent; - } - } -} +/****************************************************************************** + * 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 UnityEngine; + +namespace Spine.Unity.Modules { + [RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))] + public class SkeletonPartsRenderer : MonoBehaviour { + + #region Properties + MeshGenerator meshGenerator; + public MeshGenerator MeshGenerator { + get { + LazyIntialize(); + return meshGenerator; + } + } + + MeshRenderer meshRenderer; + public MeshRenderer MeshRenderer { + get { + LazyIntialize(); + return meshRenderer; + } + } + + MeshFilter meshFilter; + public MeshFilter MeshFilter { + get { + LazyIntialize(); + return meshFilter; + } + } + #endregion + + MeshRendererBuffers buffers; + SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction(); + + + void LazyIntialize () { + if (buffers == null) { + buffers = new MeshRendererBuffers(); + buffers.Initialize(); + + if (meshGenerator != null) return; + meshGenerator = new MeshGenerator(); + meshFilter = GetComponent(); + meshRenderer = GetComponent(); + currentInstructions.Clear(); + } + } + + public void ClearMesh () { + LazyIntialize(); + meshFilter.sharedMesh = null; + } + + public void RenderParts (ExposedList instructions, int startSubmesh, int endSubmesh) { + LazyIntialize(); + + // STEP 1: Create instruction + var smartMesh = buffers.GetNextMesh(); + currentInstructions.SetWithSubset(instructions, startSubmesh, endSubmesh); + bool updateTriangles = SkeletonRendererInstruction.GeometryNotEqual(currentInstructions, smartMesh.instructionUsed); + + // STEP 2: Generate mesh buffers. + var currentInstructionsSubmeshesItems = currentInstructions.submeshInstructions.Items; + meshGenerator.Begin(); + if (currentInstructions.hasActiveClipping) { + for (int i = 0; i < currentInstructions.submeshInstructions.Count; i++) + meshGenerator.AddSubmesh(currentInstructionsSubmeshesItems[i], updateTriangles); + } else { + meshGenerator.BuildMeshWithArrays(currentInstructions, updateTriangles); + } + + buffers.UpdateSharedMaterials(currentInstructions.submeshInstructions); + + // STEP 3: modify mesh. + var mesh = smartMesh.mesh; + + if (meshGenerator.VertexCount <= 0) { // Clear an empty mesh + updateTriangles = false; + mesh.Clear(); + } else { + meshGenerator.FillVertexData(mesh); + if (updateTriangles) { + meshGenerator.FillTriangles(mesh); + meshRenderer.sharedMaterials = buffers.GetUpdatedSharedMaterialsArray(); + } else if (buffers.MaterialsChangedInLastUpdate()) { + meshRenderer.sharedMaterials = buffers.GetUpdatedSharedMaterialsArray(); + } + } + meshGenerator.FillLateVertexData(mesh); + + meshFilter.sharedMesh = mesh; + smartMesh.instructionUsed.Set(currentInstructions); + } + + public void SetPropertyBlock (MaterialPropertyBlock block) { + LazyIntialize(); + meshRenderer.SetPropertyBlock(block); + } + + public static SkeletonPartsRenderer NewPartsRendererGameObject (Transform parent, string name) { + var go = new GameObject(name, typeof(MeshFilter), typeof(MeshRenderer)); + go.transform.SetParent(parent, false); + var returnComponent = go.AddComponent(); + + return returnComponent; + } + } +} diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonPartsRenderer.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonPartsRenderer.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonPartsRenderer.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonPartsRenderer.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs index b9e11d18e..6a3e3d22d 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs @@ -1,235 +1,235 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -#define SPINE_OPTIONAL_RENDEROVERRIDE - -using UnityEngine; -using System.Collections.Generic; -using Spine.Unity; - -namespace Spine.Unity.Modules { - - [ExecuteInEditMode] - [HelpURL("https://github.com/pharan/spine-unity-docs/blob/master/SkeletonRenderSeparator.md")] - public class SkeletonRenderSeparator : MonoBehaviour { - public const int DefaultSortingOrderIncrement = 5; - - #region Inspector - [SerializeField] - protected SkeletonRenderer skeletonRenderer; - public SkeletonRenderer SkeletonRenderer { - get { return skeletonRenderer; } - set { - #if SPINE_OPTIONAL_RENDEROVERRIDE - if (skeletonRenderer != null) - skeletonRenderer.GenerateMeshOverride -= HandleRender; - #endif - - skeletonRenderer = value; - this.enabled = false; // Disable if nulled. - } - } - - MeshRenderer mainMeshRenderer; - public bool copyPropertyBlock = true; - [Tooltip("Copies MeshRenderer flags into each parts renderer")] - public bool copyMeshRendererFlags = true; - public List partsRenderers = new List(); - - #if UNITY_EDITOR - void Reset () { - if (skeletonRenderer == null) - skeletonRenderer = GetComponent(); - } - #endif - #endregion - - #region Runtime Instantiation - /// Adds a SkeletonRenderSeparator and child SkeletonPartsRenderer GameObjects to a given SkeletonRenderer. - /// The to skeleton renderer. - /// The target SkeletonRenderer or SkeletonAnimation. - /// Sorting layer to be used for the parts renderers. - /// Number of additional SkeletonPartsRenderers on top of the ones determined by counting the number of separator slots. - /// The integer to increment the sorting order per SkeletonPartsRenderer to separate them. - /// The sorting order value of the first SkeletonPartsRenderer. - /// If set to true, a minimum number of SkeletonPartsRenderer GameObjects (determined by separatorSlots.Count + 1) will be added. - public static SkeletonRenderSeparator AddToSkeletonRenderer (SkeletonRenderer skeletonRenderer, int sortingLayerID = 0, int extraPartsRenderers = 0, int sortingOrderIncrement = DefaultSortingOrderIncrement, int baseSortingOrder = 0, bool addMinimumPartsRenderers = true) { - if (skeletonRenderer == null) { - Debug.Log("Tried to add SkeletonRenderSeparator to a null SkeletonRenderer reference."); - return null; - } - - var srs = skeletonRenderer.gameObject.AddComponent(); - srs.skeletonRenderer = skeletonRenderer; - - skeletonRenderer.Initialize(false); - int count = extraPartsRenderers; - if (addMinimumPartsRenderers) - count = extraPartsRenderers + skeletonRenderer.separatorSlots.Count + 1; - - var skeletonRendererTransform = skeletonRenderer.transform; - var componentRenderers = srs.partsRenderers; - - for (int i = 0; i < count; i++) { - var spr = SkeletonPartsRenderer.NewPartsRendererGameObject(skeletonRendererTransform, i.ToString()); - var mr = spr.MeshRenderer; - mr.sortingLayerID = sortingLayerID; - mr.sortingOrder = baseSortingOrder + (i * sortingOrderIncrement); - componentRenderers.Add(spr); - } - - return srs; - } - - /// Add a child SkeletonPartsRenderer GameObject to this SkeletonRenderSeparator. - public void AddPartsRenderer (int sortingOrderIncrement = DefaultSortingOrderIncrement) { - int sortingLayerID = 0; - int sortingOrder = 0; - if (partsRenderers.Count > 0) { - var previous = partsRenderers[partsRenderers.Count - 1]; - var previousMeshRenderer = previous.MeshRenderer; - sortingLayerID = previousMeshRenderer.sortingLayerID; - sortingOrder = previousMeshRenderer.sortingOrder + sortingOrderIncrement; - } - - var spr = SkeletonPartsRenderer.NewPartsRendererGameObject(skeletonRenderer.transform, partsRenderers.Count.ToString()); - partsRenderers.Add(spr); - - var mr = spr.MeshRenderer; - mr.sortingLayerID = sortingLayerID; - mr.sortingOrder = sortingOrder; - } - #endregion - - void OnEnable () { - if (skeletonRenderer == null) return; - if (copiedBlock == null) copiedBlock = new MaterialPropertyBlock(); - mainMeshRenderer = skeletonRenderer.GetComponent(); - - #if SPINE_OPTIONAL_RENDEROVERRIDE - skeletonRenderer.GenerateMeshOverride -= HandleRender; - skeletonRenderer.GenerateMeshOverride += HandleRender; - #endif - - if (copyMeshRendererFlags) { - var lightProbeUsage = mainMeshRenderer.lightProbeUsage; - bool receiveShadows = mainMeshRenderer.receiveShadows; - var reflectionProbeUsage = mainMeshRenderer.reflectionProbeUsage; - var shadowCastingMode = mainMeshRenderer.shadowCastingMode; - var motionVectorGenerationMode = mainMeshRenderer.motionVectorGenerationMode; - var probeAnchor = mainMeshRenderer.probeAnchor; - - for (int i = 0; i < partsRenderers.Count; i++) { - var currentRenderer = partsRenderers[i]; - if (currentRenderer == null) continue; // skip null items. - - var mr = currentRenderer.MeshRenderer; - mr.lightProbeUsage = lightProbeUsage; - mr.receiveShadows = receiveShadows; - mr.reflectionProbeUsage = reflectionProbeUsage; - mr.shadowCastingMode = shadowCastingMode; - mr.motionVectorGenerationMode = motionVectorGenerationMode; - mr.probeAnchor = probeAnchor; - } - } - } - - void OnDisable () { - if (skeletonRenderer == null) return; - #if SPINE_OPTIONAL_RENDEROVERRIDE - skeletonRenderer.GenerateMeshOverride -= HandleRender; - #endif - - #if UNITY_EDITOR - skeletonRenderer.LateUpdate(); - #endif - - foreach (var s in partsRenderers) - s.ClearMesh(); - } - - MaterialPropertyBlock copiedBlock; - - void HandleRender (SkeletonRendererInstruction instruction) { - int rendererCount = partsRenderers.Count; - if (rendererCount <= 0) return; - - if (copyPropertyBlock) - mainMeshRenderer.GetPropertyBlock(copiedBlock); - - var settings = new MeshGenerator.Settings { - addNormals = skeletonRenderer.addNormals, - calculateTangents = skeletonRenderer.calculateTangents, - immutableTriangles = false, // parts cannot do immutable triangles. - pmaVertexColors = skeletonRenderer.pmaVertexColors, - //renderMeshes = skeletonRenderer.renderMeshes, - tintBlack = skeletonRenderer.tintBlack, - useClipping = true, - zSpacing = skeletonRenderer.zSpacing - }; - - var submeshInstructions = instruction.submeshInstructions; - var submeshInstructionsItems = submeshInstructions.Items; - int lastSubmeshInstruction = submeshInstructions.Count - 1; - - int rendererIndex = 0; - var currentRenderer = partsRenderers[rendererIndex]; - for (int si = 0, start = 0; si <= lastSubmeshInstruction; si++) { - if (submeshInstructionsItems[si].forceSeparate || si == lastSubmeshInstruction) { - // Apply properties - var meshGenerator = currentRenderer.MeshGenerator; - meshGenerator.settings = settings; - - if (copyPropertyBlock) - currentRenderer.SetPropertyBlock(copiedBlock); - - // Render - currentRenderer.RenderParts(instruction.submeshInstructions, start, si + 1); - - start = si + 1; - rendererIndex++; - if (rendererIndex < rendererCount) { - currentRenderer = partsRenderers[rendererIndex]; - } else { - // Not enough renderers. Skip the rest of the instructions. - break; - } - } - } - - // Clear extra renderers if they exist. - for (; rendererIndex < rendererCount; rendererIndex++) { - partsRenderers[rendererIndex].ClearMesh(); - } - - } - - } -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +#define SPINE_OPTIONAL_RENDEROVERRIDE + +using UnityEngine; +using System.Collections.Generic; +using Spine.Unity; + +namespace Spine.Unity.Modules { + + [ExecuteInEditMode] + [HelpURL("https://github.com/pharan/spine-unity-docs/blob/master/SkeletonRenderSeparator.md")] + public class SkeletonRenderSeparator : MonoBehaviour { + public const int DefaultSortingOrderIncrement = 5; + + #region Inspector + [SerializeField] + protected SkeletonRenderer skeletonRenderer; + public SkeletonRenderer SkeletonRenderer { + get { return skeletonRenderer; } + set { + #if SPINE_OPTIONAL_RENDEROVERRIDE + if (skeletonRenderer != null) + skeletonRenderer.GenerateMeshOverride -= HandleRender; + #endif + + skeletonRenderer = value; + this.enabled = false; // Disable if nulled. + } + } + + MeshRenderer mainMeshRenderer; + public bool copyPropertyBlock = true; + [Tooltip("Copies MeshRenderer flags into each parts renderer")] + public bool copyMeshRendererFlags = true; + public List partsRenderers = new List(); + + #if UNITY_EDITOR + void Reset () { + if (skeletonRenderer == null) + skeletonRenderer = GetComponent(); + } + #endif + #endregion + + #region Runtime Instantiation + /// Adds a SkeletonRenderSeparator and child SkeletonPartsRenderer GameObjects to a given SkeletonRenderer. + /// The to skeleton renderer. + /// The target SkeletonRenderer or SkeletonAnimation. + /// Sorting layer to be used for the parts renderers. + /// Number of additional SkeletonPartsRenderers on top of the ones determined by counting the number of separator slots. + /// The integer to increment the sorting order per SkeletonPartsRenderer to separate them. + /// The sorting order value of the first SkeletonPartsRenderer. + /// If set to true, a minimum number of SkeletonPartsRenderer GameObjects (determined by separatorSlots.Count + 1) will be added. + public static SkeletonRenderSeparator AddToSkeletonRenderer (SkeletonRenderer skeletonRenderer, int sortingLayerID = 0, int extraPartsRenderers = 0, int sortingOrderIncrement = DefaultSortingOrderIncrement, int baseSortingOrder = 0, bool addMinimumPartsRenderers = true) { + if (skeletonRenderer == null) { + Debug.Log("Tried to add SkeletonRenderSeparator to a null SkeletonRenderer reference."); + return null; + } + + var srs = skeletonRenderer.gameObject.AddComponent(); + srs.skeletonRenderer = skeletonRenderer; + + skeletonRenderer.Initialize(false); + int count = extraPartsRenderers; + if (addMinimumPartsRenderers) + count = extraPartsRenderers + skeletonRenderer.separatorSlots.Count + 1; + + var skeletonRendererTransform = skeletonRenderer.transform; + var componentRenderers = srs.partsRenderers; + + for (int i = 0; i < count; i++) { + var spr = SkeletonPartsRenderer.NewPartsRendererGameObject(skeletonRendererTransform, i.ToString()); + var mr = spr.MeshRenderer; + mr.sortingLayerID = sortingLayerID; + mr.sortingOrder = baseSortingOrder + (i * sortingOrderIncrement); + componentRenderers.Add(spr); + } + + return srs; + } + + /// Add a child SkeletonPartsRenderer GameObject to this SkeletonRenderSeparator. + public void AddPartsRenderer (int sortingOrderIncrement = DefaultSortingOrderIncrement) { + int sortingLayerID = 0; + int sortingOrder = 0; + if (partsRenderers.Count > 0) { + var previous = partsRenderers[partsRenderers.Count - 1]; + var previousMeshRenderer = previous.MeshRenderer; + sortingLayerID = previousMeshRenderer.sortingLayerID; + sortingOrder = previousMeshRenderer.sortingOrder + sortingOrderIncrement; + } + + var spr = SkeletonPartsRenderer.NewPartsRendererGameObject(skeletonRenderer.transform, partsRenderers.Count.ToString()); + partsRenderers.Add(spr); + + var mr = spr.MeshRenderer; + mr.sortingLayerID = sortingLayerID; + mr.sortingOrder = sortingOrder; + } + #endregion + + void OnEnable () { + if (skeletonRenderer == null) return; + if (copiedBlock == null) copiedBlock = new MaterialPropertyBlock(); + mainMeshRenderer = skeletonRenderer.GetComponent(); + + #if SPINE_OPTIONAL_RENDEROVERRIDE + skeletonRenderer.GenerateMeshOverride -= HandleRender; + skeletonRenderer.GenerateMeshOverride += HandleRender; + #endif + + if (copyMeshRendererFlags) { + var lightProbeUsage = mainMeshRenderer.lightProbeUsage; + bool receiveShadows = mainMeshRenderer.receiveShadows; + var reflectionProbeUsage = mainMeshRenderer.reflectionProbeUsage; + var shadowCastingMode = mainMeshRenderer.shadowCastingMode; + var motionVectorGenerationMode = mainMeshRenderer.motionVectorGenerationMode; + var probeAnchor = mainMeshRenderer.probeAnchor; + + for (int i = 0; i < partsRenderers.Count; i++) { + var currentRenderer = partsRenderers[i]; + if (currentRenderer == null) continue; // skip null items. + + var mr = currentRenderer.MeshRenderer; + mr.lightProbeUsage = lightProbeUsage; + mr.receiveShadows = receiveShadows; + mr.reflectionProbeUsage = reflectionProbeUsage; + mr.shadowCastingMode = shadowCastingMode; + mr.motionVectorGenerationMode = motionVectorGenerationMode; + mr.probeAnchor = probeAnchor; + } + } + } + + void OnDisable () { + if (skeletonRenderer == null) return; + #if SPINE_OPTIONAL_RENDEROVERRIDE + skeletonRenderer.GenerateMeshOverride -= HandleRender; + #endif + + #if UNITY_EDITOR + skeletonRenderer.LateUpdate(); + #endif + + foreach (var s in partsRenderers) + s.ClearMesh(); + } + + MaterialPropertyBlock copiedBlock; + + void HandleRender (SkeletonRendererInstruction instruction) { + int rendererCount = partsRenderers.Count; + if (rendererCount <= 0) return; + + if (copyPropertyBlock) + mainMeshRenderer.GetPropertyBlock(copiedBlock); + + var settings = new MeshGenerator.Settings { + addNormals = skeletonRenderer.addNormals, + calculateTangents = skeletonRenderer.calculateTangents, + immutableTriangles = false, // parts cannot do immutable triangles. + pmaVertexColors = skeletonRenderer.pmaVertexColors, + //renderMeshes = skeletonRenderer.renderMeshes, + tintBlack = skeletonRenderer.tintBlack, + useClipping = true, + zSpacing = skeletonRenderer.zSpacing + }; + + var submeshInstructions = instruction.submeshInstructions; + var submeshInstructionsItems = submeshInstructions.Items; + int lastSubmeshInstruction = submeshInstructions.Count - 1; + + int rendererIndex = 0; + var currentRenderer = partsRenderers[rendererIndex]; + for (int si = 0, start = 0; si <= lastSubmeshInstruction; si++) { + if (submeshInstructionsItems[si].forceSeparate || si == lastSubmeshInstruction) { + // Apply properties + var meshGenerator = currentRenderer.MeshGenerator; + meshGenerator.settings = settings; + + if (copyPropertyBlock) + currentRenderer.SetPropertyBlock(copiedBlock); + + // Render + currentRenderer.RenderParts(instruction.submeshInstructions, start, si + 1); + + start = si + 1; + rendererIndex++; + if (rendererIndex < rendererCount) { + currentRenderer = partsRenderers[rendererIndex]; + } else { + // Not enough renderers. Skip the rest of the instructions. + break; + } + } + } + + // Clear extra renderers if they exist. + for (; rendererIndex < rendererCount; rendererIndex++) { + partsRenderers[rendererIndex].ClearMesh(); + } + + } + + } +} diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.txt b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.txt similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.txt rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.txt diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.txt.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.txt.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.txt.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonRenderSeparator/SkeletonRenderSeparator.txt.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityEyeConstraint.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityEyeConstraint.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityEyeConstraint.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityEyeConstraint.cs index b2bbb79cf..9b2effb1a 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityEyeConstraint.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityEyeConstraint.cs @@ -1,87 +1,87 @@ -/****************************************************************************** - * 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 UnityEngine; -using System.Collections; - -namespace Spine.Unity.Modules { - public class SkeletonUtilityEyeConstraint : SkeletonUtilityConstraint { - public Transform[] eyes; - public float radius = 0.5f; - public Transform target; - public Vector3 targetPosition; - public float speed = 10; - Vector3[] origins; - Vector3 centerPoint; - - protected override void OnEnable () { - if (!Application.isPlaying) - return; - - base.OnEnable(); - - Bounds centerBounds = new Bounds(eyes[0].localPosition, Vector3.zero); - origins = new Vector3[eyes.Length]; - for (int i = 0; i < eyes.Length; i++) { - origins[i] = eyes[i].localPosition; - centerBounds.Encapsulate(origins[i]); - } - - centerPoint = centerBounds.center; - } - - protected override void OnDisable () { - if (!Application.isPlaying) - return; - - base.OnDisable(); - } - - public override void DoUpdate () { - - if (target != null) - targetPosition = target.position; - - Vector3 goal = targetPosition; - - Vector3 center = transform.TransformPoint(centerPoint); - Vector3 dir = goal - center; - - if (dir.magnitude > 1) - dir.Normalize(); - - for (int i = 0; i < eyes.Length; i++) { - center = transform.TransformPoint(origins[i]); - eyes[i].position = Vector3.MoveTowards(eyes[i].position, center + (dir * radius), speed * Time.deltaTime); - } - - } - } -} +/****************************************************************************** + * 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 UnityEngine; +using System.Collections; + +namespace Spine.Unity.Modules { + public class SkeletonUtilityEyeConstraint : SkeletonUtilityConstraint { + public Transform[] eyes; + public float radius = 0.5f; + public Transform target; + public Vector3 targetPosition; + public float speed = 10; + Vector3[] origins; + Vector3 centerPoint; + + protected override void OnEnable () { + if (!Application.isPlaying) + return; + + base.OnEnable(); + + Bounds centerBounds = new Bounds(eyes[0].localPosition, Vector3.zero); + origins = new Vector3[eyes.Length]; + for (int i = 0; i < eyes.Length; i++) { + origins[i] = eyes[i].localPosition; + centerBounds.Encapsulate(origins[i]); + } + + centerPoint = centerBounds.center; + } + + protected override void OnDisable () { + if (!Application.isPlaying) + return; + + base.OnDisable(); + } + + public override void DoUpdate () { + + if (target != null) + targetPosition = target.position; + + Vector3 goal = targetPosition; + + Vector3 center = transform.TransformPoint(centerPoint); + Vector3 dir = goal - center; + + if (dir.magnitude > 1) + dir.Normalize(); + + for (int i = 0; i < eyes.Length; i++) { + center = transform.TransformPoint(origins[i]); + eyes[i].position = Vector3.MoveTowards(eyes[i].position, center + (dir * radius), speed * Time.deltaTime); + } + + } + } +} diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityEyeConstraint.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityEyeConstraint.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityEyeConstraint.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityEyeConstraint.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityGroundConstraint.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityGroundConstraint.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityGroundConstraint.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityGroundConstraint.cs index 6913f037b..d8ab190bf 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityGroundConstraint.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityGroundConstraint.cs @@ -1,129 +1,129 @@ -/****************************************************************************** - * 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 UnityEngine; - -namespace Spine.Unity.Modules { - [RequireComponent(typeof(SkeletonUtilityBone)), ExecuteInEditMode] - public class SkeletonUtilityGroundConstraint : SkeletonUtilityConstraint { - - [Tooltip("LayerMask for what objects to raycast against")] - public LayerMask groundMask; - [Tooltip("Use 2D")] - public bool use2D = false; - [Tooltip("Uses SphereCast for 3D mode and CircleCast for 2D mode")] - public bool useRadius = false; - [Tooltip("The Radius")] - public float castRadius = 0.1f; - [Tooltip("How high above the target bone to begin casting from")] - public float castDistance = 5f; - [Tooltip("X-Axis adjustment")] - public float castOffset = 0; - [Tooltip("Y-Axis adjustment")] - public float groundOffset = 0; - [Tooltip("How fast the target IK position adjusts to the ground. Use smaller values to prevent snapping")] - public float adjustSpeed = 5; - - Vector3 rayOrigin; - Vector3 rayDir = new Vector3(0, -1, 0); - float hitY; - float lastHitY; - - protected override void OnEnable () { - base.OnEnable(); - lastHitY = transform.position.y; - } - - public override void DoUpdate () { - rayOrigin = transform.position + new Vector3(castOffset, castDistance, 0); - - hitY = float.MinValue; - if (use2D) { - RaycastHit2D hit; - - if (useRadius) - hit = Physics2D.CircleCast(rayOrigin, castRadius, rayDir, castDistance + groundOffset, groundMask); - else - hit = Physics2D.Raycast(rayOrigin, rayDir, castDistance + groundOffset, groundMask); - - if (hit.collider != null) { - hitY = hit.point.y + groundOffset; - if (Application.isPlaying) - hitY = Mathf.MoveTowards(lastHitY, hitY, adjustSpeed * Time.deltaTime); - } else { - if (Application.isPlaying) - hitY = Mathf.MoveTowards(lastHitY, transform.position.y, adjustSpeed * Time.deltaTime); - } - } else { - RaycastHit hit; - bool validHit = false; - - if (useRadius) - validHit = Physics.SphereCast(rayOrigin, castRadius, rayDir, out hit, castDistance + groundOffset, groundMask); - else - validHit = Physics.Raycast(rayOrigin, rayDir, out hit, castDistance + groundOffset, groundMask); - - if (validHit) { - hitY = hit.point.y + groundOffset; - if (Application.isPlaying) - hitY = Mathf.MoveTowards(lastHitY, hitY, adjustSpeed * Time.deltaTime); - - } else { - if (Application.isPlaying) - hitY = Mathf.MoveTowards(lastHitY, transform.position.y, adjustSpeed * Time.deltaTime); - } - } - - Vector3 v = transform.position; - v.y = Mathf.Clamp(v.y, Mathf.Min(lastHitY, hitY), float.MaxValue); - transform.position = v; - - utilBone.bone.X = transform.localPosition.x; - utilBone.bone.Y = transform.localPosition.y; - - lastHitY = hitY; - } - - void OnDrawGizmos () { - Vector3 hitEnd = rayOrigin + (rayDir * Mathf.Min(castDistance, rayOrigin.y - hitY)); - Vector3 clearEnd = rayOrigin + (rayDir * castDistance); - Gizmos.DrawLine(rayOrigin, hitEnd); - - if (useRadius) { - Gizmos.DrawLine(new Vector3(hitEnd.x - castRadius, hitEnd.y - groundOffset, hitEnd.z), new Vector3(hitEnd.x + castRadius, hitEnd.y - groundOffset, hitEnd.z)); - Gizmos.DrawLine(new Vector3(clearEnd.x - castRadius, clearEnd.y, clearEnd.z), new Vector3(clearEnd.x + castRadius, clearEnd.y, clearEnd.z)); - } - - Gizmos.color = Color.red; - Gizmos.DrawLine(hitEnd, clearEnd); - } - } - -} +/****************************************************************************** + * 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 UnityEngine; + +namespace Spine.Unity.Modules { + [RequireComponent(typeof(SkeletonUtilityBone)), ExecuteInEditMode] + public class SkeletonUtilityGroundConstraint : SkeletonUtilityConstraint { + + [Tooltip("LayerMask for what objects to raycast against")] + public LayerMask groundMask; + [Tooltip("Use 2D")] + public bool use2D = false; + [Tooltip("Uses SphereCast for 3D mode and CircleCast for 2D mode")] + public bool useRadius = false; + [Tooltip("The Radius")] + public float castRadius = 0.1f; + [Tooltip("How high above the target bone to begin casting from")] + public float castDistance = 5f; + [Tooltip("X-Axis adjustment")] + public float castOffset = 0; + [Tooltip("Y-Axis adjustment")] + public float groundOffset = 0; + [Tooltip("How fast the target IK position adjusts to the ground. Use smaller values to prevent snapping")] + public float adjustSpeed = 5; + + Vector3 rayOrigin; + Vector3 rayDir = new Vector3(0, -1, 0); + float hitY; + float lastHitY; + + protected override void OnEnable () { + base.OnEnable(); + lastHitY = transform.position.y; + } + + public override void DoUpdate () { + rayOrigin = transform.position + new Vector3(castOffset, castDistance, 0); + + hitY = float.MinValue; + if (use2D) { + RaycastHit2D hit; + + if (useRadius) + hit = Physics2D.CircleCast(rayOrigin, castRadius, rayDir, castDistance + groundOffset, groundMask); + else + hit = Physics2D.Raycast(rayOrigin, rayDir, castDistance + groundOffset, groundMask); + + if (hit.collider != null) { + hitY = hit.point.y + groundOffset; + if (Application.isPlaying) + hitY = Mathf.MoveTowards(lastHitY, hitY, adjustSpeed * Time.deltaTime); + } else { + if (Application.isPlaying) + hitY = Mathf.MoveTowards(lastHitY, transform.position.y, adjustSpeed * Time.deltaTime); + } + } else { + RaycastHit hit; + bool validHit = false; + + if (useRadius) + validHit = Physics.SphereCast(rayOrigin, castRadius, rayDir, out hit, castDistance + groundOffset, groundMask); + else + validHit = Physics.Raycast(rayOrigin, rayDir, out hit, castDistance + groundOffset, groundMask); + + if (validHit) { + hitY = hit.point.y + groundOffset; + if (Application.isPlaying) + hitY = Mathf.MoveTowards(lastHitY, hitY, adjustSpeed * Time.deltaTime); + + } else { + if (Application.isPlaying) + hitY = Mathf.MoveTowards(lastHitY, transform.position.y, adjustSpeed * Time.deltaTime); + } + } + + Vector3 v = transform.position; + v.y = Mathf.Clamp(v.y, Mathf.Min(lastHitY, hitY), float.MaxValue); + transform.position = v; + + utilBone.bone.X = transform.localPosition.x; + utilBone.bone.Y = transform.localPosition.y; + + lastHitY = hitY; + } + + void OnDrawGizmos () { + Vector3 hitEnd = rayOrigin + (rayDir * Mathf.Min(castDistance, rayOrigin.y - hitY)); + Vector3 clearEnd = rayOrigin + (rayDir * castDistance); + Gizmos.DrawLine(rayOrigin, hitEnd); + + if (useRadius) { + Gizmos.DrawLine(new Vector3(hitEnd.x - castRadius, hitEnd.y - groundOffset, hitEnd.z), new Vector3(hitEnd.x + castRadius, hitEnd.y - groundOffset, hitEnd.z)); + Gizmos.DrawLine(new Vector3(clearEnd.x - castRadius, clearEnd.y, clearEnd.z), new Vector3(clearEnd.x + castRadius, clearEnd.y, clearEnd.z)); + } + + Gizmos.color = Color.red; + Gizmos.DrawLine(hitEnd, clearEnd); + } + } + +} diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityGroundConstraint.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityGroundConstraint.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityGroundConstraint.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityGroundConstraint.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs index 447d37fe0..37ba9bcba 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs @@ -1,138 +1,138 @@ -/****************************************************************************** - * 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 UnityEngine; -using System.Collections.Generic; - -namespace Spine.Unity.Modules { - - // SkeletonUtilityKinematicShadow allows hinge chains to inherit a velocity interpreted from changes in parent transform position or from unrelated rigidbodies. - // Note: Uncheck "useRootTransformIfNull - public class SkeletonUtilityKinematicShadow : MonoBehaviour { - #region Inspector - [Tooltip("If checked, the hinge chain can inherit your root transform's velocity or position/rotation changes.")] - public bool detachedShadow = false; - public Transform parent; - public bool hideShadow = true; - public PhysicsSystem physicsSystem = PhysicsSystem.Physics3D; - #endregion - - GameObject shadowRoot; - readonly List shadowTable = new List(); - struct TransformPair { - public Transform dest, src; - } - - public enum PhysicsSystem { - Physics2D, - Physics3D - }; - - void Start () { - // Duplicate this gameObject as the "shadow" with a different parent. - shadowRoot = Instantiate(this.gameObject); - Destroy(shadowRoot.GetComponent()); - - // Prepare shadow gameObject's properties. - var shadowRootTransform = shadowRoot.transform; - shadowRootTransform.position = transform.position; - shadowRootTransform.rotation = transform.rotation; - - Vector3 scaleRef = transform.TransformPoint(Vector3.right); - float scale = Vector3.Distance(transform.position, scaleRef); - shadowRootTransform.localScale = Vector3.one; - - if (!detachedShadow) { - // Do not change to null coalescing operator (??). Unity overloads null checks for UnityEngine.Objects but not the ?? operator. - if (parent == null) - shadowRootTransform.parent = transform.root; - else - shadowRootTransform.parent = parent; - } - - if (hideShadow) - shadowRoot.hideFlags = HideFlags.HideInHierarchy; - - var shadowJoints = shadowRoot.GetComponentsInChildren(); - foreach (Joint j in shadowJoints) - j.connectedAnchor *= scale; - - // Build list of bone pairs (matches shadow transforms with bone transforms) - var bones = GetComponentsInChildren(); - var shadowBones = shadowRoot.GetComponentsInChildren(); - foreach (var b in bones) { - if (b.gameObject == this.gameObject) - continue; - - System.Type checkType = (physicsSystem == PhysicsSystem.Physics2D) ? typeof(Rigidbody2D) : typeof(Rigidbody); - foreach (var sb in shadowBones) { - if (sb.GetComponent(checkType) != null && sb.boneName == b.boneName) { - shadowTable.Add(new TransformPair { - dest = b.transform, - src = sb.transform - }); - break; - } - } - - } - - // Destroy conflicting and unneeded components - DestroyComponents(shadowBones); - - DestroyComponents(GetComponentsInChildren()); - DestroyComponents(GetComponentsInChildren()); - DestroyComponents(GetComponentsInChildren()); - } - - static void DestroyComponents (Component[] components) { - for (int i = 0, n = components.Length; i < n; i++) - Destroy(components[i]); - } - - void FixedUpdate () { - if (physicsSystem == PhysicsSystem.Physics2D) { - var shadowRootRigidbody = shadowRoot.GetComponent(); - shadowRootRigidbody.MovePosition(transform.position); - shadowRootRigidbody.MoveRotation(transform.rotation.eulerAngles.z); - } else { - var shadowRootRigidbody = shadowRoot.GetComponent(); - shadowRootRigidbody.MovePosition(transform.position); - shadowRootRigidbody.MoveRotation(transform.rotation); - } - - for (int i = 0, n = shadowTable.Count; i < n; i++) { - var pair = shadowTable[i]; - pair.dest.localPosition = pair.src.localPosition; - pair.dest.localRotation = pair.src.localRotation; - } - } - } -} +/****************************************************************************** + * 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 UnityEngine; +using System.Collections.Generic; + +namespace Spine.Unity.Modules { + + // SkeletonUtilityKinematicShadow allows hinge chains to inherit a velocity interpreted from changes in parent transform position or from unrelated rigidbodies. + // Note: Uncheck "useRootTransformIfNull + public class SkeletonUtilityKinematicShadow : MonoBehaviour { + #region Inspector + [Tooltip("If checked, the hinge chain can inherit your root transform's velocity or position/rotation changes.")] + public bool detachedShadow = false; + public Transform parent; + public bool hideShadow = true; + public PhysicsSystem physicsSystem = PhysicsSystem.Physics3D; + #endregion + + GameObject shadowRoot; + readonly List shadowTable = new List(); + struct TransformPair { + public Transform dest, src; + } + + public enum PhysicsSystem { + Physics2D, + Physics3D + }; + + void Start () { + // Duplicate this gameObject as the "shadow" with a different parent. + shadowRoot = Instantiate(this.gameObject); + Destroy(shadowRoot.GetComponent()); + + // Prepare shadow gameObject's properties. + var shadowRootTransform = shadowRoot.transform; + shadowRootTransform.position = transform.position; + shadowRootTransform.rotation = transform.rotation; + + Vector3 scaleRef = transform.TransformPoint(Vector3.right); + float scale = Vector3.Distance(transform.position, scaleRef); + shadowRootTransform.localScale = Vector3.one; + + if (!detachedShadow) { + // Do not change to null coalescing operator (??). Unity overloads null checks for UnityEngine.Objects but not the ?? operator. + if (parent == null) + shadowRootTransform.parent = transform.root; + else + shadowRootTransform.parent = parent; + } + + if (hideShadow) + shadowRoot.hideFlags = HideFlags.HideInHierarchy; + + var shadowJoints = shadowRoot.GetComponentsInChildren(); + foreach (Joint j in shadowJoints) + j.connectedAnchor *= scale; + + // Build list of bone pairs (matches shadow transforms with bone transforms) + var bones = GetComponentsInChildren(); + var shadowBones = shadowRoot.GetComponentsInChildren(); + foreach (var b in bones) { + if (b.gameObject == this.gameObject) + continue; + + System.Type checkType = (physicsSystem == PhysicsSystem.Physics2D) ? typeof(Rigidbody2D) : typeof(Rigidbody); + foreach (var sb in shadowBones) { + if (sb.GetComponent(checkType) != null && sb.boneName == b.boneName) { + shadowTable.Add(new TransformPair { + dest = b.transform, + src = sb.transform + }); + break; + } + } + + } + + // Destroy conflicting and unneeded components + DestroyComponents(shadowBones); + + DestroyComponents(GetComponentsInChildren()); + DestroyComponents(GetComponentsInChildren()); + DestroyComponents(GetComponentsInChildren()); + } + + static void DestroyComponents (Component[] components) { + for (int i = 0, n = components.Length; i < n; i++) + Destroy(components[i]); + } + + void FixedUpdate () { + if (physicsSystem == PhysicsSystem.Physics2D) { + var shadowRootRigidbody = shadowRoot.GetComponent(); + shadowRootRigidbody.MovePosition(transform.position); + shadowRootRigidbody.MoveRotation(transform.rotation.eulerAngles.z); + } else { + var shadowRootRigidbody = shadowRoot.GetComponent(); + shadowRootRigidbody.MovePosition(transform.position); + shadowRootRigidbody.MoveRotation(transform.rotation); + } + + for (int i = 0, n = shadowTable.Count; i < n; i++) { + var pair = shadowTable[i]; + pair.dest.localPosition = pair.src.localPosition; + pair.dest.localRotation = pair.src.localRotation; + } + } + } +} diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SkeletonPMAMultiply.mat b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAMultiply.mat similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SkeletonPMAMultiply.mat rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAMultiply.mat diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SkeletonPMAMultiply.mat.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAMultiply.mat.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SkeletonPMAMultiply.mat.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAMultiply.mat.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SkeletonPMAScreen.mat b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAScreen.mat similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SkeletonPMAScreen.mat rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAScreen.mat diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SkeletonPMAScreen.mat.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAScreen.mat.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SkeletonPMAScreen.mat.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SkeletonPMAScreen.mat.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SlotBlendModes.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SlotBlendModes.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SlotBlendModes.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SlotBlendModes.cs diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SlotBlendModes.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SlotBlendModes.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/SlotBlendModes.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/SlotBlendModes.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Multiply.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Multiply.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Multiply.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Multiply.shader diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Multiply.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Multiply.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Multiply.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Multiply.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Screen.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Screen.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Screen.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Screen.shader diff --git a/spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Screen.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Screen.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Screen.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SlotBlendModes/Spine-Skeleton-PMA-Screen.shader.meta diff --git a/spine-unity/Assets/spine-unity/Modules/TK2D.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/TK2D.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/TK2D.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/TK2D.meta diff --git a/spine-unity/Assets/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs index 36ecb7268..842c438ed 100644 --- a/spine-unity/Assets/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs @@ -1,157 +1,157 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -#if SPINE_TK2D -using System; -using UnityEngine; -using Spine; - -// MITCH: handle TPackerCW flip mode (probably not swap uv horizontaly) -namespace Spine.Unity.TK2D { - public class SpriteCollectionAttachmentLoader : AttachmentLoader { - private tk2dSpriteCollectionData sprites; - private float u, v, u2, v2; - private bool regionRotated; - private float regionOriginalWidth, regionOriginalHeight; - private float regionWidth, regionHeight; - private float regionOffsetX, regionOffsetY; - private Material material; - - public SpriteCollectionAttachmentLoader (tk2dSpriteCollectionData sprites) { - if (sprites == null) - throw new ArgumentNullException("sprites cannot be null."); - this.sprites = sprites; - } - - private void ProcessSpriteDefinition (String name) { - // Strip folder names. - int index = name.LastIndexOfAny(new char[] {'/', '\\'}); - if (index != -1) - name = name.Substring(index + 1); - - tk2dSpriteDefinition def = sprites.inst.GetSpriteDefinition(name); - - if (def == null) { - Debug.Log("Sprite not found in atlas: " + name, sprites); - throw new Exception("Sprite not found in atlas: " + name); - } - if (def.complexGeometry) - throw new NotImplementedException("Complex geometry is not supported: " + name); - if (def.flipped == tk2dSpriteDefinition.FlipMode.TPackerCW) - throw new NotImplementedException("Only 2D Toolkit atlases are supported: " + name); - - Vector2 minTexCoords = Vector2.one, maxTexCoords = Vector2.zero; - for (int i = 0; i < def.uvs.Length; ++i) { - Vector2 uv = def.uvs[i]; - minTexCoords = Vector2.Min(minTexCoords, uv); - maxTexCoords = Vector2.Max(maxTexCoords, uv); - } - regionRotated = def.flipped == tk2dSpriteDefinition.FlipMode.Tk2d; - if (regionRotated) { - float temp = minTexCoords.x; - minTexCoords.x = maxTexCoords.x; - maxTexCoords.x = temp; - } - u = minTexCoords.x; - v = maxTexCoords.y; - u2 = maxTexCoords.x; - v2 = minTexCoords.y; - - regionOriginalWidth = (int)(def.untrimmedBoundsData[1].x / def.texelSize.x); - regionOriginalHeight = (int)(def.untrimmedBoundsData[1].y / def.texelSize.y); - - regionWidth = (int)(def.boundsData[1].x / def.texelSize.x); - regionHeight = (int)(def.boundsData[1].y / def.texelSize.y); - - float x0 = def.untrimmedBoundsData[0].x - def.untrimmedBoundsData[1].x / 2; - float x1 = def.boundsData[0].x - def.boundsData[1].x / 2; - regionOffsetX = (int)((x1 - x0) / def.texelSize.x); - - float y0 = def.untrimmedBoundsData[0].y - def.untrimmedBoundsData[1].y / 2; - float y1 = def.boundsData[0].y - def.boundsData[1].y / 2; - regionOffsetY = (int)((y1 - y0) / def.texelSize.y); - - material = def.materialInst; - } - - public RegionAttachment NewRegionAttachment (Skin skin, String name, String path) { - ProcessSpriteDefinition(path); - - RegionAttachment region = new RegionAttachment(name); - region.Path = path; - region.RendererObject = material; - region.SetUVs(u, v, u2, v2, regionRotated); - region.RegionOriginalWidth = regionOriginalWidth; - region.RegionOriginalHeight = regionOriginalHeight; - region.RegionWidth = regionWidth; - region.RegionHeight = regionHeight; - region.RegionOffsetX = regionOffsetX; - region.RegionOffsetY = regionOffsetY; - return region; - } - - public MeshAttachment NewMeshAttachment (Skin skin, String name, String path) { - ProcessSpriteDefinition(path); - - MeshAttachment mesh = new MeshAttachment(name); - mesh.Path = path; - mesh.RendererObject = material; - mesh.RegionU = u; - mesh.RegionV = v; - mesh.RegionU2 = u2; - mesh.RegionV2 = v2; - mesh.RegionRotate = regionRotated; - mesh.RegionOriginalWidth = regionOriginalWidth; - mesh.RegionOriginalHeight = regionOriginalHeight; - mesh.RegionWidth = regionWidth; - mesh.RegionHeight = regionHeight; - mesh.RegionOffsetX = regionOffsetX; - mesh.RegionOffsetY = regionOffsetY; - return mesh; - } - - 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); - } - } -} -#endif +/****************************************************************************** + * 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. + *****************************************************************************/ + +#if SPINE_TK2D +using System; +using UnityEngine; +using Spine; + +// MITCH: handle TPackerCW flip mode (probably not swap uv horizontaly) +namespace Spine.Unity.TK2D { + public class SpriteCollectionAttachmentLoader : AttachmentLoader { + private tk2dSpriteCollectionData sprites; + private float u, v, u2, v2; + private bool regionRotated; + private float regionOriginalWidth, regionOriginalHeight; + private float regionWidth, regionHeight; + private float regionOffsetX, regionOffsetY; + private Material material; + + public SpriteCollectionAttachmentLoader (tk2dSpriteCollectionData sprites) { + if (sprites == null) + throw new ArgumentNullException("sprites cannot be null."); + this.sprites = sprites; + } + + private void ProcessSpriteDefinition (String name) { + // Strip folder names. + int index = name.LastIndexOfAny(new char[] {'/', '\\'}); + if (index != -1) + name = name.Substring(index + 1); + + tk2dSpriteDefinition def = sprites.inst.GetSpriteDefinition(name); + + if (def == null) { + Debug.Log("Sprite not found in atlas: " + name, sprites); + throw new Exception("Sprite not found in atlas: " + name); + } + if (def.complexGeometry) + throw new NotImplementedException("Complex geometry is not supported: " + name); + if (def.flipped == tk2dSpriteDefinition.FlipMode.TPackerCW) + throw new NotImplementedException("Only 2D Toolkit atlases are supported: " + name); + + Vector2 minTexCoords = Vector2.one, maxTexCoords = Vector2.zero; + for (int i = 0; i < def.uvs.Length; ++i) { + Vector2 uv = def.uvs[i]; + minTexCoords = Vector2.Min(minTexCoords, uv); + maxTexCoords = Vector2.Max(maxTexCoords, uv); + } + regionRotated = def.flipped == tk2dSpriteDefinition.FlipMode.Tk2d; + if (regionRotated) { + float temp = minTexCoords.x; + minTexCoords.x = maxTexCoords.x; + maxTexCoords.x = temp; + } + u = minTexCoords.x; + v = maxTexCoords.y; + u2 = maxTexCoords.x; + v2 = minTexCoords.y; + + regionOriginalWidth = (int)(def.untrimmedBoundsData[1].x / def.texelSize.x); + regionOriginalHeight = (int)(def.untrimmedBoundsData[1].y / def.texelSize.y); + + regionWidth = (int)(def.boundsData[1].x / def.texelSize.x); + regionHeight = (int)(def.boundsData[1].y / def.texelSize.y); + + float x0 = def.untrimmedBoundsData[0].x - def.untrimmedBoundsData[1].x / 2; + float x1 = def.boundsData[0].x - def.boundsData[1].x / 2; + regionOffsetX = (int)((x1 - x0) / def.texelSize.x); + + float y0 = def.untrimmedBoundsData[0].y - def.untrimmedBoundsData[1].y / 2; + float y1 = def.boundsData[0].y - def.boundsData[1].y / 2; + regionOffsetY = (int)((y1 - y0) / def.texelSize.y); + + material = def.materialInst; + } + + public RegionAttachment NewRegionAttachment (Skin skin, String name, String path) { + ProcessSpriteDefinition(path); + + RegionAttachment region = new RegionAttachment(name); + region.Path = path; + region.RendererObject = material; + region.SetUVs(u, v, u2, v2, regionRotated); + region.RegionOriginalWidth = regionOriginalWidth; + region.RegionOriginalHeight = regionOriginalHeight; + region.RegionWidth = regionWidth; + region.RegionHeight = regionHeight; + region.RegionOffsetX = regionOffsetX; + region.RegionOffsetY = regionOffsetY; + return region; + } + + public MeshAttachment NewMeshAttachment (Skin skin, String name, String path) { + ProcessSpriteDefinition(path); + + MeshAttachment mesh = new MeshAttachment(name); + mesh.Path = path; + mesh.RendererObject = material; + mesh.RegionU = u; + mesh.RegionV = v; + mesh.RegionU2 = u2; + mesh.RegionV2 = v2; + mesh.RegionRotate = regionRotated; + mesh.RegionOriginalWidth = regionOriginalWidth; + mesh.RegionOriginalHeight = regionOriginalHeight; + mesh.RegionWidth = regionWidth; + mesh.RegionHeight = regionHeight; + mesh.RegionOffsetX = regionOffsetX; + mesh.RegionOffsetY = regionOffsetY; + return mesh; + } + + 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); + } + } +} +#endif diff --git a/spine-unity/Assets/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/TK2D/SpriteCollectionAttachmentLoader.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/Documentation.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/Documentation.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/README.md b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/README.md similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/README.md rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/README.md diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/README.md.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/README.md.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/README.md.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/README.md.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/add-menu.png b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/add-menu.png similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/add-menu.png rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/add-menu.png diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/add-menu.png.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/add-menu.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/add-menu.png.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/add-menu.png.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/animationstate-clip-inspector.png b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/animationstate-clip-inspector.png similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/animationstate-clip-inspector.png rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/animationstate-clip-inspector.png diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/animationstate-clip-inspector.png.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/animationstate-clip-inspector.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/animationstate-clip-inspector.png.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/animationstate-clip-inspector.png.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/skeleton-flip-clip-inspector.png b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/skeleton-flip-clip-inspector.png similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/skeleton-flip-clip-inspector.png rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/skeleton-flip-clip-inspector.png diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/skeleton-flip-clip-inspector.png.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/skeleton-flip-clip-inspector.png.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/Documentation/skeleton-flip-clip-inspector.png.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/Documentation/skeleton-flip-clip-inspector.png.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/PlayableHandle Component.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/PlayableHandle Component.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/PlayableHandle Component.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/PlayableHandle Component.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/PlayableHandle Component/SkeletonAnimationPlayableHandle.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/PlayableHandle Component/SkeletonAnimationPlayableHandle.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/PlayableHandle Component/SkeletonAnimationPlayableHandle.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/PlayableHandle Component/SkeletonAnimationPlayableHandle.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/PlayableHandle Component/SkeletonAnimationPlayableHandle.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/PlayableHandle Component/SkeletonAnimationPlayableHandle.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/PlayableHandle Component/SkeletonAnimationPlayableHandle.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/PlayableHandle Component/SkeletonAnimationPlayableHandle.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/PlayableHandle Component/SpinePlayableHandleBase.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/PlayableHandle Component/SpinePlayableHandleBase.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/PlayableHandle Component/SpinePlayableHandleBase.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/PlayableHandle Component/SpinePlayableHandleBase.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/PlayableHandle Component/SpinePlayableHandleBase.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/PlayableHandle Component/SpinePlayableHandleBase.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/PlayableHandle Component/SpinePlayableHandleBase.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/PlayableHandle Component/SpinePlayableHandleBase.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateBehaviour.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateBehaviour.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateBehaviour.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateBehaviour.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateBehaviour.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateBehaviour.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateBehaviour.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateBehaviour.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateClip.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateClip.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateClip.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateClip.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateClip.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateClip.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateClip.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateClip.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateTrack.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateTrack.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateTrack.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateTrack.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateTrack.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateTrack.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateTrack.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateTrack.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipBehaviour.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipBehaviour.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipBehaviour.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipBehaviour.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipBehaviour.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipBehaviour.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipBehaviour.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipBehaviour.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipClip.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipClip.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipClip.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipClip.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipClip.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipClip.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipClip.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipClip.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipMixerBehaviour.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipMixerBehaviour.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipMixerBehaviour.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipMixerBehaviour.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipMixerBehaviour.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipMixerBehaviour.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipMixerBehaviour.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipMixerBehaviour.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipTrack.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipTrack.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipTrack.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipTrack.cs diff --git a/spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipTrack.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipTrack.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipTrack.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipTrack.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/YieldInstructions.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/YieldInstructions.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions.meta diff --git a/spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineAnimationComplete.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineAnimationComplete.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineAnimationComplete.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineAnimationComplete.cs index 535fdd6b0..13f219cca 100644 --- a/spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineAnimationComplete.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineAnimationComplete.cs @@ -1,86 +1,86 @@ -/****************************************************************************** - * 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 UnityEngine; -using System.Collections; -using Spine; - -namespace Spine.Unity { - /// - /// Use this as a condition-blocking yield instruction for Unity Coroutines. - /// The routine will pause until the AnimationState.TrackEntry fires its Complete event. - public class WaitForSpineAnimationComplete : IEnumerator { - - bool m_WasFired = false; - - public WaitForSpineAnimationComplete (Spine.TrackEntry trackEntry) { - SafeSubscribe(trackEntry); - } - - void HandleComplete (TrackEntry trackEntry) { - m_WasFired = true; - } - - void SafeSubscribe (Spine.TrackEntry trackEntry) { - if (trackEntry == null) { - // Break immediately if trackEntry is null. - Debug.LogWarning("TrackEntry was null. Coroutine will continue immediately."); - m_WasFired = true; - } else { - trackEntry.Complete += HandleComplete; - } - } - - #region Reuse - /// - /// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure. - /// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationComplete. - public WaitForSpineAnimationComplete NowWaitFor (Spine.TrackEntry trackEntry) { - SafeSubscribe(trackEntry); - return this; - } - #endregion - - #region IEnumerator - bool IEnumerator.MoveNext () { - if (m_WasFired) { - ((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse - return false; - } - - return true; - } - void IEnumerator.Reset () { m_WasFired = false; } - object IEnumerator.Current { get { return null; } } - #endregion - - } - -} +/****************************************************************************** + * 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 UnityEngine; +using System.Collections; +using Spine; + +namespace Spine.Unity { + /// + /// Use this as a condition-blocking yield instruction for Unity Coroutines. + /// The routine will pause until the AnimationState.TrackEntry fires its Complete event. + public class WaitForSpineAnimationComplete : IEnumerator { + + bool m_WasFired = false; + + public WaitForSpineAnimationComplete (Spine.TrackEntry trackEntry) { + SafeSubscribe(trackEntry); + } + + void HandleComplete (TrackEntry trackEntry) { + m_WasFired = true; + } + + void SafeSubscribe (Spine.TrackEntry trackEntry) { + if (trackEntry == null) { + // Break immediately if trackEntry is null. + Debug.LogWarning("TrackEntry was null. Coroutine will continue immediately."); + m_WasFired = true; + } else { + trackEntry.Complete += HandleComplete; + } + } + + #region Reuse + /// + /// One optimization high-frequency YieldInstruction returns is to cache instances to minimize GC pressure. + /// Use NowWaitFor to reuse the same instance of WaitForSpineAnimationComplete. + public WaitForSpineAnimationComplete NowWaitFor (Spine.TrackEntry trackEntry) { + SafeSubscribe(trackEntry); + return this; + } + #endregion + + #region IEnumerator + bool IEnumerator.MoveNext () { + if (m_WasFired) { + ((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse + return false; + } + + return true; + } + void IEnumerator.Reset () { m_WasFired = false; } + object IEnumerator.Current { get { return null; } } + #endregion + + } + +} diff --git a/spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineAnimationComplete.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineAnimationComplete.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineAnimationComplete.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineAnimationComplete.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineEvent.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineEvent.cs similarity index 97% rename from spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineEvent.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineEvent.cs index 9f619c6f8..38a9e65fc 100644 --- a/spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineEvent.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineEvent.cs @@ -1,160 +1,160 @@ -/****************************************************************************** - * 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 UnityEngine; -using System.Collections; -using Spine; - -namespace Spine.Unity { - /// - /// Use this as a condition-blocking yield instruction for Unity Coroutines. - /// The routine will pause until the AnimationState fires an event matching the given event name or EventData reference. - public class WaitForSpineEvent : IEnumerator { - - Spine.EventData m_TargetEvent; - string m_EventName; - Spine.AnimationState m_AnimationState; - - bool m_WasFired = false; - bool m_unsubscribeAfterFiring = false; - - #region Constructors - void Subscribe (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribe) { - if (state == null) { - Debug.LogWarning("AnimationState argument was null. Coroutine will continue immediately."); - m_WasFired = true; - return; - } else if (eventDataReference == null) { - Debug.LogWarning("eventDataReference argument was null. Coroutine will continue immediately."); - m_WasFired = true; - return; - } - - m_AnimationState = state; - m_TargetEvent = eventDataReference; - state.Event += HandleAnimationStateEvent; - - m_unsubscribeAfterFiring = unsubscribe; - - } - - void SubscribeByName (Spine.AnimationState state, string eventName, bool unsubscribe) { - if (state == null) { - Debug.LogWarning("AnimationState argument was null. Coroutine will continue immediately."); - m_WasFired = true; - return; - } else if (string.IsNullOrEmpty(eventName)) { - Debug.LogWarning("eventName argument was null. Coroutine will continue immediately."); - m_WasFired = true; - return; - } - - m_AnimationState = state; - m_EventName = eventName; - state.Event += HandleAnimationStateEventByName; - - m_unsubscribeAfterFiring = unsubscribe; - } - - public WaitForSpineEvent (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) { - Subscribe(state, eventDataReference, unsubscribeAfterFiring); - } - - public WaitForSpineEvent (SkeletonAnimation skeletonAnimation, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) { - // If skeletonAnimation is invalid, its state will be null. Subscribe handles null states just fine. - Subscribe(skeletonAnimation.state, eventDataReference, unsubscribeAfterFiring); - } - - public WaitForSpineEvent (Spine.AnimationState state, string eventName, bool unsubscribeAfterFiring = true) { - SubscribeByName(state, eventName, unsubscribeAfterFiring); - } - - public WaitForSpineEvent (SkeletonAnimation skeletonAnimation, string eventName, bool unsubscribeAfterFiring = true) { - // If skeletonAnimation is invalid, its state will be null. Subscribe handles null states just fine. - SubscribeByName(skeletonAnimation.state, eventName, unsubscribeAfterFiring); - } - #endregion - - #region Event Handlers - void HandleAnimationStateEventByName (Spine.TrackEntry trackEntry, Spine.Event e) { - m_WasFired |= (e.Data.Name == m_EventName); // Check event name string match. - if (m_WasFired && m_unsubscribeAfterFiring) - m_AnimationState.Event -= HandleAnimationStateEventByName; // Unsubscribe after correct event fires. - } - - void HandleAnimationStateEvent (Spine.TrackEntry trackEntry, Spine.Event e) { - m_WasFired |= (e.Data == m_TargetEvent); // Check event data reference match. - if (m_WasFired && m_unsubscribeAfterFiring) - m_AnimationState.Event -= HandleAnimationStateEvent; // Usubscribe after correct event fires. - } - #endregion - - #region Reuse - /// - /// By default, WaitForSpineEvent will unsubscribe from the event immediately after it fires a correct matching event. - /// If you want to reuse this WaitForSpineEvent instance on the same event, you can set this to false. - public bool WillUnsubscribeAfterFiring { get { return m_unsubscribeAfterFiring; } set { m_unsubscribeAfterFiring = value; } } - - public WaitForSpineEvent NowWaitFor (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) { - ((IEnumerator)this).Reset(); - Clear(state); - Subscribe(state, eventDataReference, unsubscribeAfterFiring); - - return this; - } - - public WaitForSpineEvent NowWaitFor (Spine.AnimationState state, string eventName, bool unsubscribeAfterFiring = true) { - ((IEnumerator)this).Reset(); - Clear(state); - SubscribeByName(state, eventName, unsubscribeAfterFiring); - - return this; - } - - void Clear (Spine.AnimationState state) { - state.Event -= HandleAnimationStateEvent; - state.Event -= HandleAnimationStateEventByName; - } - #endregion - - #region IEnumerator - bool IEnumerator.MoveNext () { - if (m_WasFired) { - ((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse - return false; - } - - return true; - } - void IEnumerator.Reset () { m_WasFired = false; } - object IEnumerator.Current { get { return null; } } - #endregion - } -} +/****************************************************************************** + * 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 UnityEngine; +using System.Collections; +using Spine; + +namespace Spine.Unity { + /// + /// Use this as a condition-blocking yield instruction for Unity Coroutines. + /// The routine will pause until the AnimationState fires an event matching the given event name or EventData reference. + public class WaitForSpineEvent : IEnumerator { + + Spine.EventData m_TargetEvent; + string m_EventName; + Spine.AnimationState m_AnimationState; + + bool m_WasFired = false; + bool m_unsubscribeAfterFiring = false; + + #region Constructors + void Subscribe (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribe) { + if (state == null) { + Debug.LogWarning("AnimationState argument was null. Coroutine will continue immediately."); + m_WasFired = true; + return; + } else if (eventDataReference == null) { + Debug.LogWarning("eventDataReference argument was null. Coroutine will continue immediately."); + m_WasFired = true; + return; + } + + m_AnimationState = state; + m_TargetEvent = eventDataReference; + state.Event += HandleAnimationStateEvent; + + m_unsubscribeAfterFiring = unsubscribe; + + } + + void SubscribeByName (Spine.AnimationState state, string eventName, bool unsubscribe) { + if (state == null) { + Debug.LogWarning("AnimationState argument was null. Coroutine will continue immediately."); + m_WasFired = true; + return; + } else if (string.IsNullOrEmpty(eventName)) { + Debug.LogWarning("eventName argument was null. Coroutine will continue immediately."); + m_WasFired = true; + return; + } + + m_AnimationState = state; + m_EventName = eventName; + state.Event += HandleAnimationStateEventByName; + + m_unsubscribeAfterFiring = unsubscribe; + } + + public WaitForSpineEvent (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) { + Subscribe(state, eventDataReference, unsubscribeAfterFiring); + } + + public WaitForSpineEvent (SkeletonAnimation skeletonAnimation, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) { + // If skeletonAnimation is invalid, its state will be null. Subscribe handles null states just fine. + Subscribe(skeletonAnimation.state, eventDataReference, unsubscribeAfterFiring); + } + + public WaitForSpineEvent (Spine.AnimationState state, string eventName, bool unsubscribeAfterFiring = true) { + SubscribeByName(state, eventName, unsubscribeAfterFiring); + } + + public WaitForSpineEvent (SkeletonAnimation skeletonAnimation, string eventName, bool unsubscribeAfterFiring = true) { + // If skeletonAnimation is invalid, its state will be null. Subscribe handles null states just fine. + SubscribeByName(skeletonAnimation.state, eventName, unsubscribeAfterFiring); + } + #endregion + + #region Event Handlers + void HandleAnimationStateEventByName (Spine.TrackEntry trackEntry, Spine.Event e) { + m_WasFired |= (e.Data.Name == m_EventName); // Check event name string match. + if (m_WasFired && m_unsubscribeAfterFiring) + m_AnimationState.Event -= HandleAnimationStateEventByName; // Unsubscribe after correct event fires. + } + + void HandleAnimationStateEvent (Spine.TrackEntry trackEntry, Spine.Event e) { + m_WasFired |= (e.Data == m_TargetEvent); // Check event data reference match. + if (m_WasFired && m_unsubscribeAfterFiring) + m_AnimationState.Event -= HandleAnimationStateEvent; // Usubscribe after correct event fires. + } + #endregion + + #region Reuse + /// + /// By default, WaitForSpineEvent will unsubscribe from the event immediately after it fires a correct matching event. + /// If you want to reuse this WaitForSpineEvent instance on the same event, you can set this to false. + public bool WillUnsubscribeAfterFiring { get { return m_unsubscribeAfterFiring; } set { m_unsubscribeAfterFiring = value; } } + + public WaitForSpineEvent NowWaitFor (Spine.AnimationState state, Spine.EventData eventDataReference, bool unsubscribeAfterFiring = true) { + ((IEnumerator)this).Reset(); + Clear(state); + Subscribe(state, eventDataReference, unsubscribeAfterFiring); + + return this; + } + + public WaitForSpineEvent NowWaitFor (Spine.AnimationState state, string eventName, bool unsubscribeAfterFiring = true) { + ((IEnumerator)this).Reset(); + Clear(state); + SubscribeByName(state, eventName, unsubscribeAfterFiring); + + return this; + } + + void Clear (Spine.AnimationState state) { + state.Event -= HandleAnimationStateEvent; + state.Event -= HandleAnimationStateEventByName; + } + #endregion + + #region IEnumerator + bool IEnumerator.MoveNext () { + if (m_WasFired) { + ((IEnumerator)this).Reset(); // auto-reset for YieldInstruction reuse + return false; + } + + return true; + } + void IEnumerator.Reset () { m_WasFired = false; } + object IEnumerator.Current { get { return null; } } + #endregion + } +} diff --git a/spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineEvent.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineEvent.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineEvent.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineEvent.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineTrackEntryEnd.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineTrackEntryEnd.cs similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineTrackEntryEnd.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineTrackEntryEnd.cs diff --git a/spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineTrackEntryEnd.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineTrackEntryEnd.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Modules/YieldInstructions/WaitForSpineTrackEntryEnd.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Modules/YieldInstructions/WaitForSpineTrackEntryEnd.cs.meta diff --git a/spine-unity/Assets/spine-unity/Shaders.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders.meta diff --git a/spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader diff --git a/spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader.meta diff --git a/spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader diff --git a/spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader.meta diff --git a/spine-unity/Assets/spine-unity/Shaders/Spine-SkeletonLit.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-SkeletonLit.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Spine-SkeletonLit.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-SkeletonLit.shader diff --git a/spine-unity/Assets/spine-unity/Shaders/Spine-SkeletonLit.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-SkeletonLit.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Spine-SkeletonLit.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-SkeletonLit.shader.meta diff --git a/spine-unity/Assets/spine-unity/Shaders/Utility.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Utility.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility.meta diff --git a/spine-unity/Assets/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader diff --git a/spine-unity/Assets/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader.meta diff --git a/spine-unity/Assets/spine-unity/Shaders/Utility/HiddenPass.mat b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.mat similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Utility/HiddenPass.mat rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.mat diff --git a/spine-unity/Assets/spine-unity/Shaders/Utility/HiddenPass.mat.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.mat.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Utility/HiddenPass.mat.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.mat.meta diff --git a/spine-unity/Assets/spine-unity/Shaders/Utility/HiddenPass.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.shader similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Utility/HiddenPass.shader rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.shader diff --git a/spine-unity/Assets/spine-unity/Shaders/Utility/HiddenPass.shader.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.shader.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Shaders/Utility/HiddenPass.shader.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Utility/HiddenPass.shader.meta diff --git a/spine-unity/Assets/spine-unity/SkeletonExtensions.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonExtensions.cs similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonExtensions.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonExtensions.cs diff --git a/spine-unity/Assets/spine-unity/SkeletonExtensions.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonExtensions.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonExtensions.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonExtensions.cs.meta diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility.meta similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonUtility.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility.meta diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtility.cs similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtility.cs diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtility.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtility.cs.meta diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs.meta diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs similarity index 97% rename from spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs index fb5799ca6..0caefadf3 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs @@ -1,54 +1,54 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -// Contributed by: Mitch Thompson - -using UnityEngine; - -namespace Spine.Unity { - [RequireComponent(typeof(SkeletonUtilityBone)), ExecuteInEditMode] - public abstract class SkeletonUtilityConstraint : MonoBehaviour { - - protected SkeletonUtilityBone utilBone; - protected SkeletonUtility skeletonUtility; - - protected virtual void OnEnable () { - utilBone = GetComponent(); - skeletonUtility = transform.GetComponentInParent(); - skeletonUtility.RegisterConstraint(this); - } - - protected virtual void OnDisable () { - skeletonUtility.UnregisterConstraint(this); - } - - public abstract void DoUpdate (); - } -} +/****************************************************************************** + * 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. + *****************************************************************************/ + +// Contributed by: Mitch Thompson + +using UnityEngine; + +namespace Spine.Unity { + [RequireComponent(typeof(SkeletonUtilityBone)), ExecuteInEditMode] + public abstract class SkeletonUtilityConstraint : MonoBehaviour { + + protected SkeletonUtilityBone utilBone; + protected SkeletonUtility skeletonUtility; + + protected virtual void OnEnable () { + utilBone = GetComponent(); + skeletonUtility = transform.GetComponentInParent(); + skeletonUtility.RegisterConstraint(this); + } + + protected virtual void OnDisable () { + skeletonUtility.UnregisterConstraint(this); + } + + public abstract void DoUpdate (); + } +} diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs.meta diff --git a/spine-unity/Assets/spine-unity/SpineAttributes.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/SpineAttributes.cs similarity index 100% rename from spine-unity/Assets/spine-unity/SpineAttributes.cs rename to spine-unity/Assets/Spine/Runtime/spine-unity/SpineAttributes.cs diff --git a/spine-unity/Assets/spine-unity/SpineAttributes.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/SpineAttributes.cs.meta similarity index 100% rename from spine-unity/Assets/spine-unity/SpineAttributes.cs.meta rename to spine-unity/Assets/Spine/Runtime/spine-unity/SpineAttributes.cs.meta diff --git a/spine-unity/Assets/spine-unity/version.txt b/spine-unity/Assets/Spine/version.txt similarity index 100% rename from spine-unity/Assets/spine-unity/version.txt rename to spine-unity/Assets/Spine/version.txt diff --git a/spine-unity/Assets/spine-unity/version.txt.meta b/spine-unity/Assets/Spine/version.txt.meta similarity index 100% rename from spine-unity/Assets/spine-unity/version.txt.meta rename to spine-unity/Assets/Spine/version.txt.meta diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysMeshGenerator.cs.meta b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysMeshGenerator.cs.meta deleted file mode 100644 index e2048bb20..000000000 --- a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysMeshGenerator.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: ed047fa8737dedb4081579983c193db5 -timeCreated: 1458124926 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSimpleMeshGenerator.cs b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSimpleMeshGenerator.cs deleted file mode 100644 index e69de29bb..000000000 diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSimpleMeshGenerator.cs.meta b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSimpleMeshGenerator.cs.meta deleted file mode 100644 index 72f63e4b0..000000000 --- a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSimpleMeshGenerator.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 296d4c2077fb3bc4fa9a5211c0f95011 -timeCreated: 1455406990 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSubmeshSetMeshGenerator.cs b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSubmeshSetMeshGenerator.cs deleted file mode 100644 index e69de29bb..000000000 diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSubmeshSetMeshGenerator.cs.meta b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSubmeshSetMeshGenerator.cs.meta deleted file mode 100644 index 88a01687a..000000000 --- a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSubmeshSetMeshGenerator.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 11ba077d7d984814db31d054192be532 -timeCreated: 1458047178 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSubmeshedMeshGenerator.cs b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSubmeshedMeshGenerator.cs deleted file mode 100644 index e69de29bb..000000000 diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSubmeshedMeshGenerator.cs.meta b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSubmeshedMeshGenerator.cs.meta deleted file mode 100644 index 81ce28428..000000000 --- a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ArraysSubmeshedMeshGenerator.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 412898b02d5caaf489b3ffb29e4ae1c0 -timeCreated: 1455407003 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/DoubleBufferedMesh.cs b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/DoubleBufferedMesh.cs deleted file mode 100644 index e69de29bb..000000000 diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/DoubleBufferedMesh.cs.meta b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/DoubleBufferedMesh.cs.meta deleted file mode 100644 index 8114723f9..000000000 --- a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/DoubleBufferedMesh.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 7191a70dcf4959f43961fa78e05484a0 -timeCreated: 1455140057 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ISimpleMeshGenerator.cs b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ISimpleMeshGenerator.cs deleted file mode 100644 index e69de29bb..000000000 diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ISimpleMeshGenerator.cs.meta b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ISimpleMeshGenerator.cs.meta deleted file mode 100644 index 41c9e5a9b..000000000 --- a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ISimpleMeshGenerator.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 0af0615ce8e0e054ea224e3e03ab31aa -timeCreated: 1455406790 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ISubmeshedMeshGenerator.cs b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ISubmeshedMeshGenerator.cs deleted file mode 100644 index e69de29bb..000000000 diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ISubmeshedMeshGenerator.cs.meta b/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ISubmeshedMeshGenerator.cs.meta deleted file mode 100644 index 85782f9f9..000000000 --- a/spine-unity/Assets/spine-unity/Mesh Generation/Unused/ISubmeshedMeshGenerator.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 7492a8ff24ea1884f92307ab1121e451 -timeCreated: 1458046464 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: