浏览代码

Merged master manually

badlogic 8 年之前
父节点
当前提交
cbe79ba04a

+ 4 - 4
spine-csharp/src/AnimationState.cs

@@ -845,7 +845,7 @@ namespace Spine {
 	}
 
 	class EventQueue {
-		private readonly ExposedList<EventQueueEntry> eventQueueEntries = new ExposedList<EventQueueEntry>();
+		private readonly List<EventQueueEntry> eventQueueEntries = new List<EventQueueEntry>();
 		public bool drainDisabled;
 
 		private readonly AnimationState state;
@@ -905,11 +905,11 @@ namespace Spine {
 			drainDisabled = true;
 
 			var entries = this.eventQueueEntries;
-			var entriesItems = entries.Items;
 			AnimationState state = this.state;
 
-			for (int i = 0, n = entries.Count; i < n; i++) {
-				var queueEntry = entriesItems[i];
+			// Don't cache entries.Count so callbacks can queue their own events (eg, call SetAnimation in AnimationState_Complete).
+			for (int i = 0; i < entries.Count; i++) {
+				var queueEntry = entries[i];
 				TrackEntry trackEntry = queueEntry.entry;
 
 				switch (queueEntry.type) {

+ 10 - 1
spine-starling/spine-starling/src/spine/starling/SkeletonSprite.as

@@ -69,7 +69,7 @@ public class SkeletonSprite extends DisplayObject {
 	}
 
 	override public function render (painter:Painter) : void {
-		alpha *= this.alpha * skeleton.color.a;
+		painter.state.alpha *= skeleton.a;
 		var originalBlendMode:String = painter.state.blendMode;
 		var r:Number = skeleton.color.r * 255;
 		var g:Number = skeleton.color.g * 255;
@@ -164,6 +164,7 @@ public class SkeletonSprite extends DisplayObject {
 					mesh.setTexCoords(ii, uvs[iii], uvs[iii+1]);
 				}
 				vertexData.numVertices = verticesCount;
+				painter.state.blendMode = blendModes[slot.data.blendMode.ordinal];
 				// FIXME set smoothing/filter
 				painter.batchMesh(mesh);
 			}
@@ -180,6 +181,7 @@ public class SkeletonSprite extends DisplayObject {
 		var maxX:Number = -Number.MAX_VALUE, maxY:Number = -Number.MAX_VALUE;
 		var slots:Vector.<Slot> = skeleton.slots;
 		var worldVertices:Vector.<Number> = _tempVertices;
+		var empty:Boolean = true;
 		for (var i:int = 0, n:int = slots.length; i < n; ++i) {
 			var slot:Slot = slots[i];
 			var attachment:Attachment = slot.attachment;
@@ -196,6 +198,10 @@ public class SkeletonSprite extends DisplayObject {
 				mesh.computeWorldVertices(slot, 0, verticesLength, worldVertices, 0, 2);
 			} else
 				continue;
+				
+			if (verticesLength != 0)
+				empty = false;
+			  
 			for (var ii:int = 0; ii < verticesLength; ii += 2) {
 				var x:Number = worldVertices[ii], y:Number = worldVertices[ii + 1];
 				minX = minX < x ? minX : x;
@@ -204,6 +210,9 @@ public class SkeletonSprite extends DisplayObject {
 				maxY = maxY > y ? maxY : y;
 			}
 		}
+		
+		if (empty)
+			return null;
 
 		var temp:Number;
 		if (maxX < minX) {

+ 1 - 1
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonAnimationComponent.h

@@ -82,7 +82,7 @@ public:
 	UTrackEntry () { }		
 
 	void SetTrackEntry (spTrackEntry* entry);
-	spTrackEntry* GetTrackEntry();
+	spTrackEntry* GetTrackEntry() { return entry; }
 	
 	UFUNCTION(BlueprintCallable, Category="Components|Spine|TrackEntry")
 	int GetTrackIndex () { return entry ? entry->trackIndex : 0; }

+ 1 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonComponent.h

@@ -31,6 +31,7 @@
 #pragma once
 
 #include "Components/ActorComponent.h"
+#include "SpineSkeletonDataAsset.h"
 #include "spine/spine.h"
 #include "SpineSkeletonComponent.generated.h"
 

+ 50 - 40
spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs

@@ -83,24 +83,6 @@ namespace Spine.Unity.Editor {
 			SpineEditorUtilities.ConfirmInitialization();
 			m_skeletonDataAsset = (SkeletonDataAsset)target;
 
-			// Clear empty atlas array items.
-			{
-				bool hasNulls = false;
-				foreach (var a in m_skeletonDataAsset.atlasAssets) {
-					if (a == null) {
-						hasNulls = true;
-						break;
-					}
-				}
-				if (hasNulls) {
-					var trimmedAtlasAssets = new List<AtlasAsset>();
-					foreach (var a in m_skeletonDataAsset.atlasAssets) {
-						if (a != null) trimmedAtlasAssets.Add(a);
-					}
-					m_skeletonDataAsset.atlasAssets = trimmedAtlasAssets.ToArray();
-				}
-			}
-
 			atlasAssets = serializedObject.FindProperty("atlasAssets");
 			skeletonJSON = serializedObject.FindProperty("skeletonJSON");
 			scale = serializedObject.FindProperty("scale");
@@ -126,8 +108,8 @@ namespace Spine.Unity.Editor {
 
 			m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));
 			EditorApplication.update += EditorUpdate;
-			m_skeletonData = m_skeletonDataAsset.GetSkeletonData(false);
 			RepopulateWarnings();
+			m_skeletonData = warnings.Count == 0 ? m_skeletonDataAsset.GetSkeletonData(false) : null;
 		}
 
 		void OnDestroy () {
@@ -228,8 +210,9 @@ namespace Spine.Unity.Editor {
 						m_previewUtility.Cleanup();
 						m_previewUtility = null;
 					}
-					RepopulateWarnings();
-					OnEnable();
+					m_skeletonDataAsset.Clear();
+					m_skeletonData = null;
+					OnEnable(); // Should call RepopulateWarnings.
 					return;
 				}
 			}
@@ -258,7 +241,6 @@ namespace Spine.Unity.Editor {
 				using (new EditorGUI.DisabledGroupScope(skeletonJSON.objectReferenceValue == null)) {
 					if (GUILayout.Button(new GUIContent("Attempt Reimport", Icons.warning))) {
 						DoReimport();
-						return;
 					}
 				}
 				#else
@@ -376,15 +358,12 @@ namespace Spine.Unity.Editor {
 
 		void DoReimport () {
 			SpineEditorUtilities.ImportSpineContent(new string[] { AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue) }, true);
-
 			if (m_previewUtility != null) {
 				m_previewUtility.Cleanup();
 				m_previewUtility = null;
 			}
 
-			RepopulateWarnings();
-			OnEnable();
-
+			OnEnable(); // Should call RepopulateWarnings.
 			EditorUtility.SetDirty(m_skeletonDataAsset);
 		}
 
@@ -535,6 +514,25 @@ namespace Spine.Unity.Editor {
 		void RepopulateWarnings () {
 			warnings.Clear();
 
+			// Clear null entries.
+			{
+				bool hasNulls = false;
+				foreach (var a in m_skeletonDataAsset.atlasAssets) {
+					if (a == null) {
+						hasNulls = true;
+						break;
+					}
+				}
+				if (hasNulls) {
+					var trimmedAtlasAssets = new List<AtlasAsset>();
+					foreach (var a in m_skeletonDataAsset.atlasAssets) {
+						if (a != null) trimmedAtlasAssets.Add(a);
+					}
+					m_skeletonDataAsset.atlasAssets = trimmedAtlasAssets.ToArray();
+				}
+				serializedObject.Update();
+			}
+
 			if (skeletonJSON.objectReferenceValue == null) {
 				warnings.Add("Missing Skeleton JSON");
 			} else {
@@ -544,12 +542,13 @@ namespace Spine.Unity.Editor {
 					#if !SPINE_TK2D
 					bool detectedNullAtlasEntry = false;
 					var atlasList = new List<Atlas>();
-					for (int i = 0; i < atlasAssets.arraySize; i++) {
-						if (atlasAssets.GetArrayElementAtIndex(i).objectReferenceValue == null) {
+					var actualAtlasAssets = m_skeletonDataAsset.atlasAssets;
+					for (int i = 0; i < actualAtlasAssets.Length; i++) {
+						if (m_skeletonDataAsset.atlasAssets[i] == null) {
 							detectedNullAtlasEntry = true;
 							break;
 						} else {
-							atlasList.Add(((AtlasAsset)atlasAssets.GetArrayElementAtIndex(i).objectReferenceValue).GetAtlas());
+							atlasList.Add(actualAtlasAssets[i].GetAtlas());
 						}
 					}
 
@@ -642,26 +641,37 @@ namespace Spine.Unity.Editor {
 		void CreatePreviewInstances () {
 			this.DestroyPreviewInstances();
 
+			if (warnings.Count > 0) {
+				m_skeletonDataAsset.Clear();
+				return;
+			}
+
 			var skeletonDataAsset = (SkeletonDataAsset)target;
 			if (skeletonDataAsset.GetSkeletonData(false) == null)
 				return;
 
 			if (this.m_previewInstance == null) {
 				string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", "");
-				m_previewInstance = SpineEditorUtilities.InstantiateSkeletonAnimation(skeletonDataAsset, skinName).gameObject;
 
-				if (m_previewInstance != null) {
-					m_previewInstance.hideFlags = HideFlags.HideAndDontSave;
-					m_previewInstance.layer = 0x1f;
-					m_skeletonAnimation = m_previewInstance.GetComponent<SkeletonAnimation>();
-					m_skeletonAnimation.initialSkinName = skinName;
-					m_skeletonAnimation.LateUpdate();
-					m_skeletonData = m_skeletonAnimation.skeletonDataAsset.GetSkeletonData(true);
-					m_previewInstance.GetComponent<Renderer>().enabled = false;
-					m_initialized = true;
+				try {
+					m_previewInstance = SpineEditorUtilities.InstantiateSkeletonAnimation(skeletonDataAsset, skinName).gameObject;
+
+					if (m_previewInstance != null) {
+						m_previewInstance.hideFlags = HideFlags.HideAndDontSave;
+						m_previewInstance.layer = 0x1f;
+						m_skeletonAnimation = m_previewInstance.GetComponent<SkeletonAnimation>();
+						m_skeletonAnimation.initialSkinName = skinName;
+						m_skeletonAnimation.LateUpdate();
+						m_skeletonData = m_skeletonAnimation.skeletonDataAsset.GetSkeletonData(true);
+						m_previewInstance.GetComponent<Renderer>().enabled = false;
+						m_initialized = true;
+					}
+
+					AdjustCameraGoals(true);
+				} catch {
+					DestroyPreviewInstances();
 				}
 
-				AdjustCameraGoals(true);
 			}
 		}
 

+ 20 - 19
spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs

@@ -89,14 +89,6 @@ namespace Spine.Unity {
 		}
 
 		public SkeletonData GetSkeletonData (bool quiet) {
-			if (atlasAssets == null) {
-				atlasAssets = new AtlasAsset[0];
-				if (!quiet)
-					Debug.LogError("Atlas not set for SkeletonData asset: " + name, this);
-				Clear();
-				return null;
-			}
-
 			if (skeletonJSON == null) {
 				if (!quiet)
 					Debug.LogError("Skeleton JSON file not set for SkeletonData asset: " + name, this);
@@ -104,17 +96,26 @@ namespace Spine.Unity {
 				return null;
 			}
 
-			#if !SPINE_TK2D
-			if (atlasAssets.Length == 0) {
-				Clear();
-				return null;
-			}
-			#else
-			if (atlasAssets.Length == 0 && spriteCollection == null) {
-				Clear();
-				return null;
-			}
-			#endif
+			// Support attachmentless/skinless SkeletonData.
+//			if (atlasAssets == null) {
+//				atlasAssets = new AtlasAsset[0];
+//				if (!quiet)
+//					Debug.LogError("Atlas not set for SkeletonData asset: " + name, this);
+//				Clear();
+//				return null;
+//			}
+//			#if !SPINE_TK2D
+//			if (atlasAssets.Length == 0) {
+//				Clear();
+//				return null;
+//			}
+//			#else
+//			if (atlasAssets.Length == 0 && spriteCollection == null) {
+//				Clear();
+//				return null;
+//			}
+//			#endif
+
 			if (skeletonData != null)
 				return skeletonData;
 

+ 3 - 2
spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs

@@ -214,8 +214,9 @@ namespace Spine.Unity.Editor {
 						if (skinNameString == initialSkinName.stringValue)
 							skinIndex = i;
 					}
-					skinIndex = EditorGUILayout.Popup("Initial Skin", skinIndex, skins);			
-					initialSkinName.stringValue = skins[skinIndex];
+					skinIndex = EditorGUILayout.Popup("Initial Skin", skinIndex, skins);
+					if (skins.Length > 0) // Support attachmentless/skinless SkeletonData.
+						initialSkinName.stringValue = skins[skinIndex];
 				}
 			}
 

+ 9 - 4
spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs

@@ -603,7 +603,7 @@ namespace Spine.Unity.Editor {
 				var localAtlases = FindAtlasesAtPath(dir);
 				var requiredPaths = GetRequiredAtlasRegions(sp);
 				var atlasMatch = GetMatchingAtlas(requiredPaths, localAtlases);
-				if (atlasMatch != null) {
+				if (atlasMatch != null || requiredPaths.Count == 0) {
 					IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, atlasMatch);
 				} else {
 					bool resolved = false;
@@ -830,6 +830,8 @@ namespace Spine.Unity.Editor {
 			StringReader reader = new StringReader(spineJson.text);
 			var root = Json.Deserialize(reader) as Dictionary<string, object>;
 
+			if (!root.ContainsKey("skins"))
+				return requiredPaths;			
 
 			foreach (KeyValuePair<string, object> entry in (Dictionary<string, object>)root["skins"]) {
 				foreach (KeyValuePair<string, object> slotEntry in (Dictionary<string, object>)entry.Value) {
@@ -1326,9 +1328,12 @@ namespace Spine.Unity.Editor {
 				throw e;
 			}
 
-			skin = skin ?? data.DefaultSkin ?? data.Skins.Items[0];
-			newSkeletonAnimation.skeleton.SetSkin(skin);
-			newSkeletonAnimation.initialSkinName = skin.Name;
+			bool noSkins = data.DefaultSkin == null && (data.Skins == null || data.Skins.Count == 0); // Support attachmentless/skinless SkeletonData.
+			skin = skin ?? data.DefaultSkin ?? (noSkins ? null : data.Skins.Items[0]);
+			if (skin != null) {
+				newSkeletonAnimation.initialSkinName = skin.Name;
+				newSkeletonAnimation.skeleton.SetSkin(skin);
+			}
 
 			newSkeletonAnimation.skeleton.Update(0);
 			newSkeletonAnimation.state.Update(0);

+ 1 - 1
spine-unity/Assets/spine-unity/Mesh Generation/Arrays/ArraysSimpleMeshGenerator.cs

@@ -96,7 +96,7 @@ namespace Spine.Unity.MeshGeneration {
 
 				// Apply scale to vertices
 				meshBoundsMax.x *= scale; meshBoundsMax.y *= scale;
-				meshBoundsMin.x *= scale; meshBoundsMax.y *= scale;
+				meshBoundsMin.x *= scale; meshBoundsMin.y *= scale;
 				var vertices = this.meshVertices;
 				for (int i = 0; i < totalVertexCount; i++) {
 					Vector3 p = vertices[i];

+ 13 - 13
spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs

@@ -160,25 +160,25 @@ namespace Spine.Unity {
 		}
 
 		void DisposeColliders () {
-			#if UNITY_EDITOR
 			var colliders = GetComponents<PolygonCollider2D>();
 			if (colliders.Length == 0) return;
 
-			if (Application.isPlaying) {
-				foreach (var c in colliders) {
-					if (c != null)
-						Destroy(c);
+			if (Application.isEditor) {
+				if (Application.isPlaying) {
+					foreach (var c in colliders) {
+						if (c != null)
+							Destroy(c);
+					}
+				} else {
+					foreach (var c in colliders)
+						if (c != null) 
+							DestroyImmediate(c);
 				}
 			} else {
-				foreach (var c in colliders)
-					if (c != null) 
-						DestroyImmediate(c);
+				foreach (PolygonCollider2D c in colliders)
+					if (c != null)
+						Destroy(c);
 			}
-			#else
-			foreach (PolygonCollider2D c in colliderTable.Values)
-				if (c != null)
-					Destroy(c);
-			#endif
 
 			slot = null;
 			currentAttachment = null;

+ 103 - 3
spine-unity/Assets/spine-unity/SkeletonExtensions.cs

@@ -100,16 +100,19 @@ namespace Spine.Unity {
 		#endregion
 
 		#region Bone
+		/// <summary>Sets the bone's (local) X and Y according to a Vector2</summary>
 		public static void SetPosition (this Bone bone, Vector2 position) {
 			bone.X = position.x;
 			bone.Y = position.y;
 		}
 
+		/// <summary>Sets the bone's (local) X and Y according to a Vector3. The z component is ignored.</summary>
 		public static void SetPosition (this Bone bone, Vector3 position) {
 			bone.X = position.x;
 			bone.Y = position.y;
 		}
 
+		/// <summary>Gets the bone's local X and Y as a Vector2.</summary>
 		public static Vector2 GetLocalPosition (this Bone bone) {
 			return new Vector2(bone.x, bone.y);
 		}
@@ -126,10 +129,12 @@ namespace Spine.Unity {
 			return o;
 		}
 
-		public static Vector3 GetWorldPosition (this Bone bone, UnityEngine.Transform parentTransform) {		
-			return parentTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY));
+		/// <summary>Gets the bone's Unity World position using its Spine GameObject Transform. UpdateWorldTransform needs to have been called for this to return the correct, updated value.</summary>
+		public static Vector3 GetWorldPosition (this Bone bone, UnityEngine.Transform spineGameObjectTransform) {		
+			return spineGameObjectTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY));
 		}
 
+		/// <summary>Gets the internal bone matrix as a Unity bonespace-to-skeletonspace transformation matrix.</summary>
 		public static Matrix4x4 GetMatrix4x4 (this Bone bone) {
 			return new Matrix4x4 {
 				m00 = bone.a, m01 = bone.b, m03 = bone.worldX,
@@ -138,7 +143,7 @@ namespace Spine.Unity {
 			};
 		}
 
-		/// <summary>Outputs a 2x2 Transformation Matrix that can convert a skeleton-space position to a bone-local position.</summary>
+		/// <summary>Calculates a 2x2 Transformation Matrix that can convert a skeleton-space position to a bone-local position.</summary>
 		public static void GetWorldToLocalMatrix (this Bone bone, out float ia, out float ib, out float ic, out float id) {
 			float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
 			float invDet = 1 / (a * d - b * c);
@@ -236,6 +241,8 @@ namespace Spine.Unity {
 }
 
 namespace Spine {
+	using System.Collections.Generic;
+
 	public static class SkeletonExtensions {
 		public static bool IsWeighted (this VertexAttachment va) {
 			return va.bones != null && va.bones.Length > 0;
@@ -259,6 +266,85 @@ namespace Spine {
 			animation.Apply(skeleton, lastTime, time, loop, events, 1f, false, false);
 		}
 
+		internal static void SetPropertyToSetupPose (this Skeleton skeleton, int propertyID) {
+			int tt = propertyID >> 24;
+			var timelineType = (TimelineType)tt;
+			int i = propertyID - (tt << 24);
+
+			Bone bone;
+			IkConstraint ikc;
+			PathConstraint pc;
+
+			switch (timelineType) {
+			// Bone
+			case TimelineType.Rotate:
+				bone = skeleton.bones.Items[i];
+				bone.rotation = bone.data.rotation;
+				break;
+			case TimelineType.Translate:
+				bone = skeleton.bones.Items[i];
+				bone.x = bone.data.x;
+				bone.y = bone.data.y;
+				break;
+			case TimelineType.Scale:
+				bone = skeleton.bones.Items[i];
+				bone.scaleX = bone.data.scaleX;
+				bone.scaleY = bone.data.scaleY;
+				break;
+			case TimelineType.Shear:
+				bone = skeleton.bones.Items[i];
+				bone.shearX = bone.data.shearX;
+				bone.shearY = bone.data.shearY;
+				break;
+			
+			// Slot
+			case TimelineType.Attachment:
+				skeleton.SetSlotAttachmentToSetupPose(i);
+				break;
+			case TimelineType.Color:
+				skeleton.slots.Items[i].SetColorToSetupPose();
+				break;
+			case TimelineType.Deform:
+				skeleton.slots.Items[i].attachmentVertices.Clear();
+				break;
+			
+			// Skeleton
+			case TimelineType.DrawOrder:
+				skeleton.SetDrawOrderToSetupPose();
+				break;
+
+			// IK Constraint
+			case TimelineType.IkConstraint:
+				ikc = skeleton.ikConstraints.Items[i];
+				ikc.mix = ikc.data.mix;
+				ikc.bendDirection = ikc.data.bendDirection;
+				break;
+			case TimelineType.TransformConstraint:
+				var tc = skeleton.transformConstraints.Items[i];
+				var tcData = tc.data;
+				tc.rotateMix = tcData.rotateMix;
+				tc.translateMix = tcData.translateMix;
+				tc.scaleMix = tcData.scaleMix;
+				tc.shearMix = tcData.shearMix;
+				break;
+
+			// Path Constraint
+			case TimelineType.PathConstraintPosition:
+				pc = skeleton.pathConstraints.Items[i];
+				pc.position = pc.data.position;
+				break;
+			case TimelineType.PathConstraintSpacing:
+				pc = skeleton.pathConstraints.Items[i];
+				pc.spacing = pc.data.spacing;
+				break;
+			case TimelineType.PathConstraintMix:
+				pc = skeleton.pathConstraints.Items[i];
+				pc.rotateMix = pc.data.rotateMix;
+				pc.translateMix = pc.data.translateMix;
+				break;
+			}
+		}
+
 		/// <summary>Resets the DrawOrder to the Setup Pose's draw order</summary>
 		public static void SetDrawOrderToSetupPose (this Skeleton skeleton) {
 			var slotsItems = skeleton.slots.Items;
@@ -315,5 +401,19 @@ namespace Spine {
 			animation.Apply(skeleton, 0, 0, false, null, 0, true, true);
 		}
 		#endregion
+
+		#region Skins
+		/// <summary><see cref="Spine.Skin.FindNamesForSlot(int,List)"/></summary>
+		public static void FindNamesForSlot (this Skin skin, string slotName, SkeletonData skeletonData, List<string> results) {
+			int slotIndex = skeletonData.FindSlotIndex(slotName);
+			skin.FindNamesForSlot(slotIndex, results);
+		}
+
+		/// <summary><see cref="Spine.Skin.FindAttachmentsForSlot(int,List)"/></summary>
+		public static void FindAttachmentsForSlot (this Skin skin, string slotName, SkeletonData skeletonData, List<Attachment> results) {
+			int slotIndex = skeletonData.FindSlotIndex(slotName);
+			skin.FindAttachmentsForSlot(slotIndex, results);
+		}
+		#endregion
 	}
 }