Ver código fonte

[unity] Previous commit 75b9321 was missing two added files. Added BoundingBoxFollowerGraphic component. [..] See #1770.

Harald Csaszar 4 anos atrás
pai
commit
d0681d7929

+ 255 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollowerGraphic.cs

@@ -0,0 +1,255 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated January 1, 2020. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2020, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software
+ * or otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER
+#define NEW_PREFAB_SYSTEM
+#endif
+
+using UnityEngine;
+using System.Collections.Generic;
+
+namespace Spine.Unity {
+
+	#if NEW_PREFAB_SYSTEM
+	[ExecuteAlways]
+	#else
+	[ExecuteInEditMode]
+	#endif
+	[HelpURL("http://esotericsoftware.com/spine-unity#BoundingBoxFollowerGraphic")]
+	public class BoundingBoxFollowerGraphic : MonoBehaviour {
+		internal static bool DebugMessages = true;
+
+		#region Inspector
+		public SkeletonGraphic skeletonGraphic;
+		[SpineSlot(dataField: "skeletonGraphic", containsBoundingBoxes: true)]
+		public string slotName;
+		public bool isTrigger;
+		public bool clearStateOnDisable = true;
+		#endregion
+
+		Slot slot;
+		BoundingBoxAttachment currentAttachment;
+		string currentAttachmentName;
+		PolygonCollider2D currentCollider;
+
+		public readonly Dictionary<BoundingBoxAttachment, PolygonCollider2D> colliderTable = new Dictionary<BoundingBoxAttachment, PolygonCollider2D>();
+		public readonly Dictionary<BoundingBoxAttachment, string> nameTable = new Dictionary<BoundingBoxAttachment, string>();
+
+		public Slot Slot { get { return slot; } }
+		public BoundingBoxAttachment CurrentAttachment { get { return currentAttachment; } }
+		public string CurrentAttachmentName { get { return currentAttachmentName; } }
+		public PolygonCollider2D CurrentCollider { get { return currentCollider; } }
+		public bool IsTrigger { get { return isTrigger; } }
+
+		void Start () {
+			Initialize();
+		}
+
+		void OnEnable () {
+			if (skeletonGraphic != null) {
+				skeletonGraphic.OnRebuild -= HandleRebuild;
+				skeletonGraphic.OnRebuild += HandleRebuild;
+			}
+
+			Initialize();
+		}
+
+		void HandleRebuild (SkeletonGraphic sr) {
+			//if (BoundingBoxFollowerGraphic.DebugMessages) Debug.Log("Skeleton was rebuilt. Repopulating BoundingBoxFollowerGraphic.");
+			Initialize();
+		}
+
+		/// <summary>
+		/// Initialize and instantiate the BoundingBoxFollowerGraphic colliders. This is method checks if the BoundingBoxFollowerGraphic has already been initialized for the skeleton instance and slotName and prevents overwriting unless it detects a new setup.</summary>
+		public void Initialize (bool overwrite = false) {
+			if (skeletonGraphic == null)
+				return;
+
+			skeletonGraphic.Initialize(false);
+
+			if (string.IsNullOrEmpty(slotName))
+				return;
+
+			// Don't reinitialize if the setup did not change.
+			if (!overwrite
+				&&
+				colliderTable.Count > 0 && slot != null			// Slot is set and colliders already populated.
+				&&
+				skeletonGraphic.Skeleton == slot.Skeleton		// Skeleton object did not change.
+				&&
+				slotName == slot.data.name						// Slot object did not change.
+			)
+				return;
+
+			slot = null;
+			currentAttachment = null;
+			currentAttachmentName = null;
+			currentCollider = null;
+			colliderTable.Clear();
+			nameTable.Clear();
+
+			var skeleton = skeletonGraphic.Skeleton;
+			slot = skeleton.FindSlot(slotName);
+			int slotIndex = skeleton.FindSlotIndex(slotName);
+
+			if (slot == null) {
+				if (BoundingBoxFollowerGraphic.DebugMessages)
+					Debug.LogWarning(string.Format("Slot '{0}' not found for BoundingBoxFollowerGraphic on '{1}'. (Previous colliders were disposed.)", slotName, this.gameObject.name));
+				return;
+			}
+
+			int requiredCollidersCount = 0;
+			var colliders = GetComponents<PolygonCollider2D>();
+			if (this.gameObject.activeInHierarchy) {
+				var canvas = skeletonGraphic.canvas;
+				if (canvas == null) canvas = skeletonGraphic.GetComponentInParent<Canvas>();
+				float scale = canvas != null ? canvas.referencePixelsPerUnit : 100.0f;
+
+				foreach (var skin in skeleton.Data.Skins)
+					AddCollidersForSkin(skin, slotIndex, colliders, scale, ref requiredCollidersCount);
+
+				if (skeleton.skin != null)
+					AddCollidersForSkin(skeleton.skin, slotIndex, colliders, scale, ref requiredCollidersCount);
+			}
+			DisposeExcessCollidersAfter(requiredCollidersCount);
+
+			if (BoundingBoxFollowerGraphic.DebugMessages) {
+				bool valid = colliderTable.Count != 0;
+				if (!valid) {
+					if (this.gameObject.activeInHierarchy)
+						Debug.LogWarning("Bounding Box Follower not valid! Slot [" + slotName + "] does not contain any Bounding Box Attachments!");
+					else
+						Debug.LogWarning("Bounding Box Follower tried to rebuild as a prefab.");
+				}
+			}
+		}
+
+		void AddCollidersForSkin (Skin skin, int slotIndex, PolygonCollider2D[] previousColliders, float scale, ref int collidersCount) {
+			if (skin == null) return;
+			var skinEntries = new List<Skin.SkinEntry>();
+			skin.GetAttachments(slotIndex, skinEntries);
+
+			foreach (var entry in skinEntries) {
+				var attachment = skin.GetAttachment(slotIndex, entry.Name);
+				var boundingBoxAttachment = attachment as BoundingBoxAttachment;
+
+				if (BoundingBoxFollowerGraphic.DebugMessages && attachment != null && boundingBoxAttachment == null)
+					Debug.Log("BoundingBoxFollowerGraphic tried to follow a slot that contains non-boundingbox attachments: " + slotName);
+
+				if (boundingBoxAttachment != null) {
+					if (!colliderTable.ContainsKey(boundingBoxAttachment)) {
+						var bbCollider = collidersCount < previousColliders.Length ?
+							previousColliders[collidersCount] : gameObject.AddComponent<PolygonCollider2D>();
+						++collidersCount;
+						SkeletonUtility.SetColliderPointsLocal(bbCollider, slot, boundingBoxAttachment, scale);
+						bbCollider.isTrigger = isTrigger;
+						bbCollider.enabled = false;
+						bbCollider.hideFlags = HideFlags.NotEditable;
+						bbCollider.isTrigger = IsTrigger;
+						colliderTable.Add(boundingBoxAttachment, bbCollider);
+						nameTable.Add(boundingBoxAttachment, entry.Name);
+					}
+				}
+			}
+		}
+
+		void OnDisable () {
+			if (clearStateOnDisable)
+				ClearState();
+
+			if (skeletonGraphic != null)
+				skeletonGraphic.OnRebuild -= HandleRebuild;
+		}
+
+		public void ClearState () {
+			if (colliderTable != null)
+				foreach (var col in colliderTable.Values)
+					col.enabled = false;
+
+			currentAttachment = null;
+			currentAttachmentName = null;
+			currentCollider = null;
+		}
+
+		void DisposeExcessCollidersAfter (int requiredCount) {
+			var colliders = GetComponents<PolygonCollider2D>();
+			if (colliders.Length == 0) return;
+
+			for (int i = requiredCount; i < colliders.Length; ++i) {
+				var collider = colliders[i];
+				if (collider != null) {
+#if UNITY_EDITOR
+					if (Application.isEditor && !Application.isPlaying)
+						DestroyImmediate(collider);
+					else
+#endif
+						Destroy(collider);
+				}
+			}
+		}
+
+		void LateUpdate () {
+			if (slot != null && slot.Attachment != currentAttachment)
+				MatchAttachment(slot.Attachment);
+		}
+
+		/// <summary>Sets the current collider to match attachment.</summary>
+		/// <param name="attachment">If the attachment is not a bounding box, it will be treated as null.</param>
+		void MatchAttachment (Attachment attachment) {
+			var bbAttachment = attachment as BoundingBoxAttachment;
+
+			if (BoundingBoxFollowerGraphic.DebugMessages && attachment != null && bbAttachment == null)
+				Debug.LogWarning("BoundingBoxFollowerGraphic tried to match a non-boundingbox attachment. It will treat it as null.");
+
+			if (currentCollider != null)
+				currentCollider.enabled = false;
+
+			if (bbAttachment == null) {
+				currentCollider = null;
+				currentAttachment = null;
+				currentAttachmentName = null;
+			} else {
+				PolygonCollider2D foundCollider;
+				colliderTable.TryGetValue(bbAttachment, out foundCollider);
+				if (foundCollider != null) {
+					currentCollider = foundCollider;
+					currentCollider.enabled = true;
+					currentAttachment = bbAttachment;
+					currentAttachmentName = nameTable[bbAttachment];
+				} else {
+					currentCollider = null;
+					currentAttachment = bbAttachment;
+					currentAttachmentName = null;
+					if (BoundingBoxFollowerGraphic.DebugMessages) Debug.LogFormat("Collider for BoundingBoxAttachment named '{0}' was not initialized. It is possibly from a new skin. currentAttachmentName will be null. You may need to call BoundingBoxFollowerGraphic.Initialize(overwrite: true);", bbAttachment.Name);
+				}
+			}
+		}
+	}
+
+}

+ 11 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollowerGraphic.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1c0bf7b497af9f74280040d96cdf88da
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: