From a4443caca4f8f5c8a4b2f00e93b73fbb1e4631d6 Mon Sep 17 00:00:00 2001 From: Fenrisul Date: Wed, 3 Sep 2014 20:15:03 -0700 Subject: [PATCH 1/8] WORKAROUND: for "ik" entry missing from exported JSON parsing fail Spine C# --- spine-csharp/src/SkeletonJson.cs | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/spine-csharp/src/SkeletonJson.cs b/spine-csharp/src/SkeletonJson.cs index e97102c3d..224af335a 100644 --- a/spine-csharp/src/SkeletonJson.cs +++ b/spine-csharp/src/SkeletonJson.cs @@ -120,23 +120,25 @@ namespace Spine { } // IK constraints. - foreach (Dictionary ikMap in (List)root["ik"]) { - IkConstraintData ikConstraintData = new IkConstraintData((String)ikMap["name"]); + if(root.ContainsKey("ik")){ + foreach (Dictionary ikMap in (List)root["ik"]) { + IkConstraintData ikConstraintData = new IkConstraintData((String)ikMap["name"]); - foreach (String boneName in (List)ikMap["bones"]) { - BoneData bone = skeletonData.FindBone(boneName); - if (bone == null) throw new Exception("IK bone not found: " + boneName); - ikConstraintData.bones.Add(bone); + foreach (String boneName in (List)ikMap["bones"]) { + BoneData bone = skeletonData.FindBone(boneName); + if (bone == null) throw new Exception("IK bone not found: " + boneName); + ikConstraintData.bones.Add(bone); + } + + String targetName = (String)ikMap["target"]; + ikConstraintData.target = skeletonData.FindBone(targetName); + if (ikConstraintData.target == null) throw new Exception("Target bone not found: " + targetName); + + ikConstraintData.bendDirection = GetBoolean(ikMap, "bendPositive", true) ? 1 : -1; + ikConstraintData.mix = GetFloat(ikMap, "mix", 1); + + skeletonData.ikConstraints.Add(ikConstraintData); } - - String targetName = (String)ikMap["target"]; - ikConstraintData.target = skeletonData.FindBone(targetName); - if (ikConstraintData.target == null) throw new Exception("Target bone not found: " + targetName); - - ikConstraintData.bendDirection = GetBoolean(ikMap, "bendPositive", true) ? 1 : -1; - ikConstraintData.mix = GetFloat(ikMap, "mix", 1); - - skeletonData.ikConstraints.Add(ikConstraintData); } // Slots. From 14219d846281b78647aadbeea643c5541dba3aaf Mon Sep 17 00:00:00 2001 From: Fenrisul Date: Thu, 4 Sep 2014 03:56:10 -0700 Subject: [PATCH 2/8] Added children List to Bone.cs and populated it inside Skeleton.cs Changed Bone class to implement IEnumerable to easily traverse the child list. --- spine-csharp/src/Bone.cs | 39 +++++++++++++++++++++++++++++++++++- spine-csharp/src/Skeleton.cs | 5 +++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/spine-csharp/src/Bone.cs b/spine-csharp/src/Bone.cs index 21549e4cd..dfba064e2 100644 --- a/spine-csharp/src/Bone.cs +++ b/spine-csharp/src/Bone.cs @@ -29,14 +29,50 @@ *****************************************************************************/ using System; +using System.Collections; +using System.Collections.Generic; namespace Spine { - public class Bone { + public class Bone : IEnumerable { + private sealed class Enumerator : IEnumerator{ + private int currentIndex = -1; + private Bone outer; + + internal Enumerator(Bone outer){ + this.outer = outer; + } + + public bool MoveNext(){ + int childCount = this.outer.children.Count; + return (++this.currentIndex < childCount); + } + + public void Reset(){ + this.currentIndex = -1; + } + + public object Current{ + get{ + return this.outer.children[this.currentIndex]; + } + } + } + public IEnumerator GetEnumerator () + { + return new Enumerator(this); + } + + public Bone this[int i]{ + get{ + return children[i]; + } + } static public bool yDown; internal BoneData data; internal Skeleton skeleton; internal Bone parent; + internal List children; internal float x, y, rotation, rotationIK, scaleX, scaleY; internal float m00, m01, m10, m11; internal float worldX, worldY, worldRotation, worldScaleX, worldScaleY; @@ -70,6 +106,7 @@ namespace Spine { this.data = data; this.skeleton = skeleton; this.parent = parent; + this.children = new List(); SetToSetupPose(); } diff --git a/spine-csharp/src/Skeleton.cs b/spine-csharp/src/Skeleton.cs index ab6d4d610..02aa9653f 100644 --- a/spine-csharp/src/Skeleton.cs +++ b/spine-csharp/src/Skeleton.cs @@ -77,6 +77,11 @@ namespace Spine { bones.Add(new Bone(boneData, this, parent)); } + foreach(Bone b in bones){ + if(b.Parent != null) + b.Parent.children.Add(b); + } + slots = new List(data.slots.Count); drawOrder = new List(data.slots.Count); foreach (SlotData slotData in data.slots) { From 0fa4aad44d03ec511804c42e1d03f15539f45d43 Mon Sep 17 00:00:00 2001 From: Fenrisul Date: Thu, 4 Sep 2014 05:37:06 -0700 Subject: [PATCH 3/8] Modified Bone.cs Removed IEnumerable interface Added public Children getter for children List --- spine-csharp/src/Bone.cs | 38 +++----------------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/spine-csharp/src/Bone.cs b/spine-csharp/src/Bone.cs index dfba064e2..636b064bc 100644 --- a/spine-csharp/src/Bone.cs +++ b/spine-csharp/src/Bone.cs @@ -29,44 +29,10 @@ *****************************************************************************/ using System; -using System.Collections; using System.Collections.Generic; namespace Spine { - public class Bone : IEnumerable { - private sealed class Enumerator : IEnumerator{ - private int currentIndex = -1; - private Bone outer; - - internal Enumerator(Bone outer){ - this.outer = outer; - } - - public bool MoveNext(){ - int childCount = this.outer.children.Count; - return (++this.currentIndex < childCount); - } - - public void Reset(){ - this.currentIndex = -1; - } - - public object Current{ - get{ - return this.outer.children[this.currentIndex]; - } - } - } - public IEnumerator GetEnumerator () - { - return new Enumerator(this); - } - - public Bone this[int i]{ - get{ - return children[i]; - } - } + public class Bone{ static public bool yDown; internal BoneData data; @@ -76,10 +42,12 @@ namespace Spine { internal float x, y, rotation, rotationIK, scaleX, scaleY; internal float m00, m01, m10, m11; internal float worldX, worldY, worldRotation, worldScaleX, worldScaleY; + internal bool flipX, flipY; public BoneData Data { get { return data; } } public Skeleton Skeleton { get { return skeleton; } } public Bone Parent { get { return parent; } } + public List Children { get { return children; } } public float X { get { return x; } set { x = value; } } public float Y { get { return y; } set { y = value; } } /// The forward kinetics rotation. From f643dab32d12c5a2a304630f07d3cdcb825ff8ce Mon Sep 17 00:00:00 2001 From: Fenrisul Date: Thu, 4 Sep 2014 05:39:08 -0700 Subject: [PATCH 4/8] Fixed accidental remerge --- spine-csharp/src/Bone.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/spine-csharp/src/Bone.cs b/spine-csharp/src/Bone.cs index 636b064bc..fdad97882 100644 --- a/spine-csharp/src/Bone.cs +++ b/spine-csharp/src/Bone.cs @@ -42,7 +42,6 @@ namespace Spine { internal float x, y, rotation, rotationIK, scaleX, scaleY; internal float m00, m01, m10, m11; internal float worldX, worldY, worldRotation, worldScaleX, worldScaleY; - internal bool flipX, flipY; public BoneData Data { get { return data; } } public Skeleton Skeleton { get { return skeleton; } } From bd40a5fa33764e2886a8f290ebf25027d35241db Mon Sep 17 00:00:00 2001 From: Fenrisul Date: Thu, 11 Sep 2014 20:10:33 -0700 Subject: [PATCH 5/8] SkeletonUtility initial commit --- .../{BoneComponent.cs => BoneFollower.cs} | 48 ++- ...Component.cs.meta => BoneFollower.cs.meta} | 2 +- .../Editor/BoneFollowerInspector.cs | 106 ++++++ .../Editor/BoneFollowerInspector.cs.meta | 8 + .../Editor/GUI/icon-animation.png.meta | 1 + .../Editor/GUI/icon-animationRoot.png.meta | 1 + .../spine-unity/Editor/GUI/icon-bone.png | Bin 0 -> 515 bytes .../spine-unity/Editor/GUI/icon-bone.png.meta | 47 +++ .../spine-unity/Editor/GUI/icon-boneNib.png | Bin 0 -> 3364 bytes .../Editor/GUI/icon-boneNib.png.meta | 47 +++ .../Editor/GUI/icon-boundingBox.png | Bin 0 -> 3016 bytes .../Editor/GUI/icon-boundingBox.png.meta | 47 +++ .../Editor/GUI/icon-constraintNib.png | Bin 0 -> 14078 bytes .../Editor/GUI/icon-constraintNib.png.meta | 47 +++ .../Editor/GUI/icon-event.png.meta | 1 + .../Editor/GUI/icon-hingeChain.png | Bin 0 -> 757 bytes .../Editor/GUI/icon-hingeChain.png.meta | 47 +++ .../spine-unity/Editor/GUI/icon-image.png | Bin 0 -> 3132 bytes .../Editor/GUI/icon-image.png.meta | 47 +++ .../spine-unity/Editor/GUI/icon-mesh.png | Bin 0 -> 603 bytes .../spine-unity/Editor/GUI/icon-mesh.png.meta | 47 +++ .../spine-unity/Editor/GUI/icon-null.png | Bin 0 -> 3023 bytes .../spine-unity/Editor/GUI/icon-null.png.meta | 47 +++ .../spine-unity/Editor/GUI/icon-poseBones.png | Bin 0 -> 555 bytes .../Editor/GUI/icon-poseBones.png.meta | 47 +++ .../Editor/GUI/icon-skeleton.png.meta | 1 + .../Editor/GUI/icon-skeletonUtility.png | Bin 0 -> 1133 bytes .../Editor/GUI/icon-skeletonUtility.png.meta | 47 +++ .../spine-unity/Editor/GUI/icon-skin.png | Bin 0 -> 3430 bytes .../spine-unity/Editor/GUI/icon-skin.png.meta | 47 +++ .../Editor/GUI/icon-skinPlaceholder.png | Bin 0 -> 3370 bytes .../Editor/GUI/icon-skinPlaceholder.png.meta | 47 +++ .../Editor/GUI/icon-skinsRoot.png.meta | 1 + .../spine-unity/Editor/GUI/icon-slot.png | Bin 0 -> 3387 bytes .../spine-unity/Editor/GUI/icon-slot.png.meta | 47 +++ .../Editor/GUI/icon-spine.png.meta | 1 + .../Editor/GUI/icon-subMeshRenderer.png | Bin 0 -> 3536 bytes .../Editor/GUI/icon-subMeshRenderer.png.meta | 47 +++ .../spine-unity/Editor/GUI/icon-warning.png | Bin 0 -> 1713 bytes .../Editor/GUI/icon-warning.png.meta | 47 +++ .../Editor/SkeletonAnimationInspector.cs | 37 ++ .../Editor/SkeletonDataAssetInspector.cs | 37 +- .../Editor/SpineEditorUtilities.cs | 114 +++++- .../Assets/spine-unity/Shaders/Bones.shader | 69 ++++ .../spine-unity/Shaders/Bones.shader.meta | 5 + .../Assets/spine-unity/Shaders/HiddenPass.mat | Bin 0 -> 4288 bytes .../spine-unity/Shaders/HiddenPass.mat.meta | 4 + .../spine-unity/Shaders/HiddenPass.shader | 21 ++ .../Shaders/HiddenPass.shader.meta | 5 + .../Assets/spine-unity/SkeletonAnimation.cs | 18 +- .../Assets/spine-unity/SkeletonExtensions.cs | 37 +- .../Assets/spine-unity/SkeletonRenderer.cs | 11 +- .../Assets/spine-unity/SkeletonUtility.meta | 5 + .../spine-unity/SkeletonUtility/Editor.meta | 5 + .../Editor/SkeletonUtilityBoneInspector.cs | 287 +++++++++++++++ .../SkeletonUtilityBoneInspector.cs.meta | 8 + .../Editor/SkeletonUtilityInspector.cs | 316 +++++++++++++++++ .../Editor/SkeletonUtilityInspector.cs.meta | 8 + .../SkeletonUtility/SkeletonUtility.cs | 335 ++++++++++++++++++ .../SkeletonUtility/SkeletonUtility.cs.meta | 8 + .../SkeletonUtility/SkeletonUtilityBone.cs | 218 ++++++++++++ .../SkeletonUtilityBone.cs.meta | 8 + .../SkeletonUtilityConstraint.cs | 22 ++ .../SkeletonUtilityConstraint.cs.meta | 8 + .../SkeletonUtilityEyeConstraint.cs | 61 ++++ .../SkeletonUtilityEyeConstraint.cs.meta | 8 + .../SkeletonUtilityGroundConstraint.cs | 58 +++ .../SkeletonUtilityGroundConstraint.cs.meta | 8 + .../SkeletonUtilityKinematicShadow.cs | 81 +++++ .../SkeletonUtilityKinematicShadow.cs.meta | 8 + .../SkeletonUtilitySubmeshRenderer.cs | 102 ++++++ .../SkeletonUtilitySubmeshRenderer.cs.meta | 12 + 72 files changed, 2751 insertions(+), 48 deletions(-) rename spine-unity/Assets/spine-unity/{BoneComponent.cs => BoneFollower.cs} (85%) rename spine-unity/Assets/spine-unity/{BoneComponent.cs.meta => BoneFollower.cs.meta} (78%) create mode 100644 spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs create mode 100644 spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-bone.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-bone.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-boneNib.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-boneNib.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-boundingBox.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-boundingBox.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-hingeChain.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-hingeChain.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-image.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-image.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-mesh.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-mesh.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-null.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-null.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-poseBones.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-poseBones.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-skeletonUtility.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-skeletonUtility.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-skinPlaceholder.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-skinPlaceholder.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-slot.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-slot.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-subMeshRenderer.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-subMeshRenderer.png.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-warning.png create mode 100644 spine-unity/Assets/spine-unity/Editor/GUI/icon-warning.png.meta create mode 100644 spine-unity/Assets/spine-unity/Shaders/Bones.shader create mode 100644 spine-unity/Assets/spine-unity/Shaders/Bones.shader.meta create mode 100644 spine-unity/Assets/spine-unity/Shaders/HiddenPass.mat create mode 100644 spine-unity/Assets/spine-unity/Shaders/HiddenPass.mat.meta create mode 100644 spine-unity/Assets/spine-unity/Shaders/HiddenPass.shader create mode 100644 spine-unity/Assets/spine-unity/Shaders/HiddenPass.shader.meta create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility.meta create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/Editor.meta create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs.meta create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs.meta create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs.meta create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs.meta create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs.meta create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityEyeConstraint.cs create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityEyeConstraint.cs.meta create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs.meta create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityKinematicShadow.cs create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityKinematicShadow.cs.meta create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs create mode 100644 spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs.meta diff --git a/spine-unity/Assets/spine-unity/BoneComponent.cs b/spine-unity/Assets/spine-unity/BoneFollower.cs similarity index 85% rename from spine-unity/Assets/spine-unity/BoneComponent.cs rename to spine-unity/Assets/spine-unity/BoneFollower.cs index acfe183cb..5c8fa3f92 100644 --- a/spine-unity/Assets/spine-unity/BoneComponent.cs +++ b/spine-unity/Assets/spine-unity/BoneFollower.cs @@ -36,8 +36,9 @@ using Spine; /// Sets a GameObject's transform to match a bone on a Spine skeleton. [ExecuteInEditMode] -[AddComponentMenu("Spine/BoneComponent")] -public class BoneComponent : MonoBehaviour { +[AddComponentMenu("Spine/BoneFollower")] +public class BoneFollower : MonoBehaviour { + [System.NonSerialized] public bool valid; @@ -55,31 +56,50 @@ public class BoneComponent : MonoBehaviour { } } - // TODO: Make the rotation behavior more customizable - // public bool followTransformRotation = false; - - // TODO: Make transform follow bone scale? too specific? This is really useful for shared shadow assets. - //public bool followBoneScale = false; /// If a bone isn't set, boneName is used to find the bone. public String boneName; + public bool resetOnAwake = true; + protected Transform cachedTransform; protected Transform skeletonTransform; - + + public void HandleResetRenderer(SkeletonRenderer skeletonRenderer){ + Reset(); + } + public void Reset () { bone = null; cachedTransform = transform; valid = skeletonRenderer != null && skeletonRenderer.valid; if (!valid) return; skeletonTransform = skeletonRenderer.transform; + + skeletonRenderer.OnReset -= HandleResetRenderer; + skeletonRenderer.OnReset += HandleResetRenderer; + + if(Application.isEditor) + DoUpdate(); + } + + void OnDestroy(){ + //cleanup + if(skeletonRenderer != null) + skeletonRenderer.OnReset -= HandleResetRenderer; } public void Awake () { - Reset(); + if(resetOnAwake) + Reset(); } - public void LateUpdate () { + void LateUpdate(){ + DoUpdate(); + } + + + public void DoUpdate () { if (!valid) { Reset(); return; @@ -92,6 +112,9 @@ public class BoneComponent : MonoBehaviour { Debug.LogError("Bone not found: " + boneName, this); return; } + else{ + + } } Spine.Skeleton skeleton = skeletonRenderer.skeleton; @@ -113,9 +136,10 @@ public class BoneComponent : MonoBehaviour { if(followBoneRotation) { Vector3 rotation = skeletonTransform.rotation.eulerAngles; - cachedTransform.rotation = Quaternion.Euler(rotation.x, rotation.y, - skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * flipRotation) ); + + cachedTransform.rotation = Quaternion.Euler(rotation.x, rotation.y, skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * flipRotation) ); } } + } } \ No newline at end of file diff --git a/spine-unity/Assets/spine-unity/BoneComponent.cs.meta b/spine-unity/Assets/spine-unity/BoneFollower.cs.meta similarity index 78% rename from spine-unity/Assets/spine-unity/BoneComponent.cs.meta rename to spine-unity/Assets/spine-unity/BoneFollower.cs.meta index a6a16dd66..29dabc13e 100644 --- a/spine-unity/Assets/spine-unity/BoneComponent.cs.meta +++ b/spine-unity/Assets/spine-unity/BoneFollower.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 487b42efe96d8cc408a757541ea3f169 +guid: a1fd8daaed7b64148a34acb96ba14ce1 MonoImporter: serializedVersion: 2 defaultReferences: [] diff --git a/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs b/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs new file mode 100644 index 000000000..bbf164b4e --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs @@ -0,0 +1,106 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.1 + * + * Copyright (c) 2013, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable and + * non-transferable license to install, execute and perform the Spine Runtimes + * Software (the "Software") solely for internal use. Without the written + * permission of Esoteric Software (typically granted by licensing Spine), you + * may not (a) modify, translate, adapt or otherwise create derivative works, + * improvements of the Software or develop new applications using the Software + * 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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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 UnityEditor; +using UnityEngine; + +[CustomEditor(typeof(BoneFollower))] +public class BoneFollowerInspector : Editor { + private SerializedProperty boneName, skeletonRenderer, followZPosition, followBoneRotation; + BoneFollower component; + void OnEnable () { + skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); + boneName = serializedObject.FindProperty("boneName"); + followBoneRotation = serializedObject.FindProperty("followBoneRotation"); + followZPosition = serializedObject.FindProperty("followZPosition"); + component = (BoneFollower)target; + ForceReload(); + } + + void FindRenderer(){ + if(skeletonRenderer.objectReferenceValue == null){ + SkeletonRenderer parentRenderer = component.GetComponentInParent(); + if(parentRenderer != null){ + skeletonRenderer.objectReferenceValue = (UnityEngine.Object)parentRenderer; + } + } + } + + void ForceReload(){ + if(component.skeletonRenderer != null){ + if(component.skeletonRenderer.valid == false) + component.skeletonRenderer.Reset(); + } + } + + override public void OnInspectorGUI () { + serializedObject.Update(); + + FindRenderer(); + + EditorGUILayout.PropertyField(skeletonRenderer); + + if (component.valid) { + String[] bones = new String[1]; + try{ + bones = new String[component.skeletonRenderer.skeleton.Data.Bones.Count + 1]; + } + catch{ + + } + + bones[0] = ""; + for (int i = 0; i < bones.Length - 1; i++) + bones[i + 1] = component.skeletonRenderer.skeleton.Data.Bones[i].Name; + Array.Sort(bones); + int boneIndex = Math.Max(0, Array.IndexOf(bones, boneName.stringValue)); + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Bone"); + EditorGUIUtility.LookLikeControls(); + boneIndex = EditorGUILayout.Popup(boneIndex, bones); + EditorGUILayout.EndHorizontal(); + + boneName.stringValue = boneIndex == 0 ? null : bones[boneIndex]; + EditorGUILayout.PropertyField(followBoneRotation); + EditorGUILayout.PropertyField(followZPosition); + } + else{ + GUILayout.Label("INVALID"); + } + + if (serializedObject.ApplyModifiedProperties() || + (Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed") + ) { + component.Reset(); + } + } +} diff --git a/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs.meta b/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs.meta new file mode 100644 index 000000000..a5cf9ae89 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/BoneFollowerInspector.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c71ca35fd6241cb49a0b0756a664fcf7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png.meta index f8ac9f868..6d9bc41dd 100644 --- a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png.meta +++ b/spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png.meta @@ -1,6 +1,7 @@ fileFormatVersion: 2 guid: 52b12ec801461494185a4d3dc66f3d1d TextureImporter: + fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png.meta index 1b4c1e24f..4bcf433e8 100644 --- a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png.meta +++ b/spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png.meta @@ -1,6 +1,7 @@ fileFormatVersion: 2 guid: 3d1be4ea889f3a14b864352fe49a1bde TextureImporter: + fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-bone.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-bone.png new file mode 100644 index 0000000000000000000000000000000000000000..ec66a6a85588b584071e68bfa670eb2e758a3e6b GIT binary patch literal 515 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 KMNUMnLSTYb4V82N literal 0 HcmV?d00001 diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-boundingBox.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-boundingBox.png.meta new file mode 100644 index 000000000..c90f54d3c --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/GUI/icon-boundingBox.png.meta @@ -0,0 +1,47 @@ +fileFormatVersion: 2 +guid: 955aed20030d0504b8a9c6934a5cb47a +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png new file mode 100644 index 0000000000000000000000000000000000000000..175bcb047ad5242ad2d48ca94298a65eeed61514 GIT binary patch literal 14078 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 E7aRC%)c^nh literal 0 HcmV?d00001 diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png.meta new file mode 100644 index 000000000..e7ab7aca3 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/GUI/icon-constraintNib.png.meta @@ -0,0 +1,47 @@ +fileFormatVersion: 2 +guid: de1a4f5ad4bdf1a4ea072c4d59ba87d8 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png.meta index 71c672b9c..2ab786189 100644 --- a/spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png.meta +++ b/spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png.meta @@ -1,6 +1,7 @@ fileFormatVersion: 2 guid: d226a80acc775714aa78b85e16a00e9b TextureImporter: + fileIDToRecycleName: {} serializedVersion: 2 mipmaps: mipMapMode: 0 diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-hingeChain.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-hingeChain.png new file mode 100644 index 0000000000000000000000000000000000000000..a27af1c7c529ca05ab5f82b5b0f72d093b37fb8e GIT binary patch literal 757 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 WK!44B#El970000-n zl9S}FA$SID@;pHjY3hIw2yregKVKUl9TZ>c|Kxy_Y<%JECX%8N-6*>5VE%y`O9;_#=-k_0h{dXyka=~ zOqTsFwbU*EJV=L&iviF99;nw9@YIWVi>?tGlh zveZwemcd%-^*LZky{^tbJ`?bgDEi{twB;#`V>Frq?)qH<+*7an)oc$|Jeww~t7pJr z;fV@^)6=0B?m4jGnJg8GmvpN5z&r5~aeU|SIOp5Du)jEOG24SDz=0&^YZi!O3oIC8 zjwHD&A0$bJq{i8afH%Mz@YqkK!*yr2t4_3b2H@At+Ym*seXmy$$9BS*twICpo!FUJ pVNsLk$zKLWQtfY?{CWSX`2(S2E9%66Rh0k$002ovPDHLkV1oU23VZ+n literal 0 HcmV?d00001 diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-mesh.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-mesh.png.meta new file mode 100644 index 000000000..a98b0e9c8 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/GUI/icon-mesh.png.meta @@ -0,0 +1,47 @@ +fileFormatVersion: 2 +guid: a309a2e14638a204091b915126910f45 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-null.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-null.png new file mode 100644 index 0000000000000000000000000000000000000000..9a6d738ebd50b85b80645160e244c3886933b4d8 GIT binary patch literal 3023 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 literal 0 HcmV?d00001 diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeletonUtility.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeletonUtility.png.meta new file mode 100644 index 000000000..9d3c22794 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeletonUtility.png.meta @@ -0,0 +1,47 @@ +fileFormatVersion: 2 +guid: 5bb0631368b462047869d8788673cb48 +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png new file mode 100644 index 0000000000000000000000000000000000000000..3d9bddeb4a3c2c2889143bc1a79853dbb84166a4 GIT binary patch literal 3430 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 literal 0 HcmV?d00001 diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png.meta new file mode 100644 index 000000000..3be7a6e69 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skin.png.meta @@ -0,0 +1,47 @@ +fileFormatVersion: 2 +guid: bfd9f3d2607e9e44c97384d7575a17dc +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skinPlaceholder.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skinPlaceholder.png new file mode 100644 index 0000000000000000000000000000000000000000..3b11d379e43d42f770f6b3aaa58588f63774553b GIT binary patch literal 3370 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.#u=icW8^bYW~9?4Xt&z{fM76)v9U1(0s+j-%zWM0*m$l*6qE$JCaxbaeEA z-|rvX-QC6f{5+D$e!oLu5KwmsnU`Cu3ZR8_qsm#V5T z3_Uwn84)ZBqT{fAQ0$gv)M$UP}pYXGiP4{Fr3Y1m+SR< zThp{JtyYUo(`3^$d4GSOi^bx{Mx)VMU0q%1Tm4UShcF@%0B)w!>1ZO6SoV6o_a#a4 z3LykDpBjeoVQXvaRW6sS1F+cX>}I@g=>Y(qzRt2MOyB!~`o*pyx@w$%4*4KMPEP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0008}NklG$kOe(4~nQ7sj}BL*m3A zAU~oTqYL9dFfPrkU_o3F6JrqLj76ACggb>Yq*%D#w)cLYo7NBl6B5t%< zK%-bJe!9KA{e`vm??$8X8KAEZYv1>sfiex?d7dg13Zrv#bJ-vWvQZR`h)AW`Z0=7^ zPL8HhDRpsi@%q8RL8n|U1Iz)VA`%1ET5ClFDVNJB;9I~0GFt1s)z#JaT-O~3QtRvM zPO(^2nM_6+jYiz>_f0mNwWU&NB#NSbv)TN8XJ_ZDFbsFs*4Flb9uP^nTplWRftR(` z3#nAfT5I1=r_-P%h}QZ^wOak5R4RQP$FZc->1XwNeF31=YVB65)sMq4 zeBN%i`vWth|CYYLzi)vUh<)Gh8e{$h3_y}3N5D_6>l&>!?RNVQU;!YG<0nB799e5S zcex5@I0&GW@(P8*n*hcbDwWEs!(JwnnFi!K;6>oKu7E{r{muX^wOXw-?1{*YLC`M% zzXC+SnNsRZDOCl+BuSpn%*>R#-EJ6$;j=Idj{qwoTn(GLC2<-k0pE#;aU4fPgfUyWL0g^YiY+#6+giX#A2+ zr_Zgme*wu|zzXnz$G~Hy)YI|t@q5;76S7Vn>( zoxOd2ejYC_E>@?erbd>QmOg4Wn?EY0%*n~ggX=80?QQ6=pg{X+d{G@8FERh~(W9M8jKP;b}tX)`s1kcwO~3o9UP2!Ya)444iDRA!_Q z%|sDHY4Mk60*yuoO`2RXSDhx&V`d)W!SL*6oMO{x2^;M=qAx;8K!+BZEK=~{+4CS^ zGDyLkST&@^WvJ1VT1KE*Wt%kmvLb!F0o=F&NU%#N0W(S>fZe>+VwKpX;Eb+>ntQhS zATR?Vi=^Q5q;l2ifD9v0AeJZO>LC~g#9|&SiWQ6DwSWME1$>CQ#avh z*{rK)@M^V0WwDZoMUSfFQjk*MnM?+%nlL1Q1xleHRsq8bQL<=VoGeZ$N>T`uyoQf<*3DY*zpd>IeFmq&yY2jSt3+l~s4GZQXP%Oyh zQ_1i>jr~`n=e8*Kc&78Vr55wXM=g}w3Ch;ZO7;iT*AlIgCu!_AbW?8k#tT|T8p|0D z2_Qj0JAK+c8P_ethaJuVM|R@p?COW~M{fdeG5eQ0qu+n({U|1!*x}|+-*)Ak`n~*s zWKTqOr+1eq;8|PZvBl)QLSjX#DY&pNyp0+45OaTn+a8odVSX(iZsF8Wh3oPPbnm*u z%?g=zpZDoK7$clY*+)O>TPxHK^c-MCv_|=~U0_@Gu~;J~Q){lS1gq5CFNm)7YxjQw z38BaPk=7$4^=@rE=Y)2+kZfzCPa>{kID^5BPV<$lVX;CGPV)B0uQ>0V=#E}H^wfPh zl94`v3;^+wUVFRQ$_FA&WndRfq+LDMV0yFcw-GG8&|+-J1(+Zx{D3VGZK6UC%R-@rTt8o22M!L8}a*$ z?Ol0vc(;xZh!?@Rd4Pf`NZ->p+ziy^jaNKQcEm&6vW#nv2@vGhI+D~)juZ4N{lm-H zYywpAw^bKwSwrsz%7PoDTdqzoWpVR&AAi;Tf|&kuftI7px}T^@ze2k!8k;H%939ZK zL^)TtRx4O7r&fn`Tt{^EE&YyW&}%$uyO!PRgXFZN8km)dTOhi#DYWrYO8fQRvBdNZ z9Xr1_f9wuvC~l95@$aJzxfZvV*tk$|@yT;}6YFr$74%DgBXjYv-IwPa?>dRE2P zezXH;kcfQai-8B!5 zQRhljRvkVc*dfwJlrHJYU|}7>gV1P6IJ5E0U{CY-&f2&YJ)Mh!`+VW+zeU~a@d2{E z;HV0<^Q+(+b+wyW==`s@b&(D--xduhz*82@vNmgQ*& zgT{Ya8QVM7nYioq-dhtP4FS)XJ4b`q`Vj`B>UOzt?DWR+$ZgtB!``;O9N1x!Zw{{< z`LXZYCpY71yKg!>q}82{P{01kil;C6ulOUZ`cLQNnsuSaj?fz}l)K8vy@!)&fm&KL W*c~!{*LmCX6HzHP$&V*%EB^-QZFN}y literal 0 HcmV?d00001 diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-warning.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-warning.png.meta new file mode 100644 index 000000000..e32950ca4 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/GUI/icon-warning.png.meta @@ -0,0 +1,47 @@ +fileFormatVersion: 2 +guid: 754d724c1bd750048852e8cf3d4a05ee +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 1024 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs index bc6d6b19c..f8d29894e 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs @@ -31,16 +31,23 @@ using System; using UnityEditor; using UnityEngine; +using Spine; [CustomEditor(typeof(SkeletonAnimation))] public class SkeletonAnimationInspector : SkeletonRendererInspector { protected SerializedProperty animationName, loop, timeScale; + protected bool isPrefab; protected override void OnEnable () { base.OnEnable(); animationName = serializedObject.FindProperty("_animationName"); loop = serializedObject.FindProperty("loop"); timeScale = serializedObject.FindProperty("timeScale"); + + if(PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab) + isPrefab = true; + + } protected override void gui () { @@ -49,6 +56,25 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector { SkeletonAnimation component = (SkeletonAnimation)target; if (!component.valid) return; + //catch case where SetAnimation was used to set track 0 without using AnimationName + if(Application.isPlaying){ + TrackEntry currentState = component.state.GetCurrent(0); + if(currentState != null){ + if(component.AnimationName != animationName.stringValue){ + animationName.stringValue = currentState.Animation.Name; + } + + if(loop.boolValue != currentState.Loop){ + loop.boolValue = currentState.Loop; + } + + if(timeScale.floatValue != currentState.TimeScale){ + timeScale.floatValue = currentState.TimeScale; + } + } + } + + // Animation name. { String[] animations = new String[component.skeleton.Data.Animations.Count + 1]; @@ -69,10 +95,21 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector { String selectedAnimationName = animationIndex == 0 ? null : animations[animationIndex]; component.AnimationName = selectedAnimationName; animationName.stringValue = selectedAnimationName; + + } EditorGUILayout.PropertyField(loop); EditorGUILayout.PropertyField(timeScale); component.timeScale = Math.Max(component.timeScale, 0); + EditorGUILayout.Space(); + + if(!isPrefab){ + if(component.GetComponent() == null){ + if(GUILayout.Button(new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility), GUILayout.Height(30))){ + component.gameObject.AddComponent(); + } + } + } } } diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs index d77647e42..09618fa45 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs @@ -28,6 +28,11 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +/***************************************************************************** + * Automatic import and advanced preview added by Mitch Thompson + * Full irrevocable rights and permissions granted to Esoteric Software +*****************************************************************************/ + using System; using System.Collections.Generic; using UnityEditor; @@ -53,18 +58,26 @@ public class SkeletonDataAssetInspector : Editor { private string m_skeletonDataAssetGUID; void OnEnable () { - atlasAsset = serializedObject.FindProperty("atlasAsset"); - skeletonJSON = serializedObject.FindProperty("skeletonJSON"); - scale = serializedObject.FindProperty("scale"); - fromAnimation = serializedObject.FindProperty("fromAnimation"); - toAnimation = serializedObject.FindProperty("toAnimation"); - duration = serializedObject.FindProperty("duration"); - defaultMix = serializedObject.FindProperty("defaultMix"); - - m_skeletonDataAsset = (SkeletonDataAsset)target; - m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath(m_skeletonDataAsset) ); - - EditorApplication.update += Update; + try{ + + atlasAsset = serializedObject.FindProperty("atlasAsset"); + skeletonJSON = serializedObject.FindProperty("skeletonJSON"); + scale = serializedObject.FindProperty("scale"); + fromAnimation = serializedObject.FindProperty("fromAnimation"); + toAnimation = serializedObject.FindProperty("toAnimation"); + duration = serializedObject.FindProperty("duration"); + defaultMix = serializedObject.FindProperty("defaultMix"); + + m_skeletonDataAsset = (SkeletonDataAsset)target; + m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath(m_skeletonDataAsset) ); + + EditorApplication.update += Update; + + } + catch{ + + + } } void OnDestroy(){ diff --git a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs index eec7fc04d..ef614a1e0 100644 --- a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs +++ b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs @@ -1,4 +1,38 @@ #pragma warning disable 0219 +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.1 + * + * Copyright (c) 2013, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable and + * non-transferable license to install, execute and perform the Spine Runtimes + * Software (the "Software") solely for internal use. Without the written + * permission of Esoteric Software (typically granted by licensing Spine), you + * may not (a) modify, translate, adapt or otherwise create derivative works, + * improvements of the Software or develop new applications using the Software + * 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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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. + *****************************************************************************/ + +/***************************************************************************** + * Spine Editor Utilities created by Mitch Thompson + * Full irrevocable rights and permissions granted to Esoteric Software +*****************************************************************************/ using UnityEngine; using UnityEditor; @@ -15,6 +49,7 @@ public class SpineEditorUtilities : AssetPostprocessor { 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 skinPlaceholder; @@ -27,6 +62,11 @@ public class SpineEditorUtilities : AssetPostprocessor { public static Texture2D animationRoot; public static Texture2D spine; public static Texture2D _event; + public static Texture2D constraintNib; + public static Texture2D warning; + public static Texture2D skeletonUtility; + public static Texture2D hingeChain; + public static Texture2D subMeshRenderer; public static Mesh boneMesh{ get{ @@ -61,6 +101,7 @@ public class SpineEditorUtilities : AssetPostprocessor { skeleton = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skeleton.png"); nullBone = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-null.png"); bone = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-bone.png"); + poseBones = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-poseBones.png"); boneNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-boneNib.png"); slot = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-slot.png"); skinPlaceholder = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skinPlaceholder.png"); @@ -73,6 +114,12 @@ public class SpineEditorUtilities : AssetPostprocessor { animationRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-animationRoot.png"); spine = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-spine.png"); _event = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-event.png"); + constraintNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-constraintNib.png"); + warning = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-warning.png"); + skeletonUtility = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skeletonUtility.png"); + hingeChain = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-hingeChain.png"); + subMeshRenderer = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-subMeshRenderer.png"); + } } @@ -81,8 +128,9 @@ public class SpineEditorUtilities : AssetPostprocessor { public static string editorPath = ""; public static string editorGUIPath = ""; - - static List skeletonRendererInstanceIDs; + + static Dictionary skeletonRendererTable; + static Dictionary skeletonUtilityBoneTable; public static float defaultScale = 0.01f; public static float defaultMix = 0.2f; @@ -96,7 +144,8 @@ public class SpineEditorUtilities : AssetPostprocessor { Icons.Initialize(); - skeletonRendererInstanceIDs = new List(); + skeletonRendererTable = new Dictionary(); + skeletonUtilityBoneTable = new Dictionary(); EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged; EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI; @@ -105,22 +154,49 @@ public class SpineEditorUtilities : AssetPostprocessor { } static void HierarchyWindowChanged(){ - skeletonRendererInstanceIDs.Clear(); + skeletonRendererTable.Clear(); + skeletonUtilityBoneTable.Clear(); SkeletonRenderer[] arr = Object.FindObjectsOfType(); foreach(SkeletonRenderer r in arr) - skeletonRendererInstanceIDs.Add(r.gameObject.GetInstanceID()); + skeletonRendererTable.Add( r.gameObject.GetInstanceID(), r.gameObject ); + + SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType(); + foreach(SkeletonUtilityBone b in boneArr) + skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b); } static void HierarchyWindowItemOnGUI(int instanceId, Rect selectionRect){ - if(skeletonRendererInstanceIDs.Contains(instanceId)){ + if(skeletonRendererTable.ContainsKey(instanceId)){ Rect r = new Rect (selectionRect); r.x = r.width - 15; r.width = 15; GUI.Label(r, Icons.spine); } + else if(skeletonUtilityBoneTable.ContainsKey(instanceId)){ + Rect r = new Rect (selectionRect); + //r.x = r.width - 15; + r.x -= 26; + + if(skeletonUtilityBoneTable[instanceId] != null){ + if( skeletonUtilityBoneTable[instanceId].transform.childCount == 0 ) + r.x += 15; + + + r.width = 15; + + if( skeletonUtilityBoneTable[instanceId].mode == SkeletonUtilityBone.Mode.Follow ){ + GUI.Label(r, Icons.bone); + } + else{ + GUI.Label(r, Icons.poseBones); + } + } + + } + } [MenuItem("Assets/Spine/Ingest")] @@ -335,20 +411,24 @@ public class SpineEditorUtilities : AssetPostprocessor { string primaryName = Path.GetFileNameWithoutExtension(spineJson.name); string assetPath = Path.GetDirectoryName( AssetDatabase.GetAssetPath(spineJson)); + string filePath = assetPath + "/" + primaryName + "_SkeletonData.asset"; if(spineJson != null && atlasAsset != null){ - SkeletonDataAsset skelDataAsset = SkeletonDataAsset.CreateInstance(); - skelDataAsset.atlasAsset = atlasAsset; - skelDataAsset.skeletonJSON = spineJson; - skelDataAsset.fromAnimation = new string[0]; - skelDataAsset.toAnimation = new string[0]; - skelDataAsset.duration = new float[0]; - skelDataAsset.defaultMix = defaultMix; - skelDataAsset.scale = defaultScale; - - AssetDatabase.CreateAsset(skelDataAsset, assetPath + "/" + primaryName + "_SkeletonData.asset"); - AssetDatabase.SaveAssets(); + SkeletonDataAsset skelDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset)); + if(skelDataAsset == null){ + skelDataAsset = SkeletonDataAsset.CreateInstance(); + skelDataAsset.atlasAsset = atlasAsset; + skelDataAsset.skeletonJSON = spineJson; + skelDataAsset.fromAnimation = new string[0]; + skelDataAsset.toAnimation = new string[0]; + skelDataAsset.duration = new float[0]; + skelDataAsset.defaultMix = defaultMix; + skelDataAsset.scale = defaultScale; + + AssetDatabase.CreateAsset(skelDataAsset, filePath); + AssetDatabase.SaveAssets(); + } return skelDataAsset; } diff --git a/spine-unity/Assets/spine-unity/Shaders/Bones.shader b/spine-unity/Assets/spine-unity/Shaders/Bones.shader new file mode 100644 index 000000000..61fc977e5 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Shaders/Bones.shader @@ -0,0 +1,69 @@ +Shader "Spine/Bones" { +Properties { + _Color ("Color", Color) = (0.5,0.5,0.5,0.5) + _MainTex ("Particle Texture", 2D) = "white" {} +} + +Category { + Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } + Blend SrcAlpha OneMinusSrcAlpha + AlphaTest Greater .01 + ColorMask RGB + + Lighting Off Cull Off ZTest Always ZWrite Off Fog { Mode Off } + + SubShader { + Pass { + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_particles + + #include "UnityCG.cginc" + + sampler2D _MainTex; + fixed4 _Color; + + struct appdata_t { + float4 vertex : POSITION; + fixed4 color : COLOR; + float2 texcoord : TEXCOORD0; + }; + + struct v2f { + float4 vertex : SV_POSITION; + fixed4 color : COLOR; + float2 texcoord : TEXCOORD0; + #ifdef SOFTPARTICLES_ON + float4 projPos : TEXCOORD1; + #endif + }; + + float4 _MainTex_ST; + + v2f vert (appdata_t v) + { + v2f o; + o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); + #ifdef SOFTPARTICLES_ON + o.projPos = ComputeScreenPos (o.vertex); + COMPUTE_EYEDEPTH(o.projPos.z); + #endif + o.color = v.color; + o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); + return o; + } + + sampler2D_float _CameraDepthTexture; + + + fixed4 frag (v2f i) : SV_Target + { + return 2.0f * i.color * _Color * tex2D(_MainTex, i.texcoord); + } + ENDCG + } + } +} +} diff --git a/spine-unity/Assets/spine-unity/Shaders/Bones.shader.meta b/spine-unity/Assets/spine-unity/Shaders/Bones.shader.meta new file mode 100644 index 000000000..d01814ef9 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Shaders/Bones.shader.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 66988de88a15abd4e8846c6805485f57 +ShaderImporter: + defaultTextures: [] + userData: diff --git a/spine-unity/Assets/spine-unity/Shaders/HiddenPass.mat b/spine-unity/Assets/spine-unity/Shaders/HiddenPass.mat new file mode 100644 index 0000000000000000000000000000000000000000..31cf39d9972a7839972b6b5bf7d5263c728f8252 GIT binary patch literal 4288 zcmeHK+j87Q5FHZ&xj-P?!zEcD+`&NX0D;8u1#fUsAxoTu$E~q7@`~D(T%%dz!xv;41U<%ineF5z>14T6qyDX}AI-M= zCQD3rsCP>BC_&&5f~VJeJ!h}3Cz&hk`o1&dq{x?Oe9xLxZ}qe_xf5R;w^UCb%8 zC15ujnvJhH4yV<`kw^mSX*Z}rNC+ay2#AxB$cH&> z|M3W@bT-R(X!hUfkuZ&z5YDoa=Zdv@qU4U%pv7w_om*B7CuR1tVLna~03uTreS4s- zO0?75ds;fD5KPAAKqtn64AGc`CjvCoC<#vnAYnH`!kGwYkLsqdO~h}_nZ z092~OyCoeK+Npg$JKk>D(G>fH?e9eFL7-b{T2evc7<;#c#N@(A@3rh`hLPTn*rj~C z$XBZOgAi27TDNQ9L&AVKCXXr9+h>Q@=F7)Z@oktf*=;9&O`>~)KIEJ;W_mc>w zo%yGANQ{qG@1?+r&wjdk7a|B@xvpEh7Z(Fit=1>SS}`oFP<=TBRl-F(;m-)e$pTB5 zBUFD51Bp)-`ZU#Fpo@eN)qfroR~UQ<$FMflUq&$P%)cUx&pb-?)xe3*ewylQ5d`yh z`^M^uKPK?DS_*(lb$DONnpoDa2lhF#L&Uzr_GRwz`F6M^_AR!r{HtBFeKlf77pB!Y z-GQp^(}lMcF7&H&Yd;+S?ZTBCzbu{{{QB3Qf8cDJ$&7&+12YC@4E$diz^@|xv?nI- z>9VYk`lSt?4nEs)^y6c$e^X~UeY&!NZxy|zaEahWk3Zc0+SnCos(yd);2MwH$oIPR hO9?D6_*L%nOOX^F@BLKQkxTy$ecCp51^@n1{{ZTN@%aD% literal 0 HcmV?d00001 diff --git a/spine-unity/Assets/spine-unity/Shaders/HiddenPass.mat.meta b/spine-unity/Assets/spine-unity/Shaders/HiddenPass.mat.meta new file mode 100644 index 000000000..ef267ef07 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Shaders/HiddenPass.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 43227e5adadc6f24bb4bf74b92a56fb4 +NativeFormatImporter: + userData: diff --git a/spine-unity/Assets/spine-unity/Shaders/HiddenPass.shader b/spine-unity/Assets/spine-unity/Shaders/HiddenPass.shader new file mode 100644 index 000000000..3a0de6756 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Shaders/HiddenPass.shader @@ -0,0 +1,21 @@ +Shader "Spine/HiddenPass" { + SubShader + + { + + Tags {"Queue" = "Geometry-1" } + + Lighting Off + + Pass + + { + + ZWrite Off + + ColorMask 0 + + } + + } +} diff --git a/spine-unity/Assets/spine-unity/Shaders/HiddenPass.shader.meta b/spine-unity/Assets/spine-unity/Shaders/HiddenPass.shader.meta new file mode 100644 index 000000000..bcc031d30 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Shaders/HiddenPass.shader.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 913475501bf19374c84390868a9d6d3d +ShaderImporter: + defaultTextures: [] + userData: diff --git a/spine-unity/Assets/spine-unity/SkeletonAnimation.cs b/spine-unity/Assets/spine-unity/SkeletonAnimation.cs index 8810a5383..b2b367167 100644 --- a/spine-unity/Assets/spine-unity/SkeletonAnimation.cs +++ b/spine-unity/Assets/spine-unity/SkeletonAnimation.cs @@ -42,7 +42,9 @@ public class SkeletonAnimation : SkeletonRenderer { public Spine.AnimationState state; public delegate void UpdateBonesDelegate(SkeletonAnimation skeleton); - public UpdateBonesDelegate UpdateBones; + public UpdateBonesDelegate UpdateLocal; + public UpdateBonesDelegate UpdateWorld; + public UpdateBonesDelegate UpdateComplete; [SerializeField] private String _animationName; @@ -83,7 +85,19 @@ public class SkeletonAnimation : SkeletonRenderer { skeleton.Update(deltaTime); state.Update(deltaTime); state.Apply(skeleton); - if (UpdateBones != null) UpdateBones(this); + + if (UpdateLocal != null) + UpdateLocal(this); + skeleton.UpdateWorldTransform(); + + if (UpdateWorld != null){ + UpdateWorld(this); + skeleton.UpdateWorldTransform(); + } + + if (UpdateComplete != null){ + UpdateComplete(this); + } } } diff --git a/spine-unity/Assets/spine-unity/SkeletonExtensions.cs b/spine-unity/Assets/spine-unity/SkeletonExtensions.cs index ca8e263df..06b414658 100644 --- a/spine-unity/Assets/spine-unity/SkeletonExtensions.cs +++ b/spine-unity/Assets/spine-unity/SkeletonExtensions.cs @@ -1,4 +1,39 @@ -using UnityEngine; +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.1 + * + * Copyright (c) 2013, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable and + * non-transferable license to install, execute and perform the Spine Runtimes + * Software (the "Software") solely for internal use. Without the written + * permission of Esoteric Software (typically granted by licensing Spine), you + * may not (a) modify, translate, adapt or otherwise create derivative works, + * improvements of the Software or develop new applications using the Software + * 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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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. + *****************************************************************************/ + +/***************************************************************************** + * Spine Extensions created by Mitch Thompson + * Full irrevocable rights and permissions granted to Esoteric Software +*****************************************************************************/ + +using UnityEngine; using System.Collections; using Spine; diff --git a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs index 56d475131..a09838247 100644 --- a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs +++ b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs @@ -37,6 +37,10 @@ using Spine; /// Renders a skeleton. [ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))] public class SkeletonRenderer : MonoBehaviour { + + public delegate void SkeletonRendererDelegate(SkeletonRenderer skeletonRenderer); + public SkeletonRendererDelegate OnReset; + [System.NonSerialized] public bool valid; [System.NonSerialized] @@ -96,6 +100,7 @@ public class SkeletonRenderer : MonoBehaviour { skeleton = new Skeleton(skeletonData); if (initialSkinName != null && initialSkinName.Length > 0 && initialSkinName != "default") skeleton.SetSkin(initialSkinName); + if(OnReset != null) OnReset(this); } public void Awake () { @@ -112,7 +117,6 @@ public class SkeletonRenderer : MonoBehaviour { public virtual void LateUpdate () { if (!valid) return; - // Count vertices and submesh triangles. int vertexCount = 0; int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0; @@ -122,7 +126,8 @@ public class SkeletonRenderer : MonoBehaviour { int drawOrderCount = drawOrder.Count; bool renderMeshes = this.renderMeshes; for (int i = 0; i < drawOrderCount; i++) { - Attachment attachment = drawOrder[i].attachment; + Slot slot = drawOrder[i]; + Attachment attachment = slot.attachment; object rendererObject; int attachmentVertexCount, attachmentTriangleCount; @@ -149,7 +154,7 @@ public class SkeletonRenderer : MonoBehaviour { // Populate submesh when material changes. Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject; - if (lastMaterial != material && lastMaterial != null) { + if ((lastMaterial != material && lastMaterial != null) || slot.Data.name[0] == '*') { AddSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false); submeshTriangleCount = 0; submeshFirstVertex = vertexCount; diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility.meta b/spine-unity/Assets/spine-unity/SkeletonUtility.meta new file mode 100644 index 000000000..d690c94de --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: f6e0caaafe294de48af468a6a9321473 +folderAsset: yes +DefaultImporter: + userData: diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor.meta b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor.meta new file mode 100644 index 000000000..386e1e90b --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: a751a9d1e3e26d64d997b66a781df8e9 +folderAsset: yes +DefaultImporter: + userData: diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs new file mode 100644 index 000000000..1a6b80054 --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs @@ -0,0 +1,287 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.1 + * + * Copyright (c) 2013, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable and + * non-transferable license to install, execute and perform the Spine Runtimes + * Software (the "Software") solely for internal use. Without the written + * permission of Esoteric Software (typically granted by licensing Spine), you + * may not (a) modify, translate, adapt or otherwise create derivative works, + * improvements of the Software or develop new applications using the Software + * 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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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. + *****************************************************************************/ + +/***************************************************************************** + * Skeleton Utility created by Mitch Thompson + * Full irrevocable rights and permissions granted to Esoteric Software +*****************************************************************************/ + +using UnityEngine; +using UnityEditor; +using System.Collections; +using System.Collections.Generic; +using Spine; + +[CustomEditor(typeof(SkeletonUtilityBone)), CanEditMultipleObjects] +public class SkeletonUtilityBoneInspector : Editor { + SerializedProperty mode, boneName, zPosition, position, rotation, scale, overrideAlpha, parentReference; + + //multi selected flags + bool containsFollows, containsOverrides, multiObject; + + //single selected helpers + SkeletonUtilityBone utilityBone; + SkeletonUtility skeletonUtility; + bool canCreateHingeChain = false; + + void OnEnable(){ + mode = this.serializedObject.FindProperty("mode"); + boneName = this.serializedObject.FindProperty("boneName"); + zPosition = this.serializedObject.FindProperty("zPosition"); + position = this.serializedObject.FindProperty("position"); + rotation = this.serializedObject.FindProperty("rotation"); + scale = this.serializedObject.FindProperty("scale"); + overrideAlpha = this.serializedObject.FindProperty("overrideAlpha"); + parentReference = this.serializedObject.FindProperty("parentReference"); + + EvaluateFlags(); + + if(utilityBone.valid == false && skeletonUtility != null && skeletonUtility.skeletonRenderer != null){ + skeletonUtility.skeletonRenderer.Reset(); + } + + canCreateHingeChain = CanCreateHingeChain(); + } + + /// + /// Evaluates the flags. + /// + void EvaluateFlags(){ + utilityBone = (SkeletonUtilityBone)target; + skeletonUtility = utilityBone.skeletonUtility; + + if(Selection.objects.Length == 1){ + containsFollows = utilityBone.mode == SkeletonUtilityBone.Mode.Follow; + containsOverrides = utilityBone.mode == SkeletonUtilityBone.Mode.Override; + } + else{ + int boneCount = 0; + foreach(Object o in Selection.objects){ + if(o is GameObject){ + GameObject go = (GameObject)o; + SkeletonUtilityBone sub = go.GetComponent(); + if(sub != null){ + boneCount++; + if(sub.mode == SkeletonUtilityBone.Mode.Follow) + containsFollows = true; + if(sub.mode == SkeletonUtilityBone.Mode.Override) + containsOverrides = true; + } + } + } + + if(boneCount > 1) + multiObject = true; + } + } + + public override void OnInspectorGUI () + { + serializedObject.Update(); + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(mode); + if(EditorGUI.EndChangeCheck()){ + containsOverrides = mode.enumValueIndex == 1; + containsFollows = mode.enumValueIndex == 0; + } + + EditorGUI.BeginDisabledGroup( multiObject ); + { + string str = boneName.stringValue; + if(str == "") str = ""; + if(multiObject) str = ""; + + GUILayout.BeginHorizontal(); + EditorGUILayout.PrefixLabel("Bone"); + + if(GUILayout.Button( str, EditorStyles.popup )){ + BoneSelectorContextMenu( str, ((SkeletonUtilityBone)target).skeletonUtility.skeletonRenderer.skeleton.Bones, "", TargetBoneSelected ); + } + + GUILayout.EndHorizontal(); + } + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.PropertyField(zPosition); + EditorGUILayout.PropertyField(position); + EditorGUILayout.PropertyField(rotation); + EditorGUILayout.PropertyField(scale); + + EditorGUI.BeginDisabledGroup( containsFollows ); + { + EditorGUILayout.PropertyField(overrideAlpha); + EditorGUILayout.PropertyField(parentReference); + } + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.Space(); + + GUILayout.BeginHorizontal(); + { + EditorGUI.BeginDisabledGroup( multiObject || !utilityBone.valid || utilityBone.bone == null || utilityBone.bone.Children.Count == 0); + { + if(GUILayout.Button(new GUIContent("Add Child", SpineEditorUtilities.Icons.bone), GUILayout.Width(150), GUILayout.Height(24))) + BoneSelectorContextMenu( "", utilityBone.bone.Children, "", SpawnChildBoneSelected); + } + EditorGUI.EndDisabledGroup(); + + EditorGUI.BeginDisabledGroup( multiObject || !utilityBone.valid || utilityBone.bone == null || containsOverrides); + { + if(GUILayout.Button(new GUIContent("Add Override", SpineEditorUtilities.Icons.poseBones), GUILayout.Width(150), GUILayout.Height(24))) + SpawnOverride(); + } + EditorGUI.EndDisabledGroup(); + + EditorGUI.BeginDisabledGroup( multiObject || !utilityBone.valid || !canCreateHingeChain ); + { + if(GUILayout.Button(new GUIContent("Create Hinge Chain", SpineEditorUtilities.Icons.hingeChain), GUILayout.Width(150), GUILayout.Height(24))) + CreateHingeChain(); + } + EditorGUI.EndDisabledGroup(); + + } + GUILayout.EndHorizontal(); + + serializedObject.ApplyModifiedProperties(); + } + + void BoneSelectorContextMenu(string current, List bones, string topValue, GenericMenu.MenuFunction2 callback){ + GenericMenu menu = new GenericMenu(); + + if(topValue != "") + menu.AddItem( new GUIContent(topValue), current == topValue, callback, null ); + + for(int i = 0; i < bones.Count; i++){ + menu.AddItem( new GUIContent(bones[i].Data.Name), bones[i].Data.Name == current, callback, bones[i] ); + } + + menu.ShowAsContext(); + + } + + + void TargetBoneSelected(object obj){ + if(obj == null){ + boneName.stringValue = ""; + serializedObject.ApplyModifiedProperties(); + } + else{ + Bone bone = (Bone)obj; + boneName.stringValue = bone.Data.Name; + serializedObject.ApplyModifiedProperties(); + + utilityBone.Reset(); + } + } + + void SpawnChildBoneSelected(object obj){ + if(obj == null){ + //add recursively + foreach(var bone in utilityBone.bone.Children){ + GameObject go = skeletonUtility.SpawnBoneRecursively( bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale ); + SkeletonUtilityBone[] newUtilityBones = go.GetComponentsInChildren(); + foreach(SkeletonUtilityBone utilBone in newUtilityBones) + SkeletonUtilityInspector.AttachIcon(utilBone); + } + } + else{ + Bone bone = (Bone)obj; + GameObject go = skeletonUtility.SpawnBone( bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale ); + SkeletonUtilityInspector.AttachIcon(go.GetComponent()); + Selection.activeGameObject = go; + EditorGUIUtility.PingObject(go); + } + } + + void SpawnOverride(){ + GameObject go = skeletonUtility.SpawnBone( utilityBone.bone, utilityBone.transform.parent, SkeletonUtilityBone.Mode.Override, utilityBone.position, utilityBone.rotation, utilityBone.scale); + go.name = go.name + " [Override]"; + SkeletonUtilityInspector.AttachIcon(go.GetComponent()); + Selection.activeGameObject = go; + EditorGUIUtility.PingObject(go); + } + + bool CanCreateHingeChain(){ + if(utilityBone == null) return false; + if(utilityBone.rigidbody != null) return false; + if(utilityBone.bone != null && utilityBone.bone.Children.Count == 0) return false; + + Rigidbody[] rigidbodies = utilityBone.GetComponentsInChildren(); + + if(rigidbodies.Length > 0) return false; + + return true; + } + + void CreateHingeChain(){ + var utilBoneArr = utilityBone.GetComponentsInChildren(); + + foreach(var utilBone in utilBoneArr){ + AttachRigidbody(utilBone); + } + + utilityBone.rigidbody.isKinematic = true; + + foreach(var utilBone in utilBoneArr){ + if(utilBone == utilityBone) + continue; + + utilBone.mode = SkeletonUtilityBone.Mode.Override; + + HingeJoint joint = utilBone.gameObject.AddComponent(); + joint.axis = Vector3.forward; + joint.connectedBody = utilBone.transform.parent.rigidbody; + joint.useLimits = true; + JointLimits limits = new JointLimits(); + limits.min = -20; + limits.max = 20; + joint.limits = limits; + utilBone.rigidbody.mass = utilBone.transform.parent.rigidbody.mass * 0.75f; + } + } + + void AttachRigidbody(SkeletonUtilityBone utilBone){ + if(utilBone.GetComponent() == null){ + if(utilBone.bone.Data.Length == 0){ + SphereCollider sphere = utilBone.gameObject.AddComponent(); + sphere.radius = 0.1f; + } + else{ + float length = utilBone.bone.Data.Length; + BoxCollider box = utilBone.gameObject.AddComponent(); + box.size = new Vector3( length, length / 3, 0.2f); + box.center = new Vector3(length / 2, 0, 0); + } + } + + utilBone.gameObject.AddComponent(); + } +} diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs.meta b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs.meta new file mode 100644 index 000000000..340d6e2eb --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b3ae20b4bcc31f645afd6f5b64f82473 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs new file mode 100644 index 000000000..7358c7635 --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs @@ -0,0 +1,316 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.1 + * + * Copyright (c) 2013, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable and + * non-transferable license to install, execute and perform the Spine Runtimes + * Software (the "Software") solely for internal use. Without the written + * permission of Esoteric Software (typically granted by licensing Spine), you + * may not (a) modify, translate, adapt or otherwise create derivative works, + * improvements of the Software or develop new applications using the Software + * 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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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. + *****************************************************************************/ + +/***************************************************************************** + * Skeleton Utility created by Mitch Thompson + * Full irrevocable rights and permissions granted to Esoteric Software +*****************************************************************************/ + +using UnityEngine; +using UnityEditor; +#if UNITY_4_3 +//nothing +#else +using UnityEditor.AnimatedValues; +#endif +using System.Collections; +using System.Collections.Generic; +using Spine; + +using System.Reflection; + +[CustomEditor(typeof(SkeletonUtility))] +public class SkeletonUtilityInspector : Editor { + + public static void AttachIcon(SkeletonUtilityBone utilityBone){ + Skeleton skeleton = utilityBone.skeletonUtility.skeletonRenderer.skeleton; + Texture2D icon; + if(utilityBone.bone.Data.Length == 0) + icon = SpineEditorUtilities.Icons.nullBone; + else + icon = SpineEditorUtilities.Icons.boneNib; + + foreach(IkConstraint c in skeleton.IkConstraints){ + if(c.Target == utilityBone.bone){ + icon = SpineEditorUtilities.Icons.constraintNib; + break; + } + } + + + + typeof(EditorGUIUtility).InvokeMember("SetIconForObject", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic, null, null, new object[2]{ utilityBone.gameObject, icon}); + } + + static void AttachIconsToChildren(Transform root){ + if(root != null){ + var utilityBones = root.GetComponentsInChildren(); + foreach(var utilBone in utilityBones){ + AttachIcon(utilBone); + } + } + } + + + + static SkeletonUtilityInspector(){ + #if UNITY_4_3 + showSlots = false; + #else + showSlots = new AnimBool(false); + #endif + } + + SkeletonUtility skeletonUtility; + + Skeleton skeleton; + SkeletonRenderer skeletonRenderer; + Transform transform; + bool isPrefab; + + + Dictionary> attachmentTable = new Dictionary>(); + + + //GUI stuff +#if UNITY_4_3 + static bool showSlots; +#else + static AnimBool showSlots; +#endif + + void OnEnable(){ + skeletonUtility = (SkeletonUtility)target; + skeletonRenderer = skeletonUtility.GetComponent(); + skeleton = skeletonRenderer.skeleton; + transform = skeletonRenderer.transform; + + if(skeleton == null){ + skeletonRenderer.Reset(); + skeletonRenderer.LateUpdate(); + + skeleton = skeletonRenderer.skeleton; + } + + UpdateAttachments(); + + if(PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab) + isPrefab = true; + + } + + void OnDestroy(){ + + } + + void OnSceneGUI(){ + if(skeleton == null){ + OnEnable(); + return; + } + + float flipRotation = skeleton.FlipX ? -1 : 1; + + foreach(Bone b in skeleton.Bones){ + Vector3 vec = transform.TransformPoint(new Vector3(b.WorldX, b.WorldY, 0)); + + Quaternion rot = Quaternion.Euler(0,0,b.WorldRotation * flipRotation); + Vector3 forward = transform.TransformDirection( rot * Vector3.right); + forward *= flipRotation; + + SpineEditorUtilities.Icons.boneMaterial.SetPass(0); + Graphics.DrawMeshNow( SpineEditorUtilities.Icons.boneMesh, Matrix4x4.TRS ( vec, Quaternion.LookRotation(transform.forward, forward), Vector3.one * b.Data.Length * b.WorldScaleX)); + } + } + + void UpdateAttachments(){ + attachmentTable = new Dictionary>(); + Skin skin = skeleton.Skin; + + if(skin == null){ + skin = skeletonRenderer.skeletonDataAsset.GetSkeletonData(true).DefaultSkin; + } + + for(int i = skeleton.Slots.Count-1; i >= 0; i--){ + List attachments = new List(); + skin.FindAttachmentsForSlot(i, attachments); + + attachmentTable.Add(skeleton.Slots[i], attachments); + } + } + + void SpawnHierarchyButton(string label, string tooltip, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca, params GUILayoutOption[] options){ + GUIContent content = new GUIContent(label, tooltip); + if(GUILayout.Button(content, options)){ + if(skeletonUtility.skeletonRenderer == null) + skeletonUtility.skeletonRenderer = skeletonUtility.GetComponent(); + + if(skeletonUtility.boneRoot != null){ + return; + } + + skeletonUtility.SpawnHierarchy(mode, pos, rot, sca); + + SkeletonUtilityBone[] boneComps = skeletonUtility.GetComponentsInChildren(); + foreach(SkeletonUtilityBone b in boneComps) + AttachIcon(b); + } + } + + public override void OnInspectorGUI () + { + if(isPrefab){ + GUILayout.Label(new GUIContent("Cannot edit Prefabs", SpineEditorUtilities.Icons.warning)); + return; + } + + skeletonUtility.boneRoot = (Transform)EditorGUILayout.ObjectField( "Bone Root", skeletonUtility.boneRoot, typeof(Transform), true); + + GUILayout.BeginHorizontal(); + EditorGUI.BeginDisabledGroup(skeletonUtility.boneRoot != null); + { + if(GUILayout.Button(new GUIContent("Spawn Hierarchy", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(150), GUILayout.Height(24))) + SpawnHierarchyContextMenu(); + } + EditorGUI.EndDisabledGroup(); + + if(GUILayout.Button(new GUIContent("Spawn Submeshes", SpineEditorUtilities.Icons.subMeshRenderer), GUILayout.Width(150), GUILayout.Height(24))) + skeletonUtility.SpawnSubRenderers(true); + GUILayout.EndHorizontal(); + + EditorGUI.BeginChangeCheck(); + skeleton.FlipX = EditorGUILayout.ToggleLeft("Flip X", skeleton.FlipX); + skeleton.FlipY = EditorGUILayout.ToggleLeft("Flip Y", skeleton.FlipY); + if(EditorGUI.EndChangeCheck()){ + skeletonRenderer.LateUpdate(); + SceneView.RepaintAll(); + } + +#if UNITY_4_3 + showSlots = EditorGUILayout.Foldout(showSlots, "Slots"); +#else + showSlots.target = EditorGUILayout.Foldout(showSlots.target, "Slots"); + if(EditorGUILayout.BeginFadeGroup(showSlots.faded)){ +#endif + foreach(KeyValuePair> pair in attachmentTable){ + + Slot slot = pair.Key; + + EditorGUILayout.BeginHorizontal(); + EditorGUI.indentLevel = 1; + EditorGUILayout.LabelField(new GUIContent(slot.Data.Name, SpineEditorUtilities.Icons.slot), GUILayout.ExpandWidth(false)); + + EditorGUI.BeginChangeCheck(); + Color c = EditorGUILayout.ColorField(new Color(slot.R, slot.G, slot.B, slot.A), GUILayout.Width(60)); + + if(EditorGUI.EndChangeCheck()){ + slot.SetColor( c ); + skeletonRenderer.LateUpdate(); + } + + EditorGUILayout.EndHorizontal(); + + + + foreach(Attachment attachment in pair.Value){ + + if(slot.Attachment == attachment){ + GUI.contentColor = Color.white; + } + else{ + GUI.contentColor = Color.grey; + } + + EditorGUI.indentLevel = 2; + bool isAttached = attachment == slot.Attachment; + + Texture2D icon = null; + + if(attachment is MeshAttachment || attachment is SkinnedMeshAttachment) + icon = SpineEditorUtilities.Icons.mesh; + else + icon = SpineEditorUtilities.Icons.image; + + bool swap = EditorGUILayout.ToggleLeft( new GUIContent( attachment.Name, icon ), attachment == slot.Attachment ); + + if(!isAttached && swap){ + slot.Attachment = attachment; + skeletonRenderer.LateUpdate(); + } + else if(isAttached && !swap){ + slot.Attachment = null; + skeletonRenderer.LateUpdate(); + } + + GUI.contentColor = Color.white; + } + } + #if UNITY_4_3 + +#else + } + EditorGUILayout.EndFadeGroup(); + if(showSlots.isAnimating) + Repaint(); +#endif + } + + void SpawnHierarchyContextMenu(){ + GenericMenu menu = new GenericMenu(); + + menu.AddItem(new GUIContent("Follow"), false, SpawnFollowHierarchy); + menu.AddItem(new GUIContent("Follow (Root Only)"), false, SpawnFollowHierarchyRootOnly); + menu.AddSeparator(""); + menu.AddItem(new GUIContent("Override"), false, SpawnOverrideHierarchy); + menu.AddItem(new GUIContent("Override (Root Only)"), false, SpawnOverrideHierarchyRootOnly); + + menu.ShowAsContext(); + } + + void SpawnFollowHierarchy(){ + Selection.activeGameObject = skeletonUtility.SpawnHierarchy( SkeletonUtilityBone.Mode.Follow, true, true, true ); + AttachIconsToChildren( skeletonUtility.boneRoot ); + } + + void SpawnFollowHierarchyRootOnly(){ + Selection.activeGameObject = skeletonUtility.SpawnRoot( SkeletonUtilityBone.Mode.Follow, true, true, true ); + AttachIconsToChildren( skeletonUtility.boneRoot ); + } + + void SpawnOverrideHierarchy(){ + Selection.activeGameObject = skeletonUtility.SpawnHierarchy( SkeletonUtilityBone.Mode.Override, true, true, true ); + AttachIconsToChildren( skeletonUtility.boneRoot ); + } + + void SpawnOverrideHierarchyRootOnly(){ + Selection.activeGameObject = skeletonUtility.SpawnRoot( SkeletonUtilityBone.Mode.Override, true, true, true ); + AttachIconsToChildren( skeletonUtility.boneRoot ); + } +} diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs.meta b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs.meta new file mode 100644 index 000000000..7820cbd6d --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a5b90df955eb8c2429ac67c8b2de6c5c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs new file mode 100644 index 000000000..1813512a7 --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs @@ -0,0 +1,335 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.1 + * + * Copyright (c) 2013, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable and + * non-transferable license to install, execute and perform the Spine Runtimes + * Software (the "Software") solely for internal use. Without the written + * permission of Esoteric Software (typically granted by licensing Spine), you + * may not (a) modify, translate, adapt or otherwise create derivative works, + * improvements of the Software or develop new applications using the Software + * 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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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. + *****************************************************************************/ + +/***************************************************************************** + * Skeleton Utility created by Mitch Thompson + * Full irrevocable rights and permissions granted to Esoteric Software +*****************************************************************************/ + +using UnityEngine; +using System.Collections; +using System.Collections.Generic; +using Spine; + +[RequireComponent(typeof(SkeletonAnimation))] +[ExecuteInEditMode] +public class SkeletonUtility : MonoBehaviour { + public delegate void SkeletonUtilityDelegate(); + public event SkeletonUtilityDelegate OnReset; + + public Transform boneRoot; + + void Update(){ + if(boneRoot != null && skeletonRenderer.skeleton != null){ + Vector3 flipScale = Vector3.one; + if(skeletonRenderer.skeleton.FlipX) + flipScale.x = -1; + + if(skeletonRenderer.skeleton.FlipY) + flipScale.y = -1; + + boneRoot.localScale = flipScale; + } + } + + [HideInInspector] + public SkeletonRenderer skeletonRenderer; + + [HideInInspector] + public SkeletonAnimation skeletonAnimation; + + [System.NonSerialized] + public List utilityBones = new List(); + + [System.NonSerialized] + public List utilityConstraints = new List(); +// Dictionary utilityBoneTable; + + + protected bool hasTransformBones; + protected bool hasUtilityConstraints; + protected bool needToReprocessBones; + + void OnEnable(){ + if(skeletonRenderer == null){ + skeletonRenderer = GetComponent(); + } + + if(skeletonAnimation == null){ + skeletonAnimation = GetComponent(); + } + + skeletonRenderer.OnReset -= HandleRendererReset; + skeletonRenderer.OnReset += HandleRendererReset; + + if(skeletonAnimation != null){ + skeletonAnimation.UpdateLocal -= UpdateLocal; + skeletonAnimation.UpdateLocal += UpdateLocal; + } + + + CollectBones(); + } + + void Start(){ + //recollect because order of operations failure when switching between game mode and edit mode... +// CollectBones(); + } + + + + void OnDisable(){ + skeletonRenderer.OnReset -= HandleRendererReset; + + if(skeletonAnimation != null){ + skeletonAnimation.UpdateLocal -= UpdateLocal; + skeletonAnimation.UpdateWorld -= UpdateWorld; + skeletonAnimation.UpdateComplete -= UpdateComplete; + } + } + + void HandleRendererReset(SkeletonRenderer r){ + if(OnReset != null) + OnReset(); + + CollectBones(); + } + + public void RegisterBone(SkeletonUtilityBone bone){ + if(utilityBones.Contains(bone)) + return; + else{ + utilityBones.Add(bone); + needToReprocessBones = true; + } + } + + public void UnregisterBone(SkeletonUtilityBone bone){ + utilityBones.Remove(bone); + } + + public void RegisterConstraint(SkeletonUtilityConstraint constraint){ + + if(utilityConstraints.Contains(constraint)) + return; + else{ + utilityConstraints.Add(constraint); + needToReprocessBones = true; + } + } + + public void UnregisterConstraint(SkeletonUtilityConstraint constraint){ + utilityConstraints.Remove(constraint); + } + + public void CollectBones(){ + if(skeletonRenderer.skeleton == null) + return; + + if(boneRoot != null){ + List constraintTargetNames = new List(); + + foreach(IkConstraint c in skeletonRenderer.skeleton.IkConstraints){ + constraintTargetNames.Add(c.Target.Data.Name); + } + + foreach(var b in utilityBones){ + if(b.bone == null){ + return; + } + if(b.mode == SkeletonUtilityBone.Mode.Override){ + hasTransformBones = true; + } + + if(constraintTargetNames.Contains( b.bone.Data.Name )){ + hasUtilityConstraints = true; + } + } + + if(utilityConstraints.Count > 0) + hasUtilityConstraints = true; + + if(skeletonAnimation != null){ + skeletonAnimation.UpdateWorld -= UpdateWorld; + skeletonAnimation.UpdateComplete -= UpdateComplete; + + if(hasTransformBones || hasUtilityConstraints){ + skeletonAnimation.UpdateWorld += UpdateWorld; + } + + if(hasUtilityConstraints){ + skeletonAnimation.UpdateComplete += UpdateComplete; + } + } + + needToReprocessBones = false; + } + else{ + utilityBones.Clear(); + utilityConstraints.Clear(); + } + + } + + void UpdateLocal(SkeletonAnimation anim){ + + if(needToReprocessBones) + CollectBones(); + + if(utilityBones == null) + return; + + foreach(SkeletonUtilityBone b in utilityBones){ + b.transformLerpComplete = false; + } + + UpdateAllBones(); + } + + void UpdateWorld(SkeletonAnimation anim){ + UpdateAllBones(); + + foreach(SkeletonUtilityConstraint c in utilityConstraints) + c.DoUpdate(); + } + + void UpdateComplete(SkeletonAnimation anim){ + UpdateAllBones(); + } + + void UpdateAllBones(){ + if(boneRoot == null){ + CollectBones(); + } + + if(utilityBones == null) + return; + + foreach(SkeletonUtilityBone b in utilityBones){ + b.DoUpdate(); + } + } + + public Transform GetBoneRoot(){ + if(boneRoot != null) + return boneRoot; + + boneRoot = new GameObject("SkeletonUtility-Root").transform; + boneRoot.parent = transform; + boneRoot.localPosition = Vector3.zero; + boneRoot.localRotation = Quaternion.identity; + boneRoot.localScale = Vector3.one; + + return boneRoot; + } + + public GameObject SpawnRoot(SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca){ + GetBoneRoot(); + Skeleton skeleton = this.skeletonRenderer.skeleton; + + GameObject go = SpawnBone( skeleton.RootBone, boneRoot, mode, pos, rot, sca ); + + CollectBones(); + + return go; + } + + public GameObject SpawnHierarchy(SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca){ + GetBoneRoot(); + + Skeleton skeleton = this.skeletonRenderer.skeleton; + + GameObject go = SpawnBoneRecursively(skeleton.RootBone, boneRoot, mode, pos, rot, sca); + + CollectBones(); + + return go; + } + + public GameObject SpawnBoneRecursively(Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca){ + GameObject go = SpawnBone(bone, parent, mode, pos, rot, sca); + + foreach(Bone child in bone.Children){ + SpawnBoneRecursively(child, go.transform, mode, pos, rot, sca); + } + + return go; + } + + public GameObject SpawnBone(Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca){ + GameObject go = new GameObject(bone.Data.Name); + go.transform.parent = parent; + + SkeletonUtilityBone b = go.AddComponent(); + b.skeletonUtility = this; + b.position = pos; + b.rotation = rot; + b.scale = sca; + b.mode = mode; + b.zPosition = true; + b.Reset(); + b.bone = bone; + b.boneName = bone.Data.Name; + b.valid = true; + + if(mode == SkeletonUtilityBone.Mode.Override){ + if(rot) + go.transform.localRotation = Quaternion.Euler(0, 0, b.bone.RotationIK); + + if(pos) + go.transform.localPosition = new Vector3(b.bone.X, b.bone.Y, 0); + + go.transform.localScale = new Vector3(b.bone.scaleX, b.bone.scaleY, 0); + } + + return go; + } + + public void SpawnSubRenderers(bool disablePrimaryRenderer){ + int submeshCount = GetComponent().sharedMesh.subMeshCount; + + for(int i = 0; i < submeshCount; i++){ + GameObject go = new GameObject("Submesh " + i, typeof(MeshFilter), typeof(MeshRenderer)); + go.transform.parent = transform; + go.transform.localPosition = Vector3.zero; + go.transform.localRotation = Quaternion.identity; + go.transform.localScale = Vector3.one; + + SkeletonUtilitySubmeshRenderer s = go.AddComponent(); + s.sortingOrder = i * 10; + s.submeshIndex = i; + s.Initialize( renderer ); + s.Update(); + } + + if(disablePrimaryRenderer) + renderer.enabled = false; + } +} diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs.meta b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs.meta new file mode 100644 index 000000000..7d3d7a44f --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7f726fb798ad621458c431cb9966d91d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs new file mode 100644 index 000000000..51dee1cc6 --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs @@ -0,0 +1,218 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.1 + * + * Copyright (c) 2013, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable and + * non-transferable license to install, execute and perform the Spine Runtimes + * Software (the "Software") solely for internal use. Without the written + * permission of Esoteric Software (typically granted by licensing Spine), you + * may not (a) modify, translate, adapt or otherwise create derivative works, + * improvements of the Software or develop new applications using the Software + * 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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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. + *****************************************************************************/ + +/***************************************************************************** + * Skeleton Utility created by Mitch Thompson + * Full irrevocable rights and permissions granted to Esoteric Software +*****************************************************************************/ + +using System; +using System.IO; +using System.Collections.Generic; +using UnityEngine; +using Spine; + +/// Sets a GameObject's transform to match a bone on a Spine skeleton. +[ExecuteInEditMode] +[AddComponentMenu("Spine/SkeletonUtilityBone")] +public class SkeletonUtilityBone : MonoBehaviour { + + public enum Mode { Follow, Override } + + [System.NonSerialized] + public bool valid; + + [System.NonSerialized] + public SkeletonUtility skeletonUtility; + + [System.NonSerialized] + public Bone bone; + + public Mode mode; + + public bool zPosition = true; + public bool position; + public bool rotation; + public bool scale; + + [Range(0f,1f)] + public float overrideAlpha = 1; + + /// If a bone isn't set, boneName is used to find the bone. + public String boneName; + + public Transform parentReference; + + [HideInInspector] + public bool transformLerpComplete; + + protected Transform cachedTransform; + protected Transform skeletonTransform; + + public bool NonUniformScaleWarning{ + get{ + return nonUniformScaleWarning; + } + } + private bool nonUniformScaleWarning; + + public void Reset () { + bone = null; + cachedTransform = transform; + valid = skeletonUtility != null && skeletonUtility.skeletonRenderer != null && skeletonUtility.skeletonRenderer.valid; + if (!valid) return; + skeletonTransform = skeletonUtility.transform; + + skeletonUtility.OnReset -= HandleOnReset; + skeletonUtility.OnReset += HandleOnReset; + + DoUpdate(); + } + + void OnEnable(){ + skeletonUtility = GetComponentInParent(); + if(skeletonUtility == null) + return; + + skeletonUtility.RegisterBone(this); + + skeletonUtility.OnReset += HandleOnReset; + } + + void HandleOnReset () + { + Reset (); + } + + void OnDisable(){ + if(skeletonUtility != null){ + skeletonUtility.OnReset -= HandleOnReset; + + skeletonUtility.UnregisterBone(this); + } + } + + public void DoUpdate () { + + if (!valid) { + Reset(); + return; + } + + Spine.Skeleton skeleton = skeletonUtility.skeletonRenderer.skeleton; + + if (bone == null) { + if (boneName == null || boneName.Length == 0) return; + bone = skeleton.FindBone(boneName); + if (bone == null) { + Debug.LogError("Bone not found: " + boneName, this); + return; + } + } + + + float flipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f; + + + if(mode == Mode.Follow){ + if(position){ + cachedTransform.localPosition = new Vector3(bone.x, bone.y, 0); + } + + if(rotation){ + + if(bone.Data.InheritRotation){ + cachedTransform.localRotation = Quaternion.Euler(0,0,bone.rotationIK); + } + else{ + Vector3 euler = skeletonTransform.rotation.eulerAngles; + cachedTransform.rotation = Quaternion.Euler(euler.x, euler.y, skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * flipRotation) ); + } + + } + + if(scale){ + cachedTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1); + + nonUniformScaleWarning = (bone.scaleX != bone.scaleY); + } + + } + else if(mode == Mode.Override){ + if(transformLerpComplete) + return; + + if(parentReference == null){ + if(position){ + bone.x = Mathf.Lerp(bone.x, cachedTransform.localPosition.x, overrideAlpha); + bone.y = Mathf.Lerp(bone.y, cachedTransform.localPosition.y, overrideAlpha); + } + + if(rotation){ + bone.rotation = Mathf.LerpAngle(bone.Rotation, cachedTransform.localRotation.eulerAngles.z, overrideAlpha); + } + + if(scale){ + bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha); + bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha); + + nonUniformScaleWarning = (bone.scaleX != bone.scaleY); + } + } + else{ + if(position){ + Vector3 pos = parentReference.InverseTransformPoint(cachedTransform.position); + bone.x = Mathf.Lerp(bone.x, pos.x, overrideAlpha); + bone.y = Mathf.Lerp(bone.y, pos.y, overrideAlpha); + } + + if(rotation){ + bone.rotation = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation( Vector3.forward, parentReference.InverseTransformDirection( cachedTransform.up ) ).eulerAngles.z, overrideAlpha); + } + + //TODO: Something about this + if(scale){ + bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha); + bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha); + + nonUniformScaleWarning = (bone.scaleX != bone.scaleY); + } + } + + transformLerpComplete = true; + } + } + + void OnDrawGizmos(){ + if(NonUniformScaleWarning){ + Gizmos.DrawIcon(transform.position + new Vector3(0,0.128f,0), "icon-warning"); + } + } +} \ No newline at end of file diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs.meta b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs.meta new file mode 100644 index 000000000..f66d45053 --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b238dfcde8209044b97d23f62bcaadf6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs new file mode 100644 index 000000000..ffdcf1dd3 --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs @@ -0,0 +1,22 @@ +using UnityEngine; +using System.Collections; + +[RequireComponent(typeof(SkeletonUtilityBone)), ExecuteInEditMode] + +public abstract class SkeletonUtilityConstraint : MonoBehaviour { + + protected SkeletonUtilityBone utilBone; + protected SkeletonUtility skeletonUtility; + + protected virtual void OnEnable(){ + utilBone = GetComponent(); + skeletonUtility = 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-unity/SkeletonUtility/SkeletonUtilityConstraint.cs.meta new file mode 100644 index 000000000..dad11e0a2 --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityConstraint.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 522dbfcc6c916df4396f14f35048d185 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityEyeConstraint.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityEyeConstraint.cs new file mode 100644 index 000000000..07203faef --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityEyeConstraint.cs @@ -0,0 +1,61 @@ +using UnityEngine; +using System.Collections; + +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); + } + + } +} \ No newline at end of file diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityEyeConstraint.cs.meta b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityEyeConstraint.cs.meta new file mode 100644 index 000000000..3e82746da --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityEyeConstraint.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0d994c65b6daec64f80ae2ae04e9d999 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs new file mode 100644 index 000000000..70301d92d --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs @@ -0,0 +1,58 @@ +using UnityEngine; +using System.Collections; + +[RequireComponent(typeof(SkeletonUtilityBone)), ExecuteInEditMode] +public class SkeletonUtilityGroundConstraint : SkeletonUtilityConstraint { + + public LayerMask groundMask; + public bool use2D = true; + public float castDistance = 5f; + Vector3 rayOrigin; + Vector3 rayDir = new Vector3(0,-1,0); + float hitY; + + protected override void OnEnable () + { + base.OnEnable (); + } + + protected override void OnDisable () + { + base.OnDisable (); + } + + public override void DoUpdate() + { + rayOrigin = transform.position + new Vector3(0,castDistance,0); + + hitY = float.MinValue; + if(use2D){ + RaycastHit2D hit = Physics2D.Raycast(rayOrigin , rayDir, castDistance, groundMask); + if(hit.collider != null){ + hitY = hit.point.y; + } + } + else{ + RaycastHit hit; + if(Physics.Raycast( rayOrigin, rayDir, out hit, castDistance, groundMask)){ + hitY = hit.point.y; + } + } + + Vector3 v = transform.position; + v.y = Mathf.Clamp(v.y, hitY, float.MaxValue); + transform.position = v; + + utilBone.bone.X = transform.localPosition.x; + utilBone.bone.Y = transform.localPosition.y; + + } + + void OnDrawGizmos(){ + Vector3 hitEnd = rayOrigin + (rayDir * Mathf.Min(castDistance, rayOrigin.y - hitY)); + Vector3 clearEnd = rayOrigin + (rayDir * castDistance); + Gizmos.DrawLine(rayOrigin, hitEnd); + Gizmos.color = Color.red; + Gizmos.DrawLine(hitEnd, clearEnd); + } +} diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs.meta b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs.meta new file mode 100644 index 000000000..5d9e6920c --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3662334b99de5fe4396ab24e30c4fd12 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityKinematicShadow.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityKinematicShadow.cs new file mode 100644 index 000000000..917eb5a45 --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityKinematicShadow.cs @@ -0,0 +1,81 @@ +using UnityEngine; +using System.Collections; +using System.Collections.Generic; + +public class SkeletonUtilityKinematicShadow : MonoBehaviour { + + public bool hideShadow = true; + + Dictionary shadowTable; + GameObject shadowRoot; + + void Start(){ + shadowRoot = (GameObject)Instantiate(gameObject); + if(hideShadow) + shadowRoot.hideFlags = HideFlags.HideInHierarchy; + + shadowRoot.transform.parent = transform.root; + + shadowTable = new Dictionary(); + + Destroy(shadowRoot.GetComponent()); + + shadowRoot.transform.position = transform.position; + shadowRoot.transform.rotation = transform.rotation; + + Vector3 scaleRef = transform.TransformPoint(Vector3.right); + float scale = Vector3.Distance(transform.position, scaleRef); + shadowRoot.transform.localScale = Vector3.one; + + var shadowJoints = shadowRoot.GetComponentsInChildren(); + foreach(Joint j in shadowJoints){ + j.connectedAnchor *= scale; + } + + var joints = GetComponentsInChildren(); + foreach(var j in joints) + Destroy(j); + + var rbs = GetComponentsInChildren(); + foreach(var rb in rbs) + Destroy(rb); + + var colliders = GetComponentsInChildren(); + foreach(var c in colliders) + Destroy(c); + + + //match by bone name + var shadowBones = shadowRoot.GetComponentsInChildren(); + var bones = GetComponentsInChildren(); + + //build bone lookup + foreach(var b in bones){ + if(b.gameObject == gameObject) + continue; + + foreach(var sb in shadowBones){ + if(sb.rigidbody == null) + continue; + + if(sb.boneName == b.boneName){ + shadowTable.Add( sb.transform, b.transform ); + break; + } + } + } + + foreach(var b in shadowBones) + Destroy(b); + } + + void FixedUpdate(){ + shadowRoot.rigidbody.MovePosition( transform.position ); + shadowRoot.rigidbody.MoveRotation( transform.rotation ); + + foreach(var pair in shadowTable){ + pair.Value.localPosition = pair.Key.localPosition; + pair.Value.localRotation = pair.Key.localRotation; + } + } +} \ No newline at end of file diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityKinematicShadow.cs.meta b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityKinematicShadow.cs.meta new file mode 100644 index 000000000..06bcb6f4a --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityKinematicShadow.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cfeac06b8a6aa1645813700e3e4c0863 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs new file mode 100644 index 000000000..f6a2e682b --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs @@ -0,0 +1,102 @@ +using UnityEngine; +using System.Collections; + +[ExecuteInEditMode] +public class SkeletonUtilitySubmeshRenderer : MonoBehaviour { + + public Renderer parentRenderer; + + [System.NonSerialized] + public Mesh mesh; + + public int submeshIndex = 0; + public int sortingOrder = 0; + public int sortingLayerID = 0; + + public Material hiddenPassMaterial; + Renderer cachedRenderer; + MeshFilter filter; + Material[] sharedMaterials; + MeshFilter parentFilter; + + void Awake(){ + cachedRenderer = renderer; + sharedMaterials = cachedRenderer.sharedMaterials; + filter = GetComponent(); + + if(parentRenderer != null) + Initialize( parentRenderer ); + } + + void OnEnable(){ + parentRenderer = transform.parent.GetComponent(); + parentRenderer.GetComponent().OnReset += HandleSkeletonReset; + } + + void OnDisable(){ + parentRenderer.GetComponent().OnReset -= HandleSkeletonReset; + } + + void HandleSkeletonReset(SkeletonRenderer r){ + if(parentRenderer != null) + Initialize(parentRenderer); + } + + public void Initialize(Renderer parentRenderer){ + this.parentRenderer = parentRenderer; + parentFilter = parentRenderer.GetComponent(); + mesh = parentFilter.sharedMesh; + filter.sharedMesh = mesh; + Debug.Log("Mesh: " + mesh); + } + + public void Update(){ + if(mesh == null || mesh != parentFilter.sharedMesh){ + mesh = parentFilter.sharedMesh; + filter.sharedMesh = mesh; + } + + if(cachedRenderer == null) + cachedRenderer = renderer; + + if(mesh == null || submeshIndex > mesh.subMeshCount - 1){ + cachedRenderer.enabled = false; + return; + } + else{ + renderer.enabled = true; + } + + bool changed = false; + + if(sharedMaterials.Length != parentRenderer.sharedMaterials.Length){ + sharedMaterials = parentRenderer.sharedMaterials; + changed = true; + } + + + + for(int i = 0; i < renderer.sharedMaterials.Length; i++){ + if(i == submeshIndex) + continue; + + if(sharedMaterials[i] != hiddenPassMaterial){ + sharedMaterials[i] = hiddenPassMaterial; + changed = true; + } + } + + if(sharedMaterials[submeshIndex] != parentRenderer.sharedMaterials[submeshIndex]){ + sharedMaterials[submeshIndex] = parentRenderer.sharedMaterials[submeshIndex]; + changed = true; + } + + if(changed){ + cachedRenderer.sharedMaterials = sharedMaterials; + } + + + cachedRenderer.sortingLayerID = sortingLayerID; + cachedRenderer.sortingOrder = sortingOrder; + } +} diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs.meta b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs.meta new file mode 100644 index 000000000..168ca8811 --- /dev/null +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7820c1c2b0e52c6408de899d6939996e +MonoImporter: + serializedVersion: 2 + defaultReferences: + - parentRenderer: {instanceID: 0} + - mesh: {instanceID: 0} + - hiddenPassMaterial: {fileID: 2100000, guid: 43227e5adadc6f24bb4bf74b92a56fb4, + type: 2} + executionOrder: 0 + icon: {instanceID: 0} + userData: From aabf89e29c9b62e35db1225cd51399460a286cff Mon Sep 17 00:00:00 2001 From: Fenrisul Date: Thu, 11 Sep 2014 20:15:13 -0700 Subject: [PATCH 6/8] Fixed Goblins.cs compile error due to UpdateBones refactor --- spine-unity/Assets/Examples/Scripts/Goblins.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spine-unity/Assets/Examples/Scripts/Goblins.cs b/spine-unity/Assets/Examples/Scripts/Goblins.cs index c30e677b0..bf3a78079 100644 --- a/spine-unity/Assets/Examples/Scripts/Goblins.cs +++ b/spine-unity/Assets/Examples/Scripts/Goblins.cs @@ -40,11 +40,11 @@ public class Goblins : MonoBehaviour { public void Start () { skeletonAnimation = GetComponent(); headBone = skeletonAnimation.skeleton.FindBone("head"); - skeletonAnimation.UpdateBones += UpdateBones; + skeletonAnimation.UpdateLocal += UpdateLocal; } // This is called after the animation is applied to the skeleton and can be used to adjust the bones dynamically. - public void UpdateBones (SkeletonAnimation skeletonAnimation) { + public void UpdateLocal (SkeletonAnimation skeletonAnimation) { headBone.Rotation += 15; } From e87b15bcf8d3c4e942df8be0fc0bd05aa41635b6 Mon Sep 17 00:00:00 2001 From: Fenrisul Date: Thu, 11 Sep 2014 20:16:06 -0700 Subject: [PATCH 7/8] BoneComponent deprecated and removed --- .../Editor/BoneComponentInspector.cs | 78 ------------------- .../Editor/BoneComponentInspector.cs.meta | 8 -- 2 files changed, 86 deletions(-) delete mode 100644 spine-unity/Assets/spine-unity/Editor/BoneComponentInspector.cs delete mode 100644 spine-unity/Assets/spine-unity/Editor/BoneComponentInspector.cs.meta diff --git a/spine-unity/Assets/spine-unity/Editor/BoneComponentInspector.cs b/spine-unity/Assets/spine-unity/Editor/BoneComponentInspector.cs deleted file mode 100644 index b7373393c..000000000 --- a/spine-unity/Assets/spine-unity/Editor/BoneComponentInspector.cs +++ /dev/null @@ -1,78 +0,0 @@ -/****************************************************************************** - * Spine Runtimes Software License - * Version 2.1 - * - * Copyright (c) 2013, Esoteric Software - * All rights reserved. - * - * You are granted a perpetual, non-exclusive, non-sublicensable and - * non-transferable license to install, execute and perform the Spine Runtimes - * Software (the "Software") solely for internal use. Without the written - * permission of Esoteric Software (typically granted by licensing Spine), you - * may not (a) modify, translate, adapt or otherwise create derivative works, - * improvements of the Software or develop new applications using the Software - * 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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) 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 UnityEditor; -using UnityEngine; - -[CustomEditor(typeof(BoneComponent))] -public class BoneComponentInspector : Editor { - private SerializedProperty boneName, skeletonRenderer, followZPosition, followBoneRotation; - - void OnEnable () { - skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); - boneName = serializedObject.FindProperty("boneName"); - followBoneRotation = serializedObject.FindProperty("followBoneRotation"); - followZPosition = serializedObject.FindProperty("followZPosition"); - } - - override public void OnInspectorGUI () { - serializedObject.Update(); - BoneComponent component = (BoneComponent)target; - - EditorGUILayout.PropertyField(skeletonRenderer); - - if (component.valid) { - String[] bones = new String[component.skeletonRenderer.skeleton.Data.Bones.Count + 1]; - bones[0] = ""; - for (int i = 0; i < bones.Length - 1; i++) - bones[i + 1] = component.skeletonRenderer.skeleton.Data.Bones[i].Name; - Array.Sort(bones); - int boneIndex = Math.Max(0, Array.IndexOf(bones, boneName.stringValue)); - - EditorGUILayout.BeginHorizontal(); - EditorGUILayout.LabelField("Bone"); - EditorGUIUtility.LookLikeControls(); - boneIndex = EditorGUILayout.Popup(boneIndex, bones); - EditorGUILayout.EndHorizontal(); - - boneName.stringValue = boneIndex == 0 ? null : bones[boneIndex]; - - EditorGUILayout.PropertyField(followBoneRotation); - EditorGUILayout.PropertyField(followZPosition); - } - - if (serializedObject.ApplyModifiedProperties() || - (Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed") - ) { - component.Reset(); - } - } -} diff --git a/spine-unity/Assets/spine-unity/Editor/BoneComponentInspector.cs.meta b/spine-unity/Assets/spine-unity/Editor/BoneComponentInspector.cs.meta deleted file mode 100644 index 1b03fab20..000000000 --- a/spine-unity/Assets/spine-unity/Editor/BoneComponentInspector.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: dca21b77745bb4245a4e2e012c282ce6 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: From 8894365ac7ae30c897f738c1bc415d362d97c5ed Mon Sep 17 00:00:00 2001 From: Fenrisul Date: Thu, 11 Sep 2014 20:43:05 -0700 Subject: [PATCH 8/8] Updated Unity examples to include SkeletonUtility features --- spine-unity/Assets/Examples/Scenes/Eyes.unity | Bin 0 -> 23136 bytes .../Assets/Examples/Scenes/Eyes.unity.meta | 4 ++ .../Scenes/Raptor Animated Physics.unity | Bin 0 -> 35808 bytes .../Scenes/Raptor Animated Physics.unity.meta | 4 ++ .../Scenes/Raptor GroundConstraint.unity | Bin 0 -> 24204 bytes .../Scenes/Raptor GroundConstraint.unity.meta | 4 ++ .../Assets/Examples/Scenes/Spineboy.unity | Bin 20832 -> 21060 bytes spine-unity/Assets/Examples/Spine/Eyes.meta | 5 ++ .../Assets/Examples/Spine/Eyes/eyes.atlas.txt | 34 +++++++++++++ .../Examples/Spine/Eyes/eyes.atlas.txt.meta | 4 ++ .../Assets/Examples/Spine/Eyes/eyes.json | 1 + .../Assets/Examples/Spine/Eyes/eyes.json.meta | 4 ++ .../Assets/Examples/Spine/Eyes/eyes.png | Bin 0 -> 30130 bytes .../Assets/Examples/Spine/Eyes/eyes.png.meta | 47 ++++++++++++++++++ .../Examples/Spine/Eyes/eyes_Atlas.asset | Bin 0 -> 4180 bytes .../Examples/Spine/Eyes/eyes_Atlas.asset.meta | 4 ++ .../Examples/Spine/Eyes/eyes_Material.mat | Bin 0 -> 4216 bytes .../Spine/Eyes/eyes_Material.mat.meta | 4 ++ .../Spine/Eyes/eyes_SkeletonData.asset | Bin 0 -> 4204 bytes .../Spine/Eyes/eyes_SkeletonData.asset.meta | 4 ++ .../Assets/Examples/Spine/dragon.prefab | Bin 3190 -> 9144 bytes spine-unity/Assets/Examples/Spine/eyes.prefab | Bin 0 -> 9024 bytes .../Assets/Examples/Spine/eyes.prefab.meta | 4 ++ .../Assets/Examples/Spine/goblins-ffd.prefab | Bin 2770 -> 10168 bytes .../Assets/Examples/Spine/raptor.prefab | Bin 9016 -> 9040 bytes .../Assets/Examples/Spine/spineboy.prefab | Bin 2411 -> 9040 bytes 26 files changed, 123 insertions(+) create mode 100644 spine-unity/Assets/Examples/Scenes/Eyes.unity create mode 100644 spine-unity/Assets/Examples/Scenes/Eyes.unity.meta create mode 100644 spine-unity/Assets/Examples/Scenes/Raptor Animated Physics.unity create mode 100644 spine-unity/Assets/Examples/Scenes/Raptor Animated Physics.unity.meta create mode 100644 spine-unity/Assets/Examples/Scenes/Raptor GroundConstraint.unity create mode 100644 spine-unity/Assets/Examples/Scenes/Raptor GroundConstraint.unity.meta create mode 100644 spine-unity/Assets/Examples/Spine/Eyes.meta create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes.atlas.txt create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes.atlas.txt.meta create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes.json create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes.json.meta create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes.png create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes.png.meta create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes_Atlas.asset create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes_Atlas.asset.meta create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes_Material.mat create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes_Material.mat.meta create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes_SkeletonData.asset create mode 100644 spine-unity/Assets/Examples/Spine/Eyes/eyes_SkeletonData.asset.meta create mode 100644 spine-unity/Assets/Examples/Spine/eyes.prefab create mode 100644 spine-unity/Assets/Examples/Spine/eyes.prefab.meta diff --git a/spine-unity/Assets/Examples/Scenes/Eyes.unity b/spine-unity/Assets/Examples/Scenes/Eyes.unity new file mode 100644 index 0000000000000000000000000000000000000000..ae92cee9e0d94ce5a0d70f210a057e288a9692b3 GIT binary patch literal 23136 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 MpkF$MMH@lzUz?7jqyPW_ literal 0 HcmV?d00001 diff --git a/spine-unity/Assets/Examples/Scenes/Eyes.unity.meta b/spine-unity/Assets/Examples/Scenes/Eyes.unity.meta new file mode 100644 index 000000000..81096830a --- /dev/null +++ b/spine-unity/Assets/Examples/Scenes/Eyes.unity.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 51036c61bd222d9469b4e94cc89cceae +DefaultImporter: + userData: diff --git a/spine-unity/Assets/Examples/Scenes/Raptor Animated Physics.unity b/spine-unity/Assets/Examples/Scenes/Raptor Animated Physics.unity new file mode 100644 index 0000000000000000000000000000000000000000..d13511343bda9e5109934707e2f433998f4dbf6d GIT binary patch literal 35808 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 PKYqPO7<>!OP36R2hAI|_ literal 0 HcmV?d00001 diff --git a/spine-unity/Assets/Examples/Spine/Eyes/eyes_Atlas.asset.meta b/spine-unity/Assets/Examples/Spine/Eyes/eyes_Atlas.asset.meta new file mode 100644 index 000000000..259c170b5 --- /dev/null +++ b/spine-unity/Assets/Examples/Spine/Eyes/eyes_Atlas.asset.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: dcae7523c93690f4c80520308eced1e2 +NativeFormatImporter: + userData: diff --git a/spine-unity/Assets/Examples/Spine/Eyes/eyes_Material.mat b/spine-unity/Assets/Examples/Spine/Eyes/eyes_Material.mat new file mode 100644 index 0000000000000000000000000000000000000000..9331c1f35b6e27dd032a72256218afb12e3a1503 GIT binary patch literal 4216 zcmeHKOLH7G5SD=uNO*)-NO)y|K*GyFobWV`AMpkk1=++V#R-?})vSlwopEWj#>;6g z`3EWf0ag42a^p;eU%)8`4*USFG5vLq#@ew6R}R}%yVFvCQnx;JOEXFxxvtc)U8U5+ z^rVMU=cg}B&m=SI?%v+s6t$nB-N z9~JfgU;~8a0sn_1pu*WS>(T1J(gR@{J|P@sDbEFK^+?G-c7ryrrgUmv)tnUR4~F?T zLI8*?RrJj*ZB`tZwP9u^>YYu~-4J-yMe zqZxX7Gh&zYZ6jXE-nT+fDSO?_fwu_*;+QE=&!EQxfPBYukN@O@IptJG^5v7 gTnFVXyq=YGQ{g899KLebmxeA+67~D-+k7Sd15@SiP~;yLD-dhJ}0UIcIL$X*>M^CY`2tUf((2dG*eevDO%4yIsau8}!gIb~Sn} zI+z_~e~ZOp1m@5cr+m*J5lej8@$-_6@IcTq;o*TWwyG86y}()YM5f2_6wA%eEIbxz zHQ{8$xXTv(Ckh>X$96&sSC64K)?@o&*WWhpEF)*28_ z>-e`>K*WEW=Y;kcZK%wMA7g+Gt&YRf$`2`}Rs!Lqj=x=F%9?O`AAG$IqzR8NxFSP) z+YMYKt|v9Q*6FLx^$t@k9Fu!kQnP94JXPqP9+7K14GA1tUE5`V&^>H*u65{jGQR{0 zlytmBV4Q~VQW5K_4+~&545^fSg~jQK^}h!+p$7WKDmDeqGeM=c7dEk#KsZh>amg}V zaa!GnOVCV2*%%$UQI`inG6R+FWE~;Ny8T*8i>+#LZCAy*1BTj2%wk=qsU#d%TX)cc zpfvTx6<8Gy0s(pAoRr30@CzzqM$2sdrpokcxzGGx=rv4d)j&c zQ?3TUl)_gosuQM?Fmz$bP+4JRo-{EHhg{ zSaim)2r+f8pEZ@V>PfBZ=S)lkqVook)%6R861(dcEr`(dOkP$}e#yXLePC*9f2mPe zE2kVVb$(y2QG!!lh?H?WtgbYMz)_iZ)s$19cT&Fvh)ZZd?9Y4J#giY)NJ3A?W%tcH zYjZc=B|dx_xb>>@-e-M=uK#>6@H*W#^D?!m<;SnCDB8`~@3q24Pv7&=H;%=7 UZ@)~k_HVsI;TCo4U+)h81HiJ6tN;K2 literal 0 HcmV?d00001 diff --git a/spine-unity/Assets/Examples/Spine/Eyes/eyes_SkeletonData.asset.meta b/spine-unity/Assets/Examples/Spine/Eyes/eyes_SkeletonData.asset.meta new file mode 100644 index 000000000..64b2267c0 --- /dev/null +++ b/spine-unity/Assets/Examples/Spine/Eyes/eyes_SkeletonData.asset.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: ef2f009a37ff7ff42bc2a2f407ca9483 +NativeFormatImporter: + userData: diff --git a/spine-unity/Assets/Examples/Spine/dragon.prefab b/spine-unity/Assets/Examples/Spine/dragon.prefab index 34e41c9bc4a4bb8cf2a16a159de0337baa1af3d9..7fd541d13c13aee0dc8f371759f185e771a7c7f6 100644 GIT binary patch literal 9144 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 literal 3190 zcmeHJOK;ma5WeeIu!rUp7uL%U-P|;34a7-cxeF{73u8o5GFyo>Bsy(U^uOQ+T5{5lR z81^(lUla5-zTfwT|Lv`+^))>3x_jmgW+Nf2hC)dj)C!7J*FqKv`6w}^1!q=1rzY^z z4BWu|f;XEZm#GFV=p_?c)ki6vH#4fmJ>KVcWr@g{3(Z^AAe&s()iYJ`Z4^JRD%HBz z2#0qa%7%$j6w0MC&#`a+ib*>s5BB?LzhCevt`+RrJJpD1&h}2F=oNGD4c+*!)5N`_6BkiY)6Prd@ZG4(o4{Zc7?TQgV6w#$Q%oV9)6ExAM`s;!qNUH%L5c_|?) zIWy%qgLeUqPB*~R7aTe#T5`&y?M4rAjcZlBV?mHnI)JAv`BcoIh;osRP9)SreCg~>Pyr!mi>VGsoLoal!w zmN0Mw`kb3E7>{!n$0MIj<8cu2Nk~T&BJddtCJ_BkH@~A99Gd@krCxO3RO@t?;T+`IilBwo(eG%+1#tfMqOqGt!~-a<+BmT%x*sND;S{$%Gn zR`7&urL-2?eqZ>0Y#GabBL~qqgW(9baSkw!*fb2|JdP%Q7G&{gzmY?SvyRo+s=FI6 zN@$unL#`!qVIUKA&1YV6t>inYlSb mZ|-!}+WBe&J)lJk`)29r^C>%`fOwCL~PxsK> zv+Vjbrzltc03=@ti6Z5Xh;q!IkSo`qh#Q;tz1P+Ks=H?oNQn~3WzF`F`l{Zmdau6s zs@leEzF^FSzA@&kF`K(|HLt$-+KZPam(15ECnxvPGhI%ur%8I*&Fo>6E;Do4=8j(j zj?%-Ql`%h{%QDHMY2wBkQBs)st(}7p+^Bdb8oRe*JI&2K1Yvl2_4m8GMfS_>aa5$) z_EF)elQemg+V5s=Vh?t0=8{7CGWS!{Z_y70&3p6@&m!=xD0YLZEa%%mQ1Kw#3uxCC zvl0Y_P&9~@5y`abP;}QV`S%GX0I~eH?cB+Tp+o(|@-YV} z=z5F(cFHG{a`7NMwB$b^n5ri{-lVaZRgOwr$87UN^58j$$M7cgYqJak|{~NLDS1l{IEu?$|=n< zdu+D&FZ}-z!k`EK^=qB-=(b~5`#x2oco6PKGn<*QEiAu%6tAdgM5T<(+?Cko`Cv?* z9!(;bv36KeDBNr%SJA81?lE7FYrjLg$EgBE%MP`BLI44R&2(}2p^IISCRb@7TY2ut zTzT^q+wGj{0xvr4_M`&!N+)jF?Wqn>IaN^-6_JgHA4W-Kz^4`5{JwjNo*|4Meea!G zxypb)RGoOm!YTSu2SOIg$i|~(YzucI&E_`FS<;Uc+zjNQ0pGXDl#DI-jSl=IPHkas z4;OX>rv+7QYFIge(k(IM*k#vUK6BFJc?}ITi01QUfu+5lMWjPqHn_01L7Yyvvn1YeXy^>~t5CD9a08hdQnSfx?7Y=}SE6Mrkr` z1vTB_{FcgBbWrnsw#ZQjH4kby+% zSBIJZdgA}?lCqdAp_n@%@3@vyDBnxrRI~!XC7Kt_{Tu8a68Vo>tcZFPsXylWAh!?d zZ*#q7z_9(tT(8N`*Z-O$#idH&-882hkrW0+2Lwn0u_e?B2h9G3wtk3i=B)TaQ4$pfmPFoM;K?1b94f=@<;A#WegnhE|XSAIRCdt zC}n_MdxAn{Mk!%eY+ej!cAS1JJ1m`D3b2CixsjuYtxKI@)%yC1+^!>T(ZN98Iy8YASX@nZ(}yO&wAd{mTOg<~&3IXg+ydeyobN1P7|ppt z9UTm#b4(AaMmby_kTuAZ(TKL}NR%}N1Ku@KFt4w})hk!=xMp1dPy!C(LoDnkH1&F9 zn|dV;y=;ro47Aw6!L<^>422xbdbD%r4S8P;36JG6x|uun_uVW#D9GfCKIxq+| zOS6L3CvOkRlWcvK;-w4+N%8XQl*^TP2~ik{K1;!d4h55iO$Y5sX*o%d^17qm_j-oz z8~WT$_x&Q1Nox7P|6;l?bVdfpMgxXtzYmlAHGZ!nls`pljadgK5Bh?VUiq}rPJ-Z< zW@QYb{x|h6{$6xF9n%r|NH#7sH2nzLWI-eZw(5~UB;svWs5ZXx`H3e7NEB{K*G^Kn zhaoixkFCkUB0}*!;l5&et+6nDkO{4%Su>`=$9#7fmRGJ~dVPEbAPSM?!ezy=7Aa{v zX6mefs+q#jc&7ZPslsMc$`H`AK37BUUVK29+Pl08t+@%jtJI)8Dq584;u9W+z`)5? z-4lbHr<$04tywiOVR9o9!?U6=y%9vI(xHu)@+~RIaaP^B{D)4`0;8n-)pgHJ9BueU zj;*6Nmusz~lb*HK(bXIKJ$EOQkE*e+p?W0AUj>`|q&+2~r4J@3;GEQH_t=PsDP<4QkxC4P5)`-*vq8bOoI^4I_JPv$rDE~aO&S_a(o zt22M2chAv1f)ajUEb~I~`TL)I`G>bZz4Wi`b3cFYuk@bE*Z(x1Dy#sQsBpeqX6xnq~Zqi!aJola@u8imy7;;+6Ma&hnH z(Z44RepTP&4$uA<*5K*1etW&%NwaMe-|i7_Y8{&Rb$XwM^L4oXeMczMZ_Rb!yiMLjT3Q_Naq@0|1f4=l}o! literal 0 HcmV?d00001 diff --git a/spine-unity/Assets/Examples/Spine/eyes.prefab.meta b/spine-unity/Assets/Examples/Spine/eyes.prefab.meta new file mode 100644 index 000000000..9bbd5716e --- /dev/null +++ b/spine-unity/Assets/Examples/Spine/eyes.prefab.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 370927d98ff6b024c96ea2935adb4efb +NativeFormatImporter: + userData: diff --git a/spine-unity/Assets/Examples/Spine/goblins-ffd.prefab b/spine-unity/Assets/Examples/Spine/goblins-ffd.prefab index 4fdbf628157e0de1f56033d8569cedea6a68bac6..1f2eac9df5598bdf72119ab729edfe7a53ee5117 100644 GIT binary patch literal 10168 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 diff --git a/spine-unity/Assets/Examples/Spine/raptor.prefab b/spine-unity/Assets/Examples/Spine/raptor.prefab index 50ff3a22e8baa7618bfdd441b7ead2c52231627a..8eda80ce4a70a72ee898edee4cfec323aab3c2c3 100644 GIT binary patch delta 289 zcmdntcEL@WfkDxkfk8Qdfq{V&$W8##3?_P}dd6wS8>Mx57`ZkE9B14tz-Pid`GEwR zY*2oFiGNW_Y7qkqP@y77H4rdD@ML>IZAL+`1|#7>mdW?Ul_t*>w`O$M%rCK;qdo+v z3Zx5!6C{)wE`Vqt7Kh>mQAP{~K%-QEe2~c??C^OlLj+JP2gv>p1Vuo4LHc*r6F@Ny zAp0dV1Oq7sh9{ri{a&NB%yrj9`Tvg}yb5Ll2{P!GtWKEtd6oNQWyPRFa;YrxYd#Qu?5BJxDzmFi*a!lnek!^g;~) delta 258 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